{"action":"created","comment":{"url":"https://api.github.com/repos/zulip/zulip/pulls/comments/71064408","id":71064408,"diff_hunk":"@@ -0,0 +1,200 @@\n+# Life of a Request\n+\n+It can sometimes be confusing to figure out how to write a new feature,\n+or debug an existing one. Let's try to follow a request through the\n+Zulip codebase, and dive deep into how each part works.\n+\n+## A request is sent to the server, and handled by Nginx\n+\n+Everything in Zulip goes through nginx, when deployed in production.\n+For the most part you don't need to know how this works, except for when\n+it isn't working. Nginx does the first level of routing--deciding which\n+application will serve the request (or deciding to serve the request\n+itself for static content).\n+\n+## Nginx secures traffic with SSL\n+\n+If you visit your zulip server in your browser and discover that your\n+traffic isn't being properly encrypted, an nginx configuration is the\n+likely culprit.\n+\n+## Static files are served directly by Nginx\n+\n+Static files include javascript, css, static assets (like emoji, avatars),\n+and user uploads (if stored locally and not on S3).\n+\n+```\n+/home/zulip/prod-static\n+```\n+\n+## Nginx routes other requests between tornado and django\n+\n+All our connected clients hold open long-polling connections so that\n+they can recieve events (messages, presence notifications, and so on) in\n+real-time. Events are served by Zulip's `tornado` application.\n+\n+Nearly every other kind of request is served by the `zerver` Django\n+application.\n+\n+# Django routes the request to a view in urls.py files\n+\n+There are various urls.py files throughout the server codebase, and you\n+can read about it more in [the directory structure doc](http://zulip.readthedocs.io/en/latest/directory-structure.html).\n+\n+The main Zulip Django app is `zerver`. The routes are found in\n+```\n+zproject/urls.py\n+zproject/legacy_urls.py\n+```\n+\n+There are HTML-serving, REST API, legacy, and webhook url patterns.\n+\n+## Views serving HTML are internationalized by server path\n+\n+If you look in [zproject/urls.py](https://github.com/zulip/zulip/blob/master/zproject/urls.py), you'll see something called\n+`i18n_urls`. These urls show up in the address bar of the browser, and\n+serve HTML.\n+\n+For example, the `/hello` page (preview [here](https://zulip.com/hello/))\n+gets translated in Chinese at `zh-cn/hello/` (preview [here](https://zulip.com/zh-cn/hello/)).\n+\n+Note the `zh-cn` prefix--that url pattern gets added by `i18n_patterns`.\n+\n+## API endpoints use REST\n+\n+With the exception of Webhooks (which we do not control), and legacy","path":"docs/life-of-a-request.md","position":65,"original_position":65,"commit_id":"2bbaf5a43e58311c8a922aed3770ab2bb630c02c","original_commit_id":"2bbaf5a43e58311c8a922aed3770ab2bb630c02c","user":{"login":"jdherg","id":233152,"avatar_url":"https://avatars.githubusercontent.com/u/233152?v=3","gravatar_id":"","url":"https://api.github.com/users/jdherg","html_url":"https://github.com/jdherg","followers_url":"https://api.github.com/users/jdherg/followers","following_url":"https://api.github.com/users/jdherg/following{/other_user}","gists_url":"https://api.github.com/users/jdherg/gists{/gist_id}","starred_url":"https://api.github.com/users/jdherg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdherg/subscriptions","organizations_url":"https://api.github.com/users/jdherg/orgs","repos_url":"https://api.github.com/users/jdherg/repos","events_url":"https://api.github.com/users/jdherg/events{/privacy}","received_events_url":"https://api.github.com/users/jdherg/received_events","type":"User","site_admin":false},"body":"I think \"Webhooks\" is lowercase elsewhere.","created_at":"2016-07-16T10:36:04Z","updated_at":"2016-07-16T10:36:04Z","html_url":"https://github.com/zulip/zulip/pull/1302#discussion_r71064408","pull_request_url":"https://api.github.com/repos/zulip/zulip/pulls/1302","_links":{"self":{"href":"https://api.github.com/repos/zulip/zulip/pulls/comments/71064408"},"html":{"href":"https://github.com/zulip/zulip/pull/1302#discussion_r71064408"},"pull_request":{"href":"https://api.github.com/repos/zulip/zulip/pulls/1302"}}},"pull_request":{"url":"https://api.github.com/repos/zulip/zulip/pulls/1302","id":77696533,"html_url":"https://github.com/zulip/zulip/pull/1302","diff_url":"https://github.com/zulip/zulip/pull/1302.diff","patch_url":"https://github.com/zulip/zulip/pull/1302.patch","issue_url":"https://api.github.com/repos/zulip/zulip/issues/1302","number":1302,"state":"open","locked":false,"title":"[RFC] \"Life of a Request\" Doc","user":{"login":"acrefoot","id":1207554,"avatar_url":"https://avatars.githubusercontent.com/u/1207554?v=3","gravatar_id":"","url":"https://api.github.com/users/acrefoot","html_url":"https://github.com/acrefoot","followers_url":"https://api.github.com/users/acrefoot/followers","following_url":"https://api.github.com/users/acrefoot/following{/other_user}","gists_url":"https://api.github.com/users/acrefoot/gists{/gist_id}","starred_url":"https://api.github.com/users/acrefoot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acrefoot/subscriptions","organizations_url":"https://api.github.com/users/acrefoot/orgs","repos_url":"https://api.github.com/users/acrefoot/repos","events_url":"https://api.github.com/users/acrefoot/events{/privacy}","received_events_url":"https://api.github.com/users/acrefoot/received_events","type":"User","site_admin":false},"body":"I'd appreciate comments on `docs/life-of-a-request.md` especially.\r\n\r\n","created_at":"2016-07-16T01:18:37Z","updated_at":"2016-07-16T10:36:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d1578c60cc61c4a0685dfa463745bca21e4de095","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/zulip/zulip/pulls/1302/commits","review_comments_url":"https://api.github.com/repos/zulip/zulip/pulls/1302/comments","review_comment_url":"https://api.github.com/repos/zulip/zulip/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zulip/zulip/issues/1302/comments","statuses_url":"https://api.github.com/repos/zulip/zulip/statuses/2bbaf5a43e58311c8a922aed3770ab2bb630c02c","head":{"label":"acrefoot:acrefoot-views-docs","ref":"acrefoot-views-docs","sha":"2bbaf5a43e58311c8a922aed3770ab2bb630c02c","user":{"login":"acrefoot","id":1207554,"avatar_url":"https://avatars.githubusercontent.com/u/1207554?v=3","gravatar_id":"","url":"https://api.github.com/users/acrefoot","html_url":"https://github.com/acrefoot","followers_url":"https://api.github.com/users/acrefoot/followers","following_url":"https://api.github.com/users/acrefoot/following{/other_user}","gists_url":"https://api.github.com/users/acrefoot/gists{/gist_id}","starred_url":"https://api.github.com/users/acrefoot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acrefoot/subscriptions","organizations_url":"https://api.github.com/users/acrefoot/orgs","repos_url":"https://api.github.com/users/acrefoot/repos","events_url":"https://api.github.com/users/acrefoot/events{/privacy}","received_events_url":"https://api.github.com/users/acrefoot/received_events","type":"User","site_admin":false},"repo":{"id":58563960,"name":"zulip","full_name":"acrefoot/zulip","owner":{"login":"acrefoot","id":1207554,"avatar_url":"https://avatars.githubusercontent.com/u/1207554?v=3","gravatar_id":"","url":"https://api.github.com/users/acrefoot","html_url":"https://github.com/acrefoot","followers_url":"https://api.github.com/users/acrefoot/followers","following_url":"https://api.github.com/users/acrefoot/following{/other_user}","gists_url":"https://api.github.com/users/acrefoot/gists{/gist_id}","starred_url":"https://api.github.com/users/acrefoot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acrefoot/subscriptions","organizations_url":"https://api.github.com/users/acrefoot/orgs","repos_url":"https://api.github.com/users/acrefoot/repos","events_url":"https://api.github.com/users/acrefoot/events{/privacy}","received_events_url":"https://api.github.com/users/acrefoot/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/acrefoot/zulip","description":"Zulip server - powerful open source group chat","fork":true,"url":"https://api.github.com/repos/acrefoot/zulip","forks_url":"https://api.github.com/repos/acrefoot/zulip/forks","keys_url":"https://api.github.com/repos/acrefoot/zulip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acrefoot/zulip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acrefoot/zulip/teams","hooks_url":"https://api.github.com/repos/acrefoot/zulip/hooks","issue_events_url":"https://api.github.com/repos/acrefoot/zulip/issues/events{/number}","events_url":"https://api.github.com/repos/acrefoot/zulip/events","assignees_url":"https://api.github.com/repos/acrefoot/zulip/assignees{/user}","branches_url":"https://api.github.com/repos/acrefoot/zulip/branches{/branch}","tags_url":"https://api.github.com/repos/acrefoot/zulip/tags","blobs_url":"https://api.github.com/repos/acrefoot/zulip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acrefoot/zulip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acrefoot/zulip/git/refs{/sha}","trees_url":"https://api.github.com/repos/acrefoot/zulip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acrefoot/zulip/statuses/{sha}","languages_url":"https://api.github.com/repos/acrefoot/zulip/languages","stargazers_url":"https://api.github.com/repos/acrefoot/zulip/stargazers","contributors_url":"https://api.github.com/repos/acrefoot/zulip/contributors","subscribers_url":"https://api.github.com/repos/acrefoot/zulip/subscribers","subscription_url":"https://api.github.com/repos/acrefoot/zulip/subscription","commits_url":"https://api.github.com/repos/acrefoot/zulip/commits{/sha}","git_commits_url":"https://api.github.com/repos/acrefoot/zulip/git/commits{/sha}","comments_url":"https://api.github.com/repos/acrefoot/zulip/comments{/number}","issue_comment_url":"https://api.github.com/repos/acrefoot/zulip/issues/comments{/number}","contents_url":"https://api.github.com/repos/acrefoot/zulip/contents/{+path}","compare_url":"https://api.github.com/repos/acrefoot/zulip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acrefoot/zulip/merges","archive_url":"https://api.github.com/repos/acrefoot/zulip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acrefoot/zulip/downloads","issues_url":"https://api.github.com/repos/acrefoot/zulip/issues{/number}","pulls_url":"https://api.github.com/repos/acrefoot/zulip/pulls{/number}","milestones_url":"https://api.github.com/repos/acrefoot/zulip/milestones{/number}","notifications_url":"https://api.github.com/repos/acrefoot/zulip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acrefoot/zulip/labels{/name}","releases_url":"https://api.github.com/repos/acrefoot/zulip/releases{/id}","deployments_url":"https://api.github.com/repos/acrefoot/zulip/deployments","created_at":"2016-05-11T16:57:36Z","updated_at":"2016-05-11T16:57:43Z","pushed_at":"2016-07-16T01:18:27Z","git_url":"git://github.com/acrefoot/zulip.git","ssh_url":"git@github.com:acrefoot/zulip.git","clone_url":"https://github.com/acrefoot/zulip.git","svn_url":"https://github.com/acrefoot/zulip","homepage":"","size":112726,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"zulip:master","ref":"master","sha":"09754c9861e487a92f4251087403be1900a1254d","user":{"login":"zulip","id":4921959,"avatar_url":"https://avatars.githubusercontent.com/u/4921959?v=3","gravatar_id":"","url":"https://api.github.com/users/zulip","html_url":"https://github.com/zulip","followers_url":"https://api.github.com/users/zulip/followers","following_url":"https://api.github.com/users/zulip/following{/other_user}","gists_url":"https://api.github.com/users/zulip/gists{/gist_id}","starred_url":"https://api.github.com/users/zulip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zulip/subscriptions","organizations_url":"https://api.github.com/users/zulip/orgs","repos_url":"https://api.github.com/users/zulip/repos","events_url":"https://api.github.com/users/zulip/events{/privacy}","received_events_url":"https://api.github.com/users/zulip/received_events","type":"Organization","site_admin":false},"repo":{"id":43160685,"name":"zulip","full_name":"zulip/zulip","owner":{"login":"zulip","id":4921959,"avatar_url":"https://avatars.githubusercontent.com/u/4921959?v=3","gravatar_id":"","url":"https://api.github.com/users/zulip","html_url":"https://github.com/zulip","followers_url":"https://api.github.com/users/zulip/followers","following_url":"https://api.github.com/users/zulip/following{/other_user}","gists_url":"https://api.github.com/users/zulip/gists{/gist_id}","starred_url":"https://api.github.com/users/zulip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zulip/subscriptions","organizations_url":"https://api.github.com/users/zulip/orgs","repos_url":"https://api.github.com/users/zulip/repos","events_url":"https://api.github.com/users/zulip/events{/privacy}","received_events_url":"https://api.github.com/users/zulip/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zulip/zulip","description":"Zulip server - powerful open source group chat","fork":false,"url":"https://api.github.com/repos/zulip/zulip","forks_url":"https://api.github.com/repos/zulip/zulip/forks","keys_url":"https://api.github.com/repos/zulip/zulip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zulip/zulip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zulip/zulip/teams","hooks_url":"https://api.github.com/repos/zulip/zulip/hooks","issue_events_url":"https://api.github.com/repos/zulip/zulip/issues/events{/number}","events_url":"https://api.github.com/repos/zulip/zulip/events","assignees_url":"https://api.github.com/repos/zulip/zulip/assignees{/user}","branches_url":"https://api.github.com/repos/zulip/zulip/branches{/branch}","tags_url":"https://api.github.com/repos/zulip/zulip/tags","blobs_url":"https://api.github.com/repos/zulip/zulip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zulip/zulip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zulip/zulip/git/refs{/sha}","trees_url":"https://api.github.com/repos/zulip/zulip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zulip/zulip/statuses/{sha}","languages_url":"https://api.github.com/repos/zulip/zulip/languages","stargazers_url":"https://api.github.com/repos/zulip/zulip/stargazers","contributors_url":"https://api.github.com/repos/zulip/zulip/contributors","subscribers_url":"https://api.github.com/repos/zulip/zulip/subscribers","subscription_url":"https://api.github.com/repos/zulip/zulip/subscription","commits_url":"https://api.github.com/repos/zulip/zulip/commits{/sha}","git_commits_url":"https://api.github.com/repos/zulip/zulip/git/commits{/sha}","comments_url":"https://api.github.com/repos/zulip/zulip/comments{/number}","issue_comment_url":"https://api.github.com/repos/zulip/zulip/issues/comments{/number}","contents_url":"https://api.github.com/repos/zulip/zulip/contents/{+path}","compare_url":"https://api.github.com/repos/zulip/zulip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zulip/zulip/merges","archive_url":"https://api.github.com/repos/zulip/zulip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zulip/zulip/downloads","issues_url":"https://api.github.com/repos/zulip/zulip/issues{/number}","pulls_url":"https://api.github.com/repos/zulip/zulip/pulls{/number}","milestones_url":"https://api.github.com/repos/zulip/zulip/milestones{/number}","notifications_url":"https://api.github.com/repos/zulip/zulip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zulip/zulip/labels{/name}","releases_url":"https://api.github.com/repos/zulip/zulip/releases{/id}","deployments_url":"https://api.github.com/repos/zulip/zulip/deployments","created_at":"2015-09-25T16:37:25Z","updated_at":"2016-07-16T07:50:20Z","pushed_at":"2016-07-16T03:54:13Z","git_url":"git://github.com/zulip/zulip.git","ssh_url":"git@github.com:zulip/zulip.git","clone_url":"https://github.com/zulip/zulip.git","svn_url":"https://github.com/zulip/zulip","homepage":"","size":119082,"stargazers_count":3948,"watchers_count":3948,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":619,"mirror_url":null,"open_issues_count":394,"forks":619,"open_issues":394,"watchers":3948,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zulip/zulip/pulls/1302"},"html":{"href":"https://github.com/zulip/zulip/pull/1302"},"issue":{"href":"https://api.github.com/repos/zulip/zulip/issues/1302"},"comments":{"href":"https://api.github.com/repos/zulip/zulip/issues/1302/comments"},"review_comments":{"href":"https://api.github.com/repos/zulip/zulip/pulls/1302/comments"},"review_comment":{"href":"https://api.github.com/repos/zulip/zulip/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zulip/zulip/pulls/1302/commits"},"statuses":{"href":"https://api.github.com/repos/zulip/zulip/statuses/2bbaf5a43e58311c8a922aed3770ab2bb630c02c"}}}}
{"actor":{"display_login":"jdherg"}}