GitHub PullRequestReviewCommentEvent at 2014-10-22 07:59:10
Repository: sabre-http
Actor: staabm
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/fruux/sabre-http/pulls/comments/19198899","id":19198899,"diff_hunk":"@@ -74,6 +93,150 @@ function setUrl($url) {\n     }\n \n     /**\n+     * Retrieve cookies.\n+     *\n+     * Retrieves cookies sent by the client to the server.\n+     *\n+     * The assumption is these are injected during instantiation, typically\n+     * from PHP's $_COOKIE superglobal. The data IS NOT REQUIRED to come from\n+     * $_COOKIE, but MUST be compatible with the structure of $_COOKIE.\n+     *\n+     * @return array\n+     */\n+    function getCookieParams() {\n+\n+        return $this->inner->getCookieParams();\n+\n+    }\n+\n+    /**\n+     * Set cookie parameters.\n+     *\n+     * Allows a library to set the cookie parameters. Use cases include\n+     * libraries that implement additional security practices, such as\n+     * encrypting or hashing cookie values; in such cases, they will read\n+     * the original value, filter them, and re-inject into the incoming\n+     * request.\n+     *\n+     * The value provided MUST be compatible with the structure of $_COOKIE.\n+     *\n+     * @param array $cookies Cookie values\n+     * @return void\n+     * @throws \\InvalidArgumentException For invalid cookie parameters.\n+     */\n+    function setCookieParams(array $cookies) {\n+\n+        $this->inner->setCookieParams($cookies);\n+\n+    }\n+\n+    /**\n+     * Retrieve query string arguments.\n+     *\n+     * Retrieves the deserialized query string arguments, if any.\n+     *\n+     * These values SHOULD remain immutable over the course of the incoming\n+     * request. They MAY be injected during instantiation, such as from PHP's\n+     * $_GET superglobal, or MAY be derived from some other value such as the\n+     * URI. In cases where the arguments are parsed from the URI, the data\n+     * MUST be compatible with what PHP's `parse_str()` would return for\n+     * purposes of how duplicate query parameters are handled, and how nested\n+     * sets are handled.\n+     *\n+     * @return array\n+     */\n+    function getQueryParams() {\n+\n+        return $this->inner->getQueryParams();\n+\n+    }\n+\n+    /**\n+     * Retrieve the upload file metadata.\n+     *\n+     * This method MUST return file upload metadata in the same structure\n+     * as PHP's $_FILES superglobal.\n+     *\n+     * These values SHOULD remain immutable over the course of the incoming\n+     * request. They MAY be injected during instantiation, such as from PHP's\n+     * $_FILES superglobal, or MAY be derived from other sources.\n+     *\n+     * @return array Upload file(s) metadata, if any.\n+     */\n+    function getFileParams() {\n+\n+        return $this->inner->getFileParams();\n+\n+    }\n+\n+    /**\n+     * Retrieve any parameters provided in the request body.\n+     *\n+     * If the request body can be deserialized to an array, this method MAY be\n+     * used to retrieve them. These MAY be injected during instantiation from\n+     * PHP's $_POST superglobal. The data IS NOT REQUIRED to come from $_POST,\n+     * but MUST be an array.\n+     *\n+     * In cases where the request content cannot be coerced to an array, the\n+     * parent getBody() method should be used to retrieve the body content.\n+     *\n+     * @return array The deserialized body parameters, if any.\n+     */\n+    function getBodyParams() {\n+\n+        return $this->inner->getBodyParams();\n+\n+    }\n+\n+    /**\n+     * Set the request body parameters.\n+     *\n+     * If the body content can be deserialized to an array, the values obtained\n+     * MAY then be injected into the response using this method. This method\n+     * will typically be invoked by a factory marshaling request parameters.\n+     *\n+     * @param array $values The deserialized body parameters, if any.\n+     * @return void\n+     * @throws \\InvalidArgumentException For $values that cannot be accepted.\n+     */\n+    function setBodyParams(array $values) {\n+\n+        $this->inner->setBodyParams($values);\n+\n+    }\n+\n+    /**\n+     * Retrieve attributes derived from the request.\n+     *\n+     * If a router or similar is used to match against the path and/or request,\n+     * this method MAY be used to retrieve the results, so long as those\n+     * results can be represented as an array.\n+     *\n+     * @return array Attributes derived from the request.\n+     */\n+    function getAttributes() {\n+\n+        return $this->getAttributes();\n+\n+    }\n+\n+    /**\n+     * Set attributes derived from the request\n+     *\n+     * If a router or similar is used to match against the path and/or request,\n+     * this method MAY be used to inject the request with the results, so long\n+     * as those results can be represented as an array.\n+     *\n+     * @param array $attributes Attributes derived from the request.\n+     * @return void\n+     */\n+    function setAttributes(array $attributes) {\n+\n+        $this->setAttributes($attributes);","path":"lib/RequestDecorator.php","position":234,"original_position":234,"commit_id":"d18449220d35efecc77eae8342243332d0dd5bf3","original_commit_id":"d18449220d35efecc77eae8342243332d0dd5bf3","user":{"login":"staabm","id":120441,"avatar_url":"https://avatars.githubusercontent.com/u/120441?v=2","gravatar_id":"","url":"https://api.github.com/users/staabm","html_url":"https://github.com/staabm","followers_url":"https://api.github.com/users/staabm/followers","following_url":"https://api.github.com/users/staabm/following{/other_user}","gists_url":"https://api.github.com/users/staabm/gists{/gist_id}","starred_url":"https://api.github.com/users/staabm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staabm/subscriptions","organizations_url":"https://api.github.com/users/staabm/orgs","repos_url":"https://api.github.com/users/staabm/repos","events_url":"https://api.github.com/users/staabm/events{/privacy}","received_events_url":"https://api.github.com/users/staabm/received_events","type":"User","site_admin":false},"body":"same here, recursion","created_at":"2014-10-22T07:59:10Z","updated_at":"2014-10-22T07:59:10Z","html_url":"https://github.com/fruux/sabre-http/pull/17#discussion_r19198899","pull_request_url":"https://api.github.com/repos/fruux/sabre-http/pulls/17","_links":{"self":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/comments/19198899"},"html":{"href":"https://github.com/fruux/sabre-http/pull/17#discussion_r19198899"},"pull_request":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/17"}}},"pull_request":{"url":"https://api.github.com/repos/fruux/sabre-http/pulls/17","id":23134706,"html_url":"https://github.com/fruux/sabre-http/pull/17","diff_url":"https://github.com/fruux/sabre-http/pull/17.diff","patch_url":"https://github.com/fruux/sabre-http/pull/17.patch","issue_url":"https://api.github.com/repos/fruux/sabre-http/issues/17","number":17,"state":"open","locked":false,"title":"Psr 7","user":{"login":"evert","id":178960,"avatar_url":"https://avatars.githubusercontent.com/u/178960?v=2","gravatar_id":"","url":"https://api.github.com/users/evert","html_url":"https://github.com/evert","followers_url":"https://api.github.com/users/evert/followers","following_url":"https://api.github.com/users/evert/following{/other_user}","gists_url":"https://api.github.com/users/evert/gists{/gist_id}","starred_url":"https://api.github.com/users/evert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evert/subscriptions","organizations_url":"https://api.github.com/users/evert/orgs","repos_url":"https://api.github.com/users/evert/repos","events_url":"https://api.github.com/users/evert/events{/privacy}","received_events_url":"https://api.github.com/users/evert/received_events","type":"User","site_admin":false},"body":"**Do not merge, this ticket just exists for tracking purposes until its done**\r\n\r\nThis branch migrates sabre/http to [PSR-7][1]. PSR-7 solves the same problem what our `RequestInterface`, `ResponseInterface` and `MessageInterface` also solve.\r\n\r\nBecause of the benefits of standards-compliance and the potential ecosystem that may spawn around this, we'll start supporting this in a next major sabre/http version, 4.0.\r\n\r\nTodo:\r\n\r\n- [ ] 100% unittest coverage of new methods.\r\n- [ ] PSR-7 must be released.\r\n- [ ] RequestDecorator now only accepts the `IncomingRequestInterface` variant. It should also work for the plain `RequestInterface`.\r\n- [ ] The Client should ideally typehint on the generic PSR request interface, not just the Sabre one.\r\n\r\n## Changes\r\n\r\n### Bodies are now represented by a Stream object.\r\n\r\nFor a lot of real-world use-cases that we used address, using a stream object is unfortunately a bit clumsy, and due to the nature of the Stream object, we can also not fully provide backwards compatibility.\r\n\r\n`getBody()` now returns the `Stream` object (which is pretty much a direct implementation of `StreamInterface`). This object can accept both a `string` or a `stream` as its main argument.\r\n\r\n`setBody()` _must_ receive a StreamInterface-compatible object now. This means a lot of changes in sabre/dav unfortunately. Because it's a strict method signature, we're also not able to provide backwards compatibility.\r\n\r\n### Request vs. IncomingRequest\r\n\r\nOur `Request` always was what the new PSR `IncomingRequestInterface` now is. The `IncomingRequestInterface` is specifically for the 'server' use-case.\r\n\r\nHowever, since these are mostly value objects, we don't really see a reason to split these up. So our `Request` object is in fact the PSR `IncomingRequestInterface`, and we don't have a separate `RequestInterface`.\r\n\r\n### Methods that have been renamed\r\n\r\n| Old | New |\r\n| ---- | ---- |\r\n| `Message::setHttpVersion` | `Message::setProtocolVersion` |\r\n| `Message::getHttpVersion` | `Message::getProtocolVersion` |\r\n| `Request::setPostData` | `Message::setBodyParams` |\r\n| `Request::getPostData` | `Message::getBodyParams` |\r\n| `Request::getQueryParameters` | `Message::getQueryParams` |\r\n| `Response::getStatusText` | `Message::getReasonPhrase` |\r\n| `Response::getStatus` | `Message::getStatusCode` |\r\n\r\nFor _all_ of these methods we provide backwards compatibility through 3 new traits:\r\n\r\n* `Sabre\\HTTP\\BC\\MessageTrait`\r\n* `Sabre\\HTTP\\BC\\RequestTrait`\r\n* `Sabre\\HTTP\\BC\\ResponseTrait`\r\n\r\nIn a major version after version 4.0 we will remove these traits.\r\n\r\n### Methods that will be removed\r\n\r\nThe following methods still work, but will be removed in a major version after 4.0:\r\n\r\n* `Message:addHeaders`\r\n* `Message:setHeaders`\r\n\r\nThe following methods also still work, but their semantics have changed a bit:\r\n\r\n* `Message:getBodyAsString`\r\n* `Message:getBodyAsStream`\r\n\r\nThe most important thing here is that while these methods still exist, you absolutely _must_ reinitialize the stream object after using it _if_ you want to be able to read the body more than once.\r\n\r\nThis means that when you call either of those methods, you should call `setBody()` after with a valid value.\r\n\r\nLastly, `Response::setStatus`.\r\n\r\nThis was a handy method to set either just a status code with a default phrase, or set the status in one go:\r\n\r\n```php\r\n$response->setStatus(200);\r\n// is now\r\n$response->setStatusCode(200);\r\n$response->setReasonPhrase(Response::$statusCodes[200]);\r\n\r\n// and\r\n\r\n$response->setStatus('200 OK');\r\n// is now\r\n$response->setStatusCode(200);\r\n$response->setReasonPhrase('OK');\r\n```\r\n\r\nThis is not as pretty, so maybe we can find a better workaround.\r\n\r\n### New Features\r\n\r\nThe Request object now also contains references to:\r\n\r\n* `$_FILES`\r\n* `$_COOKIE`\r\n\r\n### Decorators can now decorate *any* PSR-compatible object.\r\n\r\nThis will allow people to use use the decorators even if their Request and Response objects are created by 3rd-party systems.\r\n\r\n[1]: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md","created_at":"2014-10-22T04:37:20Z","updated_at":"2014-10-22T07:59:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8cb4862f6578b52d13debb75011555faee3cb642","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/fruux/sabre-http/pulls/17/commits","review_comments_url":"https://api.github.com/repos/fruux/sabre-http/pulls/17/comments","review_comment_url":"https://api.github.com/repos/fruux/sabre-http/pulls/comments/{number}","comments_url":"https://api.github.com/repos/fruux/sabre-http/issues/17/comments","statuses_url":"https://api.github.com/repos/fruux/sabre-http/statuses/d18449220d35efecc77eae8342243332d0dd5bf3","head":{"label":"fruux:psr-7","ref":"psr-7","sha":"d18449220d35efecc77eae8342243332d0dd5bf3","user":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=2","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"repo":{"id":5848865,"name":"sabre-http","full_name":"fruux/sabre-http","owner":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=2","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fruux/sabre-http","description":"The sabre/http library provides utilities for dealing with http requests and responses.","fork":false,"url":"https://api.github.com/repos/fruux/sabre-http","forks_url":"https://api.github.com/repos/fruux/sabre-http/forks","keys_url":"https://api.github.com/repos/fruux/sabre-http/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fruux/sabre-http/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fruux/sabre-http/teams","hooks_url":"https://api.github.com/repos/fruux/sabre-http/hooks","issue_events_url":"https://api.github.com/repos/fruux/sabre-http/issues/events{/number}","events_url":"https://api.github.com/repos/fruux/sabre-http/events","assignees_url":"https://api.github.com/repos/fruux/sabre-http/assignees{/user}","branches_url":"https://api.github.com/repos/fruux/sabre-http/branches{/branch}","tags_url":"https://api.github.com/repos/fruux/sabre-http/tags","blobs_url":"https://api.github.com/repos/fruux/sabre-http/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fruux/sabre-http/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fruux/sabre-http/git/refs{/sha}","trees_url":"https://api.github.com/repos/fruux/sabre-http/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fruux/sabre-http/statuses/{sha}","languages_url":"https://api.github.com/repos/fruux/sabre-http/languages","stargazers_url":"https://api.github.com/repos/fruux/sabre-http/stargazers","contributors_url":"https://api.github.com/repos/fruux/sabre-http/contributors","subscribers_url":"https://api.github.com/repos/fruux/sabre-http/subscribers","subscription_url":"https://api.github.com/repos/fruux/sabre-http/subscription","commits_url":"https://api.github.com/repos/fruux/sabre-http/commits{/sha}","git_commits_url":"https://api.github.com/repos/fruux/sabre-http/git/commits{/sha}","comments_url":"https://api.github.com/repos/fruux/sabre-http/comments{/number}","issue_comment_url":"https://api.github.com/repos/fruux/sabre-http/issues/comments/{number}","contents_url":"https://api.github.com/repos/fruux/sabre-http/contents/{+path}","compare_url":"https://api.github.com/repos/fruux/sabre-http/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fruux/sabre-http/merges","archive_url":"https://api.github.com/repos/fruux/sabre-http/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fruux/sabre-http/downloads","issues_url":"https://api.github.com/repos/fruux/sabre-http/issues{/number}","pulls_url":"https://api.github.com/repos/fruux/sabre-http/pulls{/number}","milestones_url":"https://api.github.com/repos/fruux/sabre-http/milestones{/number}","notifications_url":"https://api.github.com/repos/fruux/sabre-http/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fruux/sabre-http/labels{/name}","releases_url":"https://api.github.com/repos/fruux/sabre-http/releases{/id}","created_at":"2012-09-17T23:37:11Z","updated_at":"2014-10-19T21:47:08Z","pushed_at":"2014-10-22T05:03:51Z","git_url":"git://github.com/fruux/sabre-http.git","ssh_url":"git@github.com:fruux/sabre-http.git","clone_url":"https://github.com/fruux/sabre-http.git","svn_url":"https://github.com/fruux/sabre-http","homepage":"http://sabre.io","size":1179,"stargazers_count":57,"watchers_count":57,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":2,"forks":10,"open_issues":2,"watchers":57,"default_branch":"master"}},"base":{"label":"fruux:master","ref":"master","sha":"5bc28e4b0c127fe133198a06505c62bc771c4156","user":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=2","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"repo":{"id":5848865,"name":"sabre-http","full_name":"fruux/sabre-http","owner":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=2","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fruux/sabre-http","description":"The sabre/http library provides utilities for dealing with http requests and responses.","fork":false,"url":"https://api.github.com/repos/fruux/sabre-http","forks_url":"https://api.github.com/repos/fruux/sabre-http/forks","keys_url":"https://api.github.com/repos/fruux/sabre-http/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fruux/sabre-http/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fruux/sabre-http/teams","hooks_url":"https://api.github.com/repos/fruux/sabre-http/hooks","issue_events_url":"https://api.github.com/repos/fruux/sabre-http/issues/events{/number}","events_url":"https://api.github.com/repos/fruux/sabre-http/events","assignees_url":"https://api.github.com/repos/fruux/sabre-http/assignees{/user}","branches_url":"https://api.github.com/repos/fruux/sabre-http/branches{/branch}","tags_url":"https://api.github.com/repos/fruux/sabre-http/tags","blobs_url":"https://api.github.com/repos/fruux/sabre-http/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fruux/sabre-http/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fruux/sabre-http/git/refs{/sha}","trees_url":"https://api.github.com/repos/fruux/sabre-http/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fruux/sabre-http/statuses/{sha}","languages_url":"https://api.github.com/repos/fruux/sabre-http/languages","stargazers_url":"https://api.github.com/repos/fruux/sabre-http/stargazers","contributors_url":"https://api.github.com/repos/fruux/sabre-http/contributors","subscribers_url":"https://api.github.com/repos/fruux/sabre-http/subscribers","subscription_url":"https://api.github.com/repos/fruux/sabre-http/subscription","commits_url":"https://api.github.com/repos/fruux/sabre-http/commits{/sha}","git_commits_url":"https://api.github.com/repos/fruux/sabre-http/git/commits{/sha}","comments_url":"https://api.github.com/repos/fruux/sabre-http/comments{/number}","issue_comment_url":"https://api.github.com/repos/fruux/sabre-http/issues/comments/{number}","contents_url":"https://api.github.com/repos/fruux/sabre-http/contents/{+path}","compare_url":"https://api.github.com/repos/fruux/sabre-http/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fruux/sabre-http/merges","archive_url":"https://api.github.com/repos/fruux/sabre-http/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fruux/sabre-http/downloads","issues_url":"https://api.github.com/repos/fruux/sabre-http/issues{/number}","pulls_url":"https://api.github.com/repos/fruux/sabre-http/pulls{/number}","milestones_url":"https://api.github.com/repos/fruux/sabre-http/milestones{/number}","notifications_url":"https://api.github.com/repos/fruux/sabre-http/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fruux/sabre-http/labels{/name}","releases_url":"https://api.github.com/repos/fruux/sabre-http/releases{/id}","created_at":"2012-09-17T23:37:11Z","updated_at":"2014-10-19T21:47:08Z","pushed_at":"2014-10-22T05:03:51Z","git_url":"git://github.com/fruux/sabre-http.git","ssh_url":"git@github.com:fruux/sabre-http.git","clone_url":"https://github.com/fruux/sabre-http.git","svn_url":"https://github.com/fruux/sabre-http","homepage":"http://sabre.io","size":1179,"stargazers_count":57,"watchers_count":57,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":2,"forks":10,"open_issues":2,"watchers":57,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/17"},"html":{"href":"https://github.com/fruux/sabre-http/pull/17"},"issue":{"href":"https://api.github.com/repos/fruux/sabre-http/issues/17"},"comments":{"href":"https://api.github.com/repos/fruux/sabre-http/issues/17/comments"},"review_comments":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/17/comments"},"review_comment":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/fruux/sabre-http/pulls/17/commits"},"statuses":{"href":"https://api.github.com/repos/fruux/sabre-http/statuses/d18449220d35efecc77eae8342243332d0dd5bf3"}}}}