summaryrefslogtreecommitdiff
path: root/ot_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_http.c')
-rw-r--r--ot_http.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/ot_http.c b/ot_http.c
index dcf634f..46ca5a9 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -44,7 +44,7 @@ ssize_t g_stats_path_len;
44 44
45enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; 45enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 };
46 46
47static void http_senddata(const int64 sock, struct ot_workstruct *ws) { 47static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
48 struct http_data *cookie = io_getcookie(sock); 48 struct http_data *cookie = io_getcookie(sock);
49 ssize_t written_size; 49 ssize_t written_size;
50 50
@@ -124,7 +124,7 @@ static void http_senddata(const int64 sock, struct ot_workstruct *ws) {
124#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) 124#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP)
125#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) 125#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404)
126#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) 126#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500)
127ssize_t http_issue_error(const int64 sock, struct ot_workstruct *ws, int code) { 127ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) {
128 char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", 128 char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required",
129 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; 129 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"};
130 char *title = error_code[code]; 130 char *title = error_code[code];
@@ -144,7 +144,7 @@ ssize_t http_issue_error(const int64 sock, struct ot_workstruct *ws, int code) {
144 return ws->reply_size = -2; 144 return ws->reply_size = -2;
145} 145}
146 146
147ssize_t http_sendiovecdata(const int64 sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) { 147ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) {
148 struct http_data *cookie = io_getcookie(sock); 148 struct http_data *cookie = io_getcookie(sock);
149 io_batch *current; 149 io_batch *current;
150 char *header; 150 char *header;
@@ -158,6 +158,13 @@ ssize_t http_sendiovecdata(const int64 sock, struct ot_workstruct *ws, size_t io
158 HTTPERROR_500; 158 HTTPERROR_500;
159 } 159 }
160 160
161 /* Descriptor numbers get recycled, so a result can only belong to this
162 connection if this connection is in fact waiting for one. */
163 if (!(cookie->flag & (STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER))) {
164 iovec_free(&iovec_entries, &iovector);
165 return 0;
166 }
167
161 /* If this socket collected request in a buffer, free it now */ 168 /* If this socket collected request in a buffer, free it now */
162 buf_reset(&cookie->request); 169 buf_reset(&cookie->request);
163 170
@@ -236,7 +243,7 @@ ssize_t http_sendiovecdata(const int64 sock, struct ot_workstruct *ws, size_t io
236 return 0; 243 return 0;
237} 244}
238 245
239static ssize_t http_handle_stats(const int64 sock, struct ot_workstruct *ws, char *read_ptr) { 246static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) {
240 static const ot_keywords keywords_main[] = {{"mode", 1}, {"format", 2}, {"info_hash", 3}, {NULL, -3}}; 247 static const ot_keywords keywords_main[] = {{"mode", 1}, {"format", 2}, {"info_hash", 3}, {NULL, -3}};
241 static const ot_keywords keywords_mode[] = {{"peer", TASK_STATS_PEERS}, 248 static const ot_keywords keywords_mode[] = {{"peer", TASK_STATS_PEERS},
242 {"conn", TASK_STATS_CONNS}, 249 {"conn", TASK_STATS_CONNS},
@@ -267,12 +274,16 @@ static ssize_t http_handle_stats(const int64 sock, struct ot_workstruct *ws, cha
267 {"url", TASK_FULLSCRAPE_TPB_URLENCODED}, {"txt", TASK_FULLSCRAPE_TPB_ASCII}, 274 {"url", TASK_FULLSCRAPE_TPB_URLENCODED}, {"txt", TASK_FULLSCRAPE_TPB_ASCII},
268 {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; 275 {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}};
269 276
270 int mode = TASK_STATS_PEERS, scanon = 1, format = 0;
271
272#ifdef WANT_RESTRICT_STATS
273 struct http_data *cookie = io_getcookie(sock); 277 struct http_data *cookie = io_getcookie(sock);
278 int mode = TASK_STATS_PEERS, scanon = 1, format = 0;
274 279
275 if (!cookie || !accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_STAT)) 280 /* A socket without one is a dead socket, which is what http_sendiovecdata
281 already answers 500 to. */
282 if (!cookie)
283 HTTPERROR_500;
284
285#ifdef WANT_RESTRICT_STATS
286 if (!accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_STAT))
276 HTTPERROR_403_IP; 287 HTTPERROR_403_IP;
277#endif 288#endif
278 289
@@ -306,8 +317,7 @@ static ssize_t http_handle_stats(const int64 sock, struct ot_workstruct *ws, cha
306 } 317 }
307 318
308 if (mode == TASK_STATS_TPB) { 319 if (mode == TASK_STATS_TPB) {
309 struct http_data *cookie = io_getcookie(sock); 320 tai6464 t;
310 tai6464 t;
311#ifdef WANT_COMPRESSION_GZIP 321#ifdef WANT_COMPRESSION_GZIP
312 ws->request[ws->request_size - 1] = 0; 322 ws->request[ws->request_size - 1] = 0;
313#ifndef WANT_COMPRESSION_GZIP_ALWAYS 323#ifndef WANT_COMPRESSION_GZIP_ALWAYS
@@ -334,6 +344,9 @@ static ssize_t http_handle_stats(const int64 sock, struct ot_workstruct *ws, cha
334 /* default format for now */ 344 /* default format for now */
335 if ((mode & TASK_CLASS_MASK) == TASK_STATS) { 345 if ((mode & TASK_CLASS_MASK) == TASK_STATS) {
336 tai6464 t; 346 tai6464 t;
347
348 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
349
337 /* Complex stats also include expensive memory debugging tools */ 350 /* Complex stats also include expensive memory debugging tools */
338 taia_uint(&t, 0); 351 taia_uint(&t, 0);
339 io_timeout(sock, t); 352 io_timeout(sock, t);
@@ -355,7 +368,7 @@ typedef struct {
355#endif 368#endif
356 369
357#ifdef WANT_FULLSCRAPE 370#ifdef WANT_FULLSCRAPE
358static ssize_t http_handle_fullscrape(const int64 sock, struct ot_workstruct *ws) { 371static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) {
359 struct http_data *cookie = io_getcookie(sock); 372 struct http_data *cookie = io_getcookie(sock);
360 int format = 0; 373 int format = 0;
361 tai6464 t; 374 tai6464 t;
@@ -425,7 +438,7 @@ static ssize_t http_handle_fullscrape(const int64 sock, struct ot_workstruct *ws
425} 438}
426#endif 439#endif
427 440
428static ssize_t http_handle_scrape(const int64 sock, struct ot_workstruct *ws, char *read_ptr) { 441static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) {
429 static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; 442 static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}};
430 443
431 ot_hash *multiscrape_buf = (ot_hash *)ws->request; 444 ot_hash *multiscrape_buf = (ot_hash *)ws->request;
@@ -504,7 +517,7 @@ static ot_keywords keywords_announce[] = {{"port", 1}, {"left", 2}, {"event",
504#endif 517#endif
505 {"peer_id", 9}, {NULL, -3}}; 518 {"peer_id", 9}, {NULL, -3}};
506static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}}; 519static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}};
507static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct *ws, char *read_ptr) { 520static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) {
508 size_t numwant; 521 size_t numwant;
509 int tmp, scanon; 522 int tmp, scanon;
510 unsigned short port = 0; 523 unsigned short port = 0;
@@ -682,7 +695,7 @@ static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct *
682 return ws->reply_size; 695 return ws->reply_size;
683} 696}
684 697
685ssize_t http_handle_request(const int64 sock, struct ot_workstruct *ws) { 698ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) {
686 ssize_t reply_off, len; 699 ssize_t reply_off, len;
687 char *read_ptr = ws->request, *write_ptr; 700 char *read_ptr = ws->request, *write_ptr;
688 701