{"action":"created","comment":{"url":"https://api.github.com/repos/natsys/tempesta/pulls/comments/43046910","id":43046910,"diff_hunk":"@@ -0,0 +1,399 @@\n+/**\n+ *  \t\tTempesta FW\n+ *\n+ * Copyright (C) 2015 Tempesta Technologies, Inc.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation; either version 2 of the License,\n+ * or (at your option) any later version.\n+ *\n+ * This program is distributed in the hope that it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n+ * FOR A PARTICULAR PURPOSE.\n+ *\n+ * See the GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License along with\n+ * his program; if not, write to the Free Software Foundation, Inc., 59\n+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n+ */\n+\n+#include <linux/inet.h>\n+\n+#include \"../../classifier.h\"\n+#include \"../../client.h\"\n+#include \"../../connection.h\"\n+#include \"../../sync_socket.h\"\n+#include \"../../http_msg.h\"\n+#include \"../../log.h\"\n+#include \"../../tempesta_fw.h\"\n+\n+#include \"helpers.h\"\n+#include \"kallsyms_helper.h\"\n+#include \"sched_helper.h\"\n+#include \"test.h\"\n+\n+#define FRANG_HASH_BITS 17\n+#define FRANG_FREQ\t8\n+#define HANDLER_OFF\t0\n+\n+typedef struct {\n+\tunsigned long\tts;\n+\tunsigned int\tconn_new;\n+\tunsigned int\treq;\n+} FrangRates;\n+\n+typedef struct frang_account_t {\n+\tstruct hlist_node hentry;\n+\tstruct in6_addr addr;\t/* client address */\n+\tunsigned long last_ts;\t/* last access time */\n+\tunsigned int conn_curr;\t/* current connections number */\n+\tFrangRates history[FRANG_FREQ];\n+} FrangAcc;\n+\n+typedef struct {\n+\tchar *str;\n+\tsize_t len;\t\t/* The pre-computed strlen(@str). */\n+} FrangCtVal;\n+\n+typedef struct {\n+\t/* Limits (zero means unlimited). */\n+\tunsigned int req_rate;\n+\tunsigned int req_burst;\n+\tunsigned int conn_rate;\n+\tunsigned int conn_burst;\n+\tunsigned int conn_max;\n+\t/*\n+\tLimits on time it takes to receive\n+\t a full header or a body chunk.\n+\t*/\n+\tunsigned long clnt_hdr_timeout;\n+\tunsigned long clnt_body_timeout;\n+\t/* Limits for HTTP request contents: uri, headers, body, etc. */\n+\tunsigned int http_uri_len;\n+\tunsigned int http_field_len;\n+\tunsigned int http_body_len;\n+\tunsigned int http_hchunk_cnt;\n+\tunsigned int http_bchunk_cnt;\n+\tbool http_ct_required;\n+\tbool http_host_required;\n+\t/* The bitmask of allowed HTTP Method values. */\n+\tunsigned long http_methods_mask;\n+\t/* The list of allowed Content-Type values. */\n+\tFrangCtVal *http_ct_vals;\n+} FrangCfg;\n+\n+FrangCfg *frang_cfg;\n+const int (*frang_conn_new) (struct sock *);\n+int (*frang_http_req_handler)(void *obj,struct sk_buff *skb, \n+\t\t\t      unsigned int off);\n+\n+struct inet_sock *isk;\n+struct sock mocksock;\n+\n+const char *inet_addr = \"192.168.245.128\";\n+\n+static TfwConnection *\n+test_conn_alloc(void)\n+{\n+\tTfwConnection *conn;\n+\tstatic struct kmem_cache *test_conn_cache = NULL;\n+\tif(!test_conn_cache)\n+\t\ttest_conn_cache = kmem_cache_create(\"tfw_test_conn_cache\",\n+\t\t\t\t        sizeof(TfwConnection), 0, 0, NULL);\n+\tBUG_ON(test_conn_cache == NULL);\n+\tconn = kmem_cache_alloc(test_conn_cache, GFP_ATOMIC);\n+\tBUG_ON(!conn);\n+\ttfw_connection_init(conn);\n+\treturn conn;\n+}\n+\n+static int\n+req_handler(TfwHttpReq  *req)\n+{\n+\tTfwConnection *conn;\n+\t\n+\n+\tconn = test_conn_alloc();\n+\tconn->msg = &req->msg;\n+\tconn->sk = &mocksock;\n+\tisk = (struct inet_sock *) (&mocksock);\n+\tisk->inet_saddr = htonl(in_aton(inet_addr));\n+\tif (!conn->sk->sk_security) {\n+\t\tfrang_conn_new(conn->sk);\n+\t}\n+\n+\treturn frang_http_req_handler((void *) conn,\n+\t\t\t\t\t       req->msg.skb_list.first, HANDLER_OFF);\n+}\n+\n+static TfwHttpReq *\n+get_test_req(const char *req)\n+{\n+\tTfwHttpReq *test_req;\n+\tunsigned char *req_data = (unsigned char *) req;\n+\tint len = strlen(req);\n+\tBUG_ON(len == 0);\n+\ttest_req = test_req_alloc(len);\n+\ttfw_http_parse_req(test_req, req_data, len);\n+\treturn test_req;\n+}\n+\n+TEST(frang, max_conn)\n+{\n+\tint res;\n+\tint i;\n+\tTfwHttpReq *mockreq;\n+\tFrangAcc *ra;\n+\tunsigned long ts;\n+\n+\tmockreq = get_test_req(\"GET / HTTP/1.1\\r\\n\");\n+\tfrang_cfg->conn_max = 5;\n+\tisk = (struct inet_sock *) (&mocksock);\n+\tisk->inet_saddr = htonl(in_aton(inet_addr));\n+\tres = frang_conn_new(&mocksock);\n+\tra = mocksock.sk_security;\n+\tra->conn_curr = 5;\n+\tmocksock.sk_security = ra;\n+\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\tts = jiffies * FRANG_FREQ / HZ;\n+\ti = ts % FRANG_FREQ;\n+\tfrang_cfg->conn_max = 0;\n+\tfrang_cfg->conn_rate = 5;\n+\tra->history[i].conn_new = 5;\n+\tmocksock.sk_security = ra;\n+\tres = req_handler(mockreq);\n+\t/*conn_rate */\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\tfrang_cfg->conn_max = 0;\n+\tfrang_cfg->conn_rate = 0;\n+\tfrang_cfg->conn_burst = 5;\n+\tra->history[i].conn_new = 5;\n+\tmocksock.sk_security = ra;\n+\n+\tres = req_handler (mockreq);\n+\t/*conn_max */\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, uri)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\n+\tmockreq = get_test_req(\"GET /home/index.html HTTP /1.1\\r\\n\");\n+\tfrang_cfg->http_uri_len = 5;\n+\tmockreq->frang_st = 3;\n+\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, ct_check)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\tFrangCtVal ctval[1];\n+\n+\tmockreq = get_test_req(\"POST /foo HTTP/1.1\\r\\nContent-Type:text/html;\");;\n+\tctval[0].str = \"application/html\";\n+\tctval[0].len = strlen(ctval[0].str);\n+\tfrang_cfg->http_ct_vals = ctval;\n+\tmockreq->frang_st = 0;\n+\n+\tres = req_handler(mockreq);\n+\t/*ct_vals*/\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+\n+\tmockreq = get_test_req(\"POST /foo HTTP/1.1\\r\\n\");\n+\tfrang_cfg->http_ct_required = true;\n+\tmockreq->frang_st = 0;\n+\n+\tres = req_handler(mockreq);\n+\t/*ct_required*/\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, req_method)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\n+\tmockreq = get_test_req(\"POST /foo HTTP/1.1\\r\\n\");\n+\tfrang_cfg->http_methods_mask = 2;\n+\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, field_len)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\n+\tmockreq = get_test_req(\"POST /foo HTTP/1.1\\r\\n\");\n+\tfrang_cfg->http_field_len = 3;\n+\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, host)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\n+\tmockreq = get_test_req(\"GET /foo HTTP/1.1\\r\\n\");\n+\tfrang_cfg->http_host_required = true;\n+\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, req_count)\n+{\n+\tint res;\n+\tint i;\n+\tTfwConnection mockconn;\n+\tunsigned long ts;\n+\tTfwHttpReq *mockreq;\n+\tFrangAcc *ra;\n+\n+\tmockreq = get_test_req(\"GET / HTTP/1.1\\r\\n\");\n+\tfrang_cfg->conn_max = 0;\n+\tfrang_cfg->conn_burst = 0;\n+\tfrang_cfg->conn_rate = 0;\n+\tfrang_cfg->req_rate = 5;\n+\tisk = (struct inet_sock *) (&mocksock);\n+\tisk->inet_saddr = htonl(in_aton(inet_addr));\n+\tmockconn.sk = &mocksock;\n+\n+\tres = frang_conn_new(&mocksock);\n+\tra = mockconn.sk->sk_security;\n+\tts = jiffies * FRANG_FREQ / HZ;\n+\ti = ts % FRANG_FREQ;\n+\tra->history[i].req = 5;\n+\tmocksock.sk_security = ra;\n+\tmockreq->frang_st = 0;\n+\tres = req_handler (mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\n+\tfrang_cfg->req_rate = 5;\n+\tfrang_cfg->req_burst = 5;\n+\tra->history[i].req = 5;\n+\tmocksock.sk_security = ra;\n+\tmockreq->frang_st = 0;\n+\tres = req_handler(mockreq);\n+\tEXPECT_EQ(TFW_BLOCK, res);\n+\ttest_req_free(mockreq);\n+}\n+\n+TEST(frang, body_len)\n+{\n+\tint res;\n+\tTfwHttpReq *mockreq;\n+\tTfwStr body;\n+\tTfwStr crlf;\n+\n+\tmockreq = get_test_req(\"POST /foo HTTP/1.1\\r\\n\");\n+\tbody.ptr = \"GET http://natsys-lab.com/foo\";","path":"tempesta_fw/t/unit/test_frang.c","position":309,"original_position":309,"commit_id":"77b06d6dfeb64254a4fbc77b8f1c332a18923b6a","original_commit_id":"77b06d6dfeb64254a4fbc77b8f1c332a18923b6a","user":{"login":"avbelov23","id":4706398,"avatar_url":"https://avatars.githubusercontent.com/u/4706398?v=3","gravatar_id":"","url":"https://api.github.com/users/avbelov23","html_url":"https://github.com/avbelov23","followers_url":"https://api.github.com/users/avbelov23/followers","following_url":"https://api.github.com/users/avbelov23/following{/other_user}","gists_url":"https://api.github.com/users/avbelov23/gists{/gist_id}","starred_url":"https://api.github.com/users/avbelov23/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avbelov23/subscriptions","organizations_url":"https://api.github.com/users/avbelov23/orgs","repos_url":"https://api.github.com/users/avbelov23/repos","events_url":"https://api.github.com/users/avbelov23/events{/privacy}","received_events_url":"https://api.github.com/users/avbelov23/received_events","type":"User","site_admin":false},"body":"https://github.com/natsys/tempesta/blob/master/tempesta_fw/str.h#L103","created_at":"2015-10-26T20:20:10Z","updated_at":"2015-10-26T20:20:10Z","html_url":"https://github.com/natsys/tempesta/pull/319#discussion_r43046910","pull_request_url":"https://api.github.com/repos/natsys/tempesta/pulls/319","_links":{"self":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/comments/43046910"},"html":{"href":"https://github.com/natsys/tempesta/pull/319#discussion_r43046910"},"pull_request":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/319"}}},"pull_request":{"url":"https://api.github.com/repos/natsys/tempesta/pulls/319","id":48184683,"html_url":"https://github.com/natsys/tempesta/pull/319","diff_url":"https://github.com/natsys/tempesta/pull/319.diff","patch_url":"https://github.com/natsys/tempesta/pull/319.patch","issue_url":"https://api.github.com/repos/natsys/tempesta/issues/319","number":319,"state":"open","locked":false,"title":"147 05","user":{"login":"sergsever","id":10198669,"avatar_url":"https://avatars.githubusercontent.com/u/10198669?v=3","gravatar_id":"","url":"https://api.github.com/users/sergsever","html_url":"https://github.com/sergsever","followers_url":"https://api.github.com/users/sergsever/followers","following_url":"https://api.github.com/users/sergsever/following{/other_user}","gists_url":"https://api.github.com/users/sergsever/gists{/gist_id}","starred_url":"https://api.github.com/users/sergsever/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sergsever/subscriptions","organizations_url":"https://api.github.com/users/sergsever/orgs","repos_url":"https://api.github.com/users/sergsever/repos","events_url":"https://api.github.com/users/sergsever/events{/privacy}","received_events_url":"https://api.github.com/users/sergsever/received_events","type":"User","site_admin":false},"body":"#147 ","created_at":"2015-10-20T10:55:32Z","updated_at":"2015-10-26T20:20:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d88b7e6ab2aab1263bc4663d363ddaa29d459f22","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/natsys/tempesta/pulls/319/commits","review_comments_url":"https://api.github.com/repos/natsys/tempesta/pulls/319/comments","review_comment_url":"https://api.github.com/repos/natsys/tempesta/pulls/comments{/number}","comments_url":"https://api.github.com/repos/natsys/tempesta/issues/319/comments","statuses_url":"https://api.github.com/repos/natsys/tempesta/statuses/77b06d6dfeb64254a4fbc77b8f1c332a18923b6a","head":{"label":"natsys:ls_147_05","ref":"ls_147_05","sha":"77b06d6dfeb64254a4fbc77b8f1c332a18923b6a","user":{"login":"natsys","id":8489938,"avatar_url":"https://avatars.githubusercontent.com/u/8489938?v=3","gravatar_id":"","url":"https://api.github.com/users/natsys","html_url":"https://github.com/natsys","followers_url":"https://api.github.com/users/natsys/followers","following_url":"https://api.github.com/users/natsys/following{/other_user}","gists_url":"https://api.github.com/users/natsys/gists{/gist_id}","starred_url":"https://api.github.com/users/natsys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natsys/subscriptions","organizations_url":"https://api.github.com/users/natsys/orgs","repos_url":"https://api.github.com/users/natsys/repos","events_url":"https://api.github.com/users/natsys/events{/privacy}","received_events_url":"https://api.github.com/users/natsys/received_events","type":"Organization","site_admin":false},"repo":{"id":23121600,"name":"tempesta","full_name":"natsys/tempesta","owner":{"login":"natsys","id":8489938,"avatar_url":"https://avatars.githubusercontent.com/u/8489938?v=3","gravatar_id":"","url":"https://api.github.com/users/natsys","html_url":"https://github.com/natsys","followers_url":"https://api.github.com/users/natsys/followers","following_url":"https://api.github.com/users/natsys/following{/other_user}","gists_url":"https://api.github.com/users/natsys/gists{/gist_id}","starred_url":"https://api.github.com/users/natsys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natsys/subscriptions","organizations_url":"https://api.github.com/users/natsys/orgs","repos_url":"https://api.github.com/users/natsys/repos","events_url":"https://api.github.com/users/natsys/events{/privacy}","received_events_url":"https://api.github.com/users/natsys/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/natsys/tempesta","description":"High performance HTTP accelerator and firewall for WAF and DDoS prevention","fork":false,"url":"https://api.github.com/repos/natsys/tempesta","forks_url":"https://api.github.com/repos/natsys/tempesta/forks","keys_url":"https://api.github.com/repos/natsys/tempesta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/natsys/tempesta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/natsys/tempesta/teams","hooks_url":"https://api.github.com/repos/natsys/tempesta/hooks","issue_events_url":"https://api.github.com/repos/natsys/tempesta/issues/events{/number}","events_url":"https://api.github.com/repos/natsys/tempesta/events","assignees_url":"https://api.github.com/repos/natsys/tempesta/assignees{/user}","branches_url":"https://api.github.com/repos/natsys/tempesta/branches{/branch}","tags_url":"https://api.github.com/repos/natsys/tempesta/tags","blobs_url":"https://api.github.com/repos/natsys/tempesta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/natsys/tempesta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/natsys/tempesta/git/refs{/sha}","trees_url":"https://api.github.com/repos/natsys/tempesta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/natsys/tempesta/statuses/{sha}","languages_url":"https://api.github.com/repos/natsys/tempesta/languages","stargazers_url":"https://api.github.com/repos/natsys/tempesta/stargazers","contributors_url":"https://api.github.com/repos/natsys/tempesta/contributors","subscribers_url":"https://api.github.com/repos/natsys/tempesta/subscribers","subscription_url":"https://api.github.com/repos/natsys/tempesta/subscription","commits_url":"https://api.github.com/repos/natsys/tempesta/commits{/sha}","git_commits_url":"https://api.github.com/repos/natsys/tempesta/git/commits{/sha}","comments_url":"https://api.github.com/repos/natsys/tempesta/comments{/number}","issue_comment_url":"https://api.github.com/repos/natsys/tempesta/issues/comments{/number}","contents_url":"https://api.github.com/repos/natsys/tempesta/contents/{+path}","compare_url":"https://api.github.com/repos/natsys/tempesta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/natsys/tempesta/merges","archive_url":"https://api.github.com/repos/natsys/tempesta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/natsys/tempesta/downloads","issues_url":"https://api.github.com/repos/natsys/tempesta/issues{/number}","pulls_url":"https://api.github.com/repos/natsys/tempesta/pulls{/number}","milestones_url":"https://api.github.com/repos/natsys/tempesta/milestones{/number}","notifications_url":"https://api.github.com/repos/natsys/tempesta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/natsys/tempesta/labels{/name}","releases_url":"https://api.github.com/repos/natsys/tempesta/releases{/id}","created_at":"2014-08-19T18:44:05Z","updated_at":"2015-10-09T03:36:18Z","pushed_at":"2015-10-26T19:58:04Z","git_url":"git://github.com/natsys/tempesta.git","ssh_url":"git@github.com:natsys/tempesta.git","clone_url":"https://github.com/natsys/tempesta.git","svn_url":"https://github.com/natsys/tempesta","homepage":"","size":4661,"stargazers_count":74,"watchers_count":74,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":16,"mirror_url":null,"open_issues_count":63,"forks":16,"open_issues":63,"watchers":74,"default_branch":"master"}},"base":{"label":"natsys:master","ref":"master","sha":"42c58718cc1a249d04e89ff73f6f9e52e620ebf6","user":{"login":"natsys","id":8489938,"avatar_url":"https://avatars.githubusercontent.com/u/8489938?v=3","gravatar_id":"","url":"https://api.github.com/users/natsys","html_url":"https://github.com/natsys","followers_url":"https://api.github.com/users/natsys/followers","following_url":"https://api.github.com/users/natsys/following{/other_user}","gists_url":"https://api.github.com/users/natsys/gists{/gist_id}","starred_url":"https://api.github.com/users/natsys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natsys/subscriptions","organizations_url":"https://api.github.com/users/natsys/orgs","repos_url":"https://api.github.com/users/natsys/repos","events_url":"https://api.github.com/users/natsys/events{/privacy}","received_events_url":"https://api.github.com/users/natsys/received_events","type":"Organization","site_admin":false},"repo":{"id":23121600,"name":"tempesta","full_name":"natsys/tempesta","owner":{"login":"natsys","id":8489938,"avatar_url":"https://avatars.githubusercontent.com/u/8489938?v=3","gravatar_id":"","url":"https://api.github.com/users/natsys","html_url":"https://github.com/natsys","followers_url":"https://api.github.com/users/natsys/followers","following_url":"https://api.github.com/users/natsys/following{/other_user}","gists_url":"https://api.github.com/users/natsys/gists{/gist_id}","starred_url":"https://api.github.com/users/natsys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natsys/subscriptions","organizations_url":"https://api.github.com/users/natsys/orgs","repos_url":"https://api.github.com/users/natsys/repos","events_url":"https://api.github.com/users/natsys/events{/privacy}","received_events_url":"https://api.github.com/users/natsys/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/natsys/tempesta","description":"High performance HTTP accelerator and firewall for WAF and DDoS prevention","fork":false,"url":"https://api.github.com/repos/natsys/tempesta","forks_url":"https://api.github.com/repos/natsys/tempesta/forks","keys_url":"https://api.github.com/repos/natsys/tempesta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/natsys/tempesta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/natsys/tempesta/teams","hooks_url":"https://api.github.com/repos/natsys/tempesta/hooks","issue_events_url":"https://api.github.com/repos/natsys/tempesta/issues/events{/number}","events_url":"https://api.github.com/repos/natsys/tempesta/events","assignees_url":"https://api.github.com/repos/natsys/tempesta/assignees{/user}","branches_url":"https://api.github.com/repos/natsys/tempesta/branches{/branch}","tags_url":"https://api.github.com/repos/natsys/tempesta/tags","blobs_url":"https://api.github.com/repos/natsys/tempesta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/natsys/tempesta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/natsys/tempesta/git/refs{/sha}","trees_url":"https://api.github.com/repos/natsys/tempesta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/natsys/tempesta/statuses/{sha}","languages_url":"https://api.github.com/repos/natsys/tempesta/languages","stargazers_url":"https://api.github.com/repos/natsys/tempesta/stargazers","contributors_url":"https://api.github.com/repos/natsys/tempesta/contributors","subscribers_url":"https://api.github.com/repos/natsys/tempesta/subscribers","subscription_url":"https://api.github.com/repos/natsys/tempesta/subscription","commits_url":"https://api.github.com/repos/natsys/tempesta/commits{/sha}","git_commits_url":"https://api.github.com/repos/natsys/tempesta/git/commits{/sha}","comments_url":"https://api.github.com/repos/natsys/tempesta/comments{/number}","issue_comment_url":"https://api.github.com/repos/natsys/tempesta/issues/comments{/number}","contents_url":"https://api.github.com/repos/natsys/tempesta/contents/{+path}","compare_url":"https://api.github.com/repos/natsys/tempesta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/natsys/tempesta/merges","archive_url":"https://api.github.com/repos/natsys/tempesta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/natsys/tempesta/downloads","issues_url":"https://api.github.com/repos/natsys/tempesta/issues{/number}","pulls_url":"https://api.github.com/repos/natsys/tempesta/pulls{/number}","milestones_url":"https://api.github.com/repos/natsys/tempesta/milestones{/number}","notifications_url":"https://api.github.com/repos/natsys/tempesta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/natsys/tempesta/labels{/name}","releases_url":"https://api.github.com/repos/natsys/tempesta/releases{/id}","created_at":"2014-08-19T18:44:05Z","updated_at":"2015-10-09T03:36:18Z","pushed_at":"2015-10-26T19:58:04Z","git_url":"git://github.com/natsys/tempesta.git","ssh_url":"git@github.com:natsys/tempesta.git","clone_url":"https://github.com/natsys/tempesta.git","svn_url":"https://github.com/natsys/tempesta","homepage":"","size":4661,"stargazers_count":74,"watchers_count":74,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":16,"mirror_url":null,"open_issues_count":63,"forks":16,"open_issues":63,"watchers":74,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/319"},"html":{"href":"https://github.com/natsys/tempesta/pull/319"},"issue":{"href":"https://api.github.com/repos/natsys/tempesta/issues/319"},"comments":{"href":"https://api.github.com/repos/natsys/tempesta/issues/319/comments"},"review_comments":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/319/comments"},"review_comment":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/natsys/tempesta/pulls/319/commits"},"statuses":{"href":"https://api.github.com/repos/natsys/tempesta/statuses/77b06d6dfeb64254a4fbc77b8f1c332a18923b6a"}}}}