{"action":"created","comment":{"url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/comments/86487321","pull_request_review_id":7144506,"id":86487321,"diff_hunk":"@@ -0,0 +1,249 @@\n+/*\n+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n+ *\n+ * WSO2 Inc. licenses this file to you under the Apache License,\n+ * Version 2.0 (the \"License\"); you may not use this file except\n+ * in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied. See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+package org.wso2.carbon.apimgt.gateway.handlers;\n+\n+import io.netty.channel.ChannelHandlerContext;\n+import io.netty.channel.ChannelInboundHandlerAdapter;\n+import io.netty.handler.codec.http.FullHttpRequest;\n+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;\n+import io.netty.handler.codec.http.websocketx.WebSocketFrame;\n+import org.apache.axiom.util.UIDGenerator;\n+import org.apache.http.HttpHeaders;\n+import org.json.simple.JSONObject;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+import org.wso2.carbon.apimgt.api.APIManagementException;\n+import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityConstants;\n+import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException;\n+import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityUtils;\n+import org.wso2.carbon.apimgt.gateway.handlers.throttling.APIThrottleConstants;\n+import org.wso2.carbon.apimgt.gateway.throttling.publisher.ThrottleDataPublisher;\n+import org.wso2.carbon.apimgt.impl.APIConstants;\n+import org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO;\n+import org.wso2.carbon.apimgt.impl.utils.APIUtil;\n+import org.wso2.carbon.context.PrivilegedCarbonContext;\n+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;\n+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;\n+\n+import java.net.InetSocketAddress;\n+\n+/**\n+ * This is a handler which is actually embedded to the netty pipeline which does operations such as\n+ * authentication and throttling for the websocket handshake and subsequent websocket frames.\n+ */\n+public class WebsocketInboundHandler extends ChannelInboundHandlerAdapter {\n+\tprivate static String tenantDomain;\n+\tprivate boolean isDefaultVersion;\n+\tprivate static int port;\n+\tprivate static volatile ThrottleDataPublisher throttleDataPublisher = null;\n+\tprivate static Logger log = LoggerFactory.getLogger(WebsocketInboundHandler.class);\n+\tprivate String uri;\n+\tprivate String version;\n+\tprivate APIKeyValidationInfoDTO infoDTO = new APIKeyValidationInfoDTO();\n+\n+\tpublic WebsocketInboundHandler() {\n+\n+\t\tif (throttleDataPublisher == null) {\n+\t\t\t// The publisher initializes in the first request only\n+\t\t\tsynchronized (this) {\n+\t\t\t\tthrottleDataPublisher = new ThrottleDataPublisher();\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * extract the version from the request uri\n+\t *\n+\t * @param url\n+\t * @return version String\n+\t */\n+\tpublic static String getversionFromUrl(final String url) {\n+\t\treturn url.replaceFirst(\".*/([^/?]+).*\", \"$1\");\n+\t}\n+\n+\t@SuppressWarnings(\"unchecked\")\n+\t@Override\n+\tpublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n+\n+\t\t//check if the request is a handshake\n+\t\tif (msg instanceof FullHttpRequest) {\n+\t\t\tFullHttpRequest req = (FullHttpRequest) msg;\n+\t\t\turi = req.getUri();\n+\t\t\tport = ((InetSocketAddress) ctx.channel().localAddress()).getPort();\n+\t\t\ttenantDomain = MultitenantUtils.getTenantDomainFromUrl(req.getUri());\n+\t\t\tif (tenantDomain.equals(req.getUri())) {\n+\t\t\t\ttenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;\n+\t\t\t} else {\n+\t\t\t\treq.setUri(req.getUri().replaceFirst(\"/\",\"-\"));\n+\t\t\t\tmsg = req;\n+\t\t\t}\n+\t\t\tif (validateOAuthHeader(req)) {\n+\t\t\t\treq.setUri(uri);\n+\t\t\t\tctx.fireChannelRead(msg);\n+\t\t\t} else {\n+\t\t\t\tctx.writeAndFlush(new TextWebSocketFrame(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE));\n+\t\t\t\tthrow new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS,\n+\t\t\t\t                               APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);\n+\t\t\t}\n+\t\t} else if (msg instanceof WebSocketFrame) {\n+\n+\t\t\t\tif (doThrottle(ctx, (WebSocketFrame) msg)) {\n+\t\t\t\t\tctx.fireChannelRead(msg);\n+\t\t\t\t} else {\n+\t\t\t\t\tctx.writeAndFlush(new TextWebSocketFrame(\"Websocket frame throttled out\"));\n+\t\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Authenticate request\n+\t *\n+\t * @param req Full Http Request\n+\t * @return true if the access token is valid\n+\t * @throws APIManagementException\n+\t */\n+\tprivate boolean validateOAuthHeader(FullHttpRequest req)\n+\t\t\tthrows APIManagementException, APISecurityException {\n+\t\ttry {\n+\t\t\tPrivilegedCarbonContext.startTenantFlow();\n+\t\t\tPrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);\n+\t\t\tversion = getversionFromUrl(uri);\n+\t\t\tAPIKeyValidationInfoDTO info;\n+\t\t\tif (!req.headers().contains(HttpHeaders.AUTHORIZATION)) {\n+\t\t\t\tlog.error(\"No Authorization Header Present\");\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tString[] auth = req.headers().get(HttpHeaders.AUTHORIZATION).split(\" \");\n+\t\t\tif (APIConstants.CONSUMER_KEY_SEGMENT.equals(auth[0])) {\n+\t\t\t\tString cacheKey;\n+\t\t\t\tString apikey = auth[1];\n+\t\t\t\tif (WebsocketUtil.isRemoveOAuthHeadersFromOutMessage()) {\n+\t\t\t\t\treq.headers().remove(HttpHeaders.AUTHORIZATION);\n+\t\t\t\t}\n+\t\t\t\t//If the key have already been validated\n+\t\t\t\tif (WebsocketUtil.isGatewayTokenCacheEnabled()) {\n+\t\t\t\t\tcacheKey = WebsocketUtil.getAccessTokenCacheKey(apikey, uri);\n+\t\t\t\t\tinfo = WebsocketUtil.validateCache(apikey, cacheKey);\n+\t\t\t\t\tif (info != null) {\n+\t\t\t\t\t\tinfoDTO = info;\n+\t\t\t\t\t\treturn info.isAuthorized();\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\tString keyValidatorClientType = APISecurityUtils.getKeyValidatorClientType();\n+\t\t\t\tif (APIConstants.API_KEY_VALIDATOR_WS_CLIENT.equals(keyValidatorClientType)) {\n+\t\t\t\t\tinfo = new WebsocketWSClient().getAPIKeyData(uri, version, apikey);\n+\t\t\t\t} else if (APIConstants.API_KEY_VALIDATOR_THRIFT_CLIENT.equals(keyValidatorClientType)) {\n+\t\t\t\t\tinfo = new WebsocketThriftClient().getAPIKeyData(uri, version, apikey);\n+\t\t\t\t} else {\n+\t\t\t\t\treturn false;\n+\t\t\t\t}\n+\t\t\t\tif (info == null || !info.isAuthorized()) {\n+\t\t\t\t\treturn false;\n+\t\t\t\t}\n+\t\t\t\tif (info.getApiName() != null && info.getApiName().contains(\"*\")) {\n+\t\t\t\t\tisDefaultVersion = true;\n+\t\t\t\t\tString[] str = info.getApiName().split(\"\\\\*\");\n+\t\t\t\t\tversion = str[1];\n+\t\t\t\t\turi += \"/\" + str[1];\n+\t\t\t\t\tinfo.setApiName(str[0]);\n+\t\t\t\t}\n+\t\t\t\tif (APIConstants.API_KEY_TYPE_PRODUCTION.equals(info.getType())) {\n+\t\t\t\t\turi = \"/_PRODUCTION_\" + uri;\n+\t\t\t\t}\n+\t\t\t\tif (APIConstants.API_KEY_TYPE_SANDBOX.equals(info.getType())) {\n+\t\t\t\t\turi = \"/_SANDBOX_\" + uri;\n+\t\t\t\t}\n+\t\t\t\tif (WebsocketUtil.isGatewayTokenCacheEnabled()) {\n+\t\t\t\t\tcacheKey = WebsocketUtil.getAccessTokenCacheKey(apikey, uri);\n+\t\t\t\t\tWebsocketUtil.putCache(info, apikey, cacheKey);\n+\t\t\t\t}\n+\t\t\t\tinfoDTO = info;\n+\t\t\t\treturn true;\n+\t\t\t} else {\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t}finally {","path":"components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/WebsocketInboundHandler.java","position":null,"original_position":180,"commit_id":"1f8227c6747ef8b5afe69d48e0868019795b9b3c","original_commit_id":"25a0f65a4467274aceb8cac2f4c69143df915190","user":{"login":"Arshardh","id":15942605,"avatar_url":"https://avatars.githubusercontent.com/u/15942605?v=3","gravatar_id":"","url":"https://api.github.com/users/Arshardh","html_url":"https://github.com/Arshardh","followers_url":"https://api.github.com/users/Arshardh/followers","following_url":"https://api.github.com/users/Arshardh/following{/other_user}","gists_url":"https://api.github.com/users/Arshardh/gists{/gist_id}","starred_url":"https://api.github.com/users/Arshardh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Arshardh/subscriptions","organizations_url":"https://api.github.com/users/Arshardh/orgs","repos_url":"https://api.github.com/users/Arshardh/repos","events_url":"https://api.github.com/users/Arshardh/events{/privacy}","received_events_url":"https://api.github.com/users/Arshardh/received_events","type":"User","site_admin":false},"body":"Fixed in 1f8227c","created_at":"2016-11-04T04:20:26Z","updated_at":"2016-11-04T04:20:26Z","html_url":"https://github.com/wso2/carbon-apimgt/pull/3124#discussion_r86487321","pull_request_url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124","_links":{"self":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/comments/86487321"},"html":{"href":"https://github.com/wso2/carbon-apimgt/pull/3124#discussion_r86487321"},"pull_request":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124"}}},"pull_request":{"url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124","id":92281060,"html_url":"https://github.com/wso2/carbon-apimgt/pull/3124","diff_url":"https://github.com/wso2/carbon-apimgt/pull/3124.diff","patch_url":"https://github.com/wso2/carbon-apimgt/pull/3124.patch","issue_url":"https://api.github.com/repos/wso2/carbon-apimgt/issues/3124","number":3124,"state":"open","locked":false,"title":"Websocket Response path mediation","user":{"login":"Arshardh","id":15942605,"avatar_url":"https://avatars.githubusercontent.com/u/15942605?v=3","gravatar_id":"","url":"https://api.github.com/users/Arshardh","html_url":"https://github.com/Arshardh","followers_url":"https://api.github.com/users/Arshardh/followers","following_url":"https://api.github.com/users/Arshardh/following{/other_user}","gists_url":"https://api.github.com/users/Arshardh/gists{/gist_id}","starred_url":"https://api.github.com/users/Arshardh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Arshardh/subscriptions","organizations_url":"https://api.github.com/users/Arshardh/orgs","repos_url":"https://api.github.com/users/Arshardh/repos","events_url":"https://api.github.com/users/Arshardh/events{/privacy}","received_events_url":"https://api.github.com/users/Arshardh/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-11-04T04:01:44Z","updated_at":"2016-11-04T04:20:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2770a6dd1d718ef00284d518eb62204dacfda53c","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124/commits","review_comments_url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124/comments","review_comment_url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wso2/carbon-apimgt/issues/3124/comments","statuses_url":"https://api.github.com/repos/wso2/carbon-apimgt/statuses/1f8227c6747ef8b5afe69d48e0868019795b9b3c","head":{"label":"Arshardh:response-path","ref":"response-path","sha":"1f8227c6747ef8b5afe69d48e0868019795b9b3c","user":{"login":"Arshardh","id":15942605,"avatar_url":"https://avatars.githubusercontent.com/u/15942605?v=3","gravatar_id":"","url":"https://api.github.com/users/Arshardh","html_url":"https://github.com/Arshardh","followers_url":"https://api.github.com/users/Arshardh/followers","following_url":"https://api.github.com/users/Arshardh/following{/other_user}","gists_url":"https://api.github.com/users/Arshardh/gists{/gist_id}","starred_url":"https://api.github.com/users/Arshardh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Arshardh/subscriptions","organizations_url":"https://api.github.com/users/Arshardh/orgs","repos_url":"https://api.github.com/users/Arshardh/repos","events_url":"https://api.github.com/users/Arshardh/events{/privacy}","received_events_url":"https://api.github.com/users/Arshardh/received_events","type":"User","site_admin":false},"repo":{"id":66906391,"name":"carbon-apimgt","full_name":"Arshardh/carbon-apimgt","owner":{"login":"Arshardh","id":15942605,"avatar_url":"https://avatars.githubusercontent.com/u/15942605?v=3","gravatar_id":"","url":"https://api.github.com/users/Arshardh","html_url":"https://github.com/Arshardh","followers_url":"https://api.github.com/users/Arshardh/followers","following_url":"https://api.github.com/users/Arshardh/following{/other_user}","gists_url":"https://api.github.com/users/Arshardh/gists{/gist_id}","starred_url":"https://api.github.com/users/Arshardh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Arshardh/subscriptions","organizations_url":"https://api.github.com/users/Arshardh/orgs","repos_url":"https://api.github.com/users/Arshardh/repos","events_url":"https://api.github.com/users/Arshardh/events{/privacy}","received_events_url":"https://api.github.com/users/Arshardh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Arshardh/carbon-apimgt","description":null,"fork":true,"url":"https://api.github.com/repos/Arshardh/carbon-apimgt","forks_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/forks","keys_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/teams","hooks_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/hooks","issue_events_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/issues/events{/number}","events_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/events","assignees_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/assignees{/user}","branches_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/branches{/branch}","tags_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/tags","blobs_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/git/refs{/sha}","trees_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/statuses/{sha}","languages_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/languages","stargazers_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/stargazers","contributors_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/contributors","subscribers_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/subscribers","subscription_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/subscription","commits_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/commits{/sha}","git_commits_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/git/commits{/sha}","comments_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/comments{/number}","issue_comment_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/issues/comments{/number}","contents_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/contents/{+path}","compare_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/merges","archive_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/downloads","issues_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/issues{/number}","pulls_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/pulls{/number}","milestones_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/milestones{/number}","notifications_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/labels{/name}","releases_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/releases{/id}","deployments_url":"https://api.github.com/repos/Arshardh/carbon-apimgt/deployments","created_at":"2016-08-30T04:27:46Z","updated_at":"2016-08-30T04:28:02Z","pushed_at":"2016-11-04T04:18:23Z","git_url":"git://github.com/Arshardh/carbon-apimgt.git","ssh_url":"git@github.com:Arshardh/carbon-apimgt.git","clone_url":"https://github.com/Arshardh/carbon-apimgt.git","svn_url":"https://github.com/Arshardh/carbon-apimgt","homepage":null,"size":153608,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","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":"wso2:web-socket","ref":"web-socket","sha":"ab8234a907a56078a06b1524622a68ef5c2a4618","user":{"login":"wso2","id":533043,"avatar_url":"https://avatars.githubusercontent.com/u/533043?v=3","gravatar_id":"","url":"https://api.github.com/users/wso2","html_url":"https://github.com/wso2","followers_url":"https://api.github.com/users/wso2/followers","following_url":"https://api.github.com/users/wso2/following{/other_user}","gists_url":"https://api.github.com/users/wso2/gists{/gist_id}","starred_url":"https://api.github.com/users/wso2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wso2/subscriptions","organizations_url":"https://api.github.com/users/wso2/orgs","repos_url":"https://api.github.com/users/wso2/repos","events_url":"https://api.github.com/users/wso2/events{/privacy}","received_events_url":"https://api.github.com/users/wso2/received_events","type":"Organization","site_admin":false},"repo":{"id":17201744,"name":"carbon-apimgt","full_name":"wso2/carbon-apimgt","owner":{"login":"wso2","id":533043,"avatar_url":"https://avatars.githubusercontent.com/u/533043?v=3","gravatar_id":"","url":"https://api.github.com/users/wso2","html_url":"https://github.com/wso2","followers_url":"https://api.github.com/users/wso2/followers","following_url":"https://api.github.com/users/wso2/following{/other_user}","gists_url":"https://api.github.com/users/wso2/gists{/gist_id}","starred_url":"https://api.github.com/users/wso2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wso2/subscriptions","organizations_url":"https://api.github.com/users/wso2/orgs","repos_url":"https://api.github.com/users/wso2/repos","events_url":"https://api.github.com/users/wso2/events{/privacy}","received_events_url":"https://api.github.com/users/wso2/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/wso2/carbon-apimgt","description":null,"fork":false,"url":"https://api.github.com/repos/wso2/carbon-apimgt","forks_url":"https://api.github.com/repos/wso2/carbon-apimgt/forks","keys_url":"https://api.github.com/repos/wso2/carbon-apimgt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wso2/carbon-apimgt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wso2/carbon-apimgt/teams","hooks_url":"https://api.github.com/repos/wso2/carbon-apimgt/hooks","issue_events_url":"https://api.github.com/repos/wso2/carbon-apimgt/issues/events{/number}","events_url":"https://api.github.com/repos/wso2/carbon-apimgt/events","assignees_url":"https://api.github.com/repos/wso2/carbon-apimgt/assignees{/user}","branches_url":"https://api.github.com/repos/wso2/carbon-apimgt/branches{/branch}","tags_url":"https://api.github.com/repos/wso2/carbon-apimgt/tags","blobs_url":"https://api.github.com/repos/wso2/carbon-apimgt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wso2/carbon-apimgt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wso2/carbon-apimgt/git/refs{/sha}","trees_url":"https://api.github.com/repos/wso2/carbon-apimgt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wso2/carbon-apimgt/statuses/{sha}","languages_url":"https://api.github.com/repos/wso2/carbon-apimgt/languages","stargazers_url":"https://api.github.com/repos/wso2/carbon-apimgt/stargazers","contributors_url":"https://api.github.com/repos/wso2/carbon-apimgt/contributors","subscribers_url":"https://api.github.com/repos/wso2/carbon-apimgt/subscribers","subscription_url":"https://api.github.com/repos/wso2/carbon-apimgt/subscription","commits_url":"https://api.github.com/repos/wso2/carbon-apimgt/commits{/sha}","git_commits_url":"https://api.github.com/repos/wso2/carbon-apimgt/git/commits{/sha}","comments_url":"https://api.github.com/repos/wso2/carbon-apimgt/comments{/number}","issue_comment_url":"https://api.github.com/repos/wso2/carbon-apimgt/issues/comments{/number}","contents_url":"https://api.github.com/repos/wso2/carbon-apimgt/contents/{+path}","compare_url":"https://api.github.com/repos/wso2/carbon-apimgt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wso2/carbon-apimgt/merges","archive_url":"https://api.github.com/repos/wso2/carbon-apimgt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wso2/carbon-apimgt/downloads","issues_url":"https://api.github.com/repos/wso2/carbon-apimgt/issues{/number}","pulls_url":"https://api.github.com/repos/wso2/carbon-apimgt/pulls{/number}","milestones_url":"https://api.github.com/repos/wso2/carbon-apimgt/milestones{/number}","notifications_url":"https://api.github.com/repos/wso2/carbon-apimgt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wso2/carbon-apimgt/labels{/name}","releases_url":"https://api.github.com/repos/wso2/carbon-apimgt/releases{/id}","deployments_url":"https://api.github.com/repos/wso2/carbon-apimgt/deployments","created_at":"2014-02-26T06:46:48Z","updated_at":"2016-10-24T04:47:12Z","pushed_at":"2016-11-04T04:18:23Z","git_url":"git://github.com/wso2/carbon-apimgt.git","ssh_url":"git@github.com:wso2/carbon-apimgt.git","clone_url":"https://github.com/wso2/carbon-apimgt.git","svn_url":"https://github.com/wso2/carbon-apimgt","homepage":null,"size":189542,"stargazers_count":20,"watchers_count":20,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":200,"mirror_url":null,"open_issues_count":11,"forks":200,"open_issues":11,"watchers":20,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124"},"html":{"href":"https://github.com/wso2/carbon-apimgt/pull/3124"},"issue":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/issues/3124"},"comments":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/issues/3124/comments"},"review_comments":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124/comments"},"review_comment":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/pulls/3124/commits"},"statuses":{"href":"https://api.github.com/repos/wso2/carbon-apimgt/statuses/1f8227c6747ef8b5afe69d48e0868019795b9b3c"}}}}
{"actor":{"display_login":"Arshardh"}}