summaryrefslogtreecommitdiff
path: root/ot_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_http.c')
-rw-r--r--ot_http.c142
1 files changed, 87 insertions, 55 deletions
diff --git a/ot_http.c b/ot_http.c
index 6bf343c..36819c7 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -14,9 +14,6 @@
14#include <sys/types.h> 14#include <sys/types.h>
15#include <unistd.h> 15#include <unistd.h>
16 16
17/* Libowfat */
18#include "io.h"
19
20/* Opentracker */ 17/* Opentracker */
21#include "ot_accesslist.h" 18#include "ot_accesslist.h"
22#include "ot_fullscrape.h" 19#include "ot_fullscrape.h"
@@ -25,9 +22,11 @@
25#include "ot_ip.h" 22#include "ot_ip.h"
26#include "ot_mutex.h" 23#include "ot_mutex.h"
27#include "ot_scan.h" 24#include "ot_scan.h"
25#include "ot_event.h"
28#include "ot_fdstate.h" 26#include "ot_fdstate.h"
27#include "ot_fmt.h"
29#include "ot_stats.h" 28#include "ot_stats.h"
30#include "scan_urlencoded_query.h" 29#include "ot_urlencoded.h"
31#include "trackerlogic.h" 30#include "trackerlogic.h"
32 31
33#define OT_MAXMULTISCRAPE_COUNT 64 32#define OT_MAXMULTISCRAPE_COUNT 64
@@ -43,7 +42,7 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
43 ssize_t written_size; 42 ssize_t written_size;
44 43
45 if (!cookie) { 44 if (!cookie) {
46 io_close(sock); 45 event_del((int)sock), close((int)sock);
47 return; 46 return;
48 } 47 }
49 48
@@ -67,7 +66,7 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
67 if ((written_size < 0) || ((written_size == ws->reply_size) && !ws->keep_alive)) { 66 if ((written_size < 0) || ((written_size == ws->reply_size) && !ws->keep_alive)) {
68 buf_reset(&cookie->request); 67 buf_reset(&cookie->request);
69 free(cookie); 68 free(cookie);
70 io_close(sock); 69 event_del((int)sock), close((int)sock);
71 return; 70 return;
72 } 71 }
73 72
@@ -77,7 +76,7 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
77 if (!(outbuf = malloc(ws->reply_size - written_size))) { 76 if (!(outbuf = malloc(ws->reply_size - written_size))) {
78 buf_reset(&cookie->request); 77 buf_reset(&cookie->request);
79 free(cookie); 78 free(cookie);
80 io_close(sock); 79 event_del((int)sock), close((int)sock);
81 return; 80 return;
82 } 81 }
83 82
@@ -88,7 +87,7 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
88 free(outbuf); 87 free(outbuf);
89 buf_reset(&cookie->request); 88 buf_reset(&cookie->request);
90 free(cookie); 89 free(cookie);
91 io_close(sock); 90 event_del((int)sock), close((int)sock);
92 return; 91 return;
93 } 92 }
94 } 93 }
@@ -98,9 +97,9 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
98 /* writeable short data sockets just have a tcp timeout */ 97 /* writeable short data sockets just have a tcp timeout */
99 if (!ws->keep_alive) { 98 if (!ws->keep_alive) {
100 fdstate_set_expiry(sock, 0); 99 fdstate_set_expiry(sock, 0);
101 io_dontwantread(sock); 100 http_interest_drop(sock, cookie, EVENT_IN);
102 } 101 }
103 io_wantwrite(sock); 102 http_interest_add(sock, cookie, EVENT_OUT);
104 } 103 }
105} 104}
106 105
@@ -113,6 +112,21 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
113#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) 112#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP)
114#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) 113#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404)
115#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) 114#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500)
115static void http_interest(const int64_t sock, struct http_data *cookie, int what) {
116 if (cookie->interest == what)
117 return;
118 cookie->interest = what;
119 event_modify((int)sock, what, fdstate_generation((int)sock));
120}
121
122void http_interest_add(const int64_t sock, struct http_data *cookie, int what) {
123 http_interest(sock, cookie, cookie->interest | what);
124}
125
126void http_interest_drop(const int64_t sock, struct http_data *cookie, int what) {
127 http_interest(sock, cookie, cookie->interest & ~what);
128}
129
116ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) { 130ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) {
117 const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", 131 const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required",
118 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; 132 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"};
@@ -157,7 +171,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t
157 171
158 /* If we came here, wait for the answer is over */ 172 /* If we came here, wait for the answer is over */
159 if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) { 173 if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) {
160 io_dontwantread(sock); 174 http_interest_drop(sock, cookie, EVENT_IN);
161 cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; 175 cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK;
162 } 176 }
163 177
@@ -208,7 +222,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t
208 } 222 }
209 223
210 fdstate_set_expiry(sock, g_now_seconds + OT_CLIENT_TIMEOUT_SEND); 224 fdstate_set_expiry(sock, g_now_seconds + OT_CLIENT_TIMEOUT_SEND);
211 io_wantwrite(sock); 225 http_interest_add(sock, cookie, EVENT_OUT);
212 return 0; 226 return 0;
213} 227}
214 228
@@ -244,6 +258,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
244 {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; 258 {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}};
245 259
246 struct http_data *cookie = fdstate_cookie(sock); 260 struct http_data *cookie = fdstate_cookie(sock);
261 char *reply;
247 int mode = TASK_STATS_PEERS, scanon = 1, format = 0; 262 int mode = TASK_STATS_PEERS, scanon = 1, format = 0;
248 263
249 /* A socket without one is a dead socket, which is what http_sendiovecdata 264 /* A socket without one is a dead socket, which is what http_sendiovecdata
@@ -257,21 +272,21 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
257#endif 272#endif
258 273
259 while (scanon) { 274 while (scanon) {
260 switch (scan_find_keywords(keywords_main, &read_ptr, SCAN_SEARCHPATH_PARAM)) { 275 switch (urlencoded_match_keyword(keywords_main, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
261 case -2: 276 case -2:
262 scanon = 0; 277 scanon = 0;
263 break; /* TERMINATOR */ 278 break; /* TERMINATOR */
264 case -1: 279 case -1:
265 HTTPERROR_400_PARAM; /* PARSE ERROR */ 280 HTTPERROR_400_PARAM; /* PARSE ERROR */
266 case -3: 281 case -3:
267 scan_urlencoded_skipvalue(&read_ptr); 282 urlencoded_skip_value(&read_ptr);
268 break; 283 break;
269 case 1: /* matched "mode" */ 284 case 1: /* matched "mode" */
270 if ((mode = scan_find_keywords(keywords_mode, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0) 285 if ((mode = urlencoded_match_keyword(keywords_mode, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
271 HTTPERROR_400_PARAM; 286 HTTPERROR_400_PARAM;
272 break; 287 break;
273 case 2: /* matched "format" */ 288 case 2: /* matched "format" */
274 if ((format = scan_find_keywords(keywords_format, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0) 289 if ((format = urlencoded_match_keyword(keywords_format, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
275 HTTPERROR_400_PARAM; 290 HTTPERROR_400_PARAM;
276 break; 291 break;
277 case 3: 292 case 3:
@@ -303,7 +318,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
303 /* Clients waiting for us should not easily timeout */ 318 /* Clients waiting for us should not easily timeout */
304 fdstate_set_expiry(sock, 0); 319 fdstate_set_expiry(sock, 0);
305 fullscrape_deliver(sock, format); 320 fullscrape_deliver(sock, format);
306 io_dontwantread(sock); 321 http_interest_drop(sock, cookie, EVENT_IN);
307 return ws->reply_size = -2; 322 return ws->reply_size = -2;
308 } 323 }
309#endif 324#endif
@@ -320,7 +335,9 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
320 } 335 }
321 336
322 /* Simple stats can be answerred immediately */ 337 /* Simple stats can be answerred immediately */
323 return ws->reply_size = return_stats_for_tracker(ws->reply, mode, 0); 338 reply = ws->reply;
339 return_stats_for_tracker(&reply, ws->outbuf + G_OUTBUF_SIZE, mode, 0);
340 return ws->reply_size = reply - ws->reply;
324} 341}
325 342
326#ifdef WANT_MODEST_FULLSCRAPES 343#ifdef WANT_MODEST_FULLSCRAPES
@@ -396,7 +413,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *
396 /* Clients waiting for us should not easily timeout */ 413 /* Clients waiting for us should not easily timeout */
397 fdstate_set_expiry(sock, 0); 414 fdstate_set_expiry(sock, 0);
398 fullscrape_deliver(sock, format); 415 fullscrape_deliver(sock, format);
399 io_dontwantread(sock); 416 http_interest_drop(sock, cookie, EVENT_IN);
400 return ws->reply_size = -2; 417 return ws->reply_size = -2;
401} 418}
402#endif 419#endif
@@ -404,9 +421,10 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *
404static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { 421static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) {
405 static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; 422 static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}};
406 423
407 ot_hash *multiscrape_buf = (ot_hash *)ws->request; 424 ot_hash *multiscrape_buf = (ot_hash *)ws->request;
408 int scanon = 1; 425 char *reply = ws->reply;
409 size_t numwant = 0; 426 int scanon = 1;
427 size_t numwant = 0;
410 428
411 /* This is to hack around stupid clients that send "scrape ?info_hash" */ 429 /* This is to hack around stupid clients that send "scrape ?info_hash" */
412 if (read_ptr[-1] != '?') { 430 if (read_ptr[-1] != '?') {
@@ -418,18 +436,18 @@ static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws,
418 } 436 }
419 437
420 while (scanon) { 438 while (scanon) {
421 switch (scan_find_keywords(keywords_scrape, &read_ptr, SCAN_SEARCHPATH_PARAM)) { 439 switch (urlencoded_match_keyword(keywords_scrape, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
422 case -2: 440 case -2:
423 scanon = 0; 441 scanon = 0;
424 break; /* TERMINATOR */ 442 break; /* TERMINATOR */
425 default: 443 default:
426 HTTPERROR_400_PARAM; /* PARSE ERROR */ 444 HTTPERROR_400_PARAM; /* PARSE ERROR */
427 case -3: 445 case -3:
428 scan_urlencoded_skipvalue(&read_ptr); 446 urlencoded_skip_value(&read_ptr);
429 break; 447 break;
430 case 1: /* matched "info_hash" */ 448 case 1: /* matched "info_hash" */
431 /* ignore this, when we have less than 20 bytes */ 449 /* ignore this, when we have less than 20 bytes */
432 if (scan_urlencoded_query(&read_ptr, (char *)(multiscrape_buf + numwant++), SCAN_SEARCHPATH_VALUE) != (ssize_t)sizeof(ot_hash)) 450 if (urlencoded_parse(&read_ptr, (char *)(multiscrape_buf + numwant++), SCAN_SEARCHPATH_VALUE) != (ssize_t)sizeof(ot_hash))
433 HTTPERROR_400_PARAM; 451 HTTPERROR_400_PARAM;
434 break; 452 break;
435 } 453 }
@@ -444,7 +462,8 @@ static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws,
444 numwant = OT_MAXMULTISCRAPE_COUNT; 462 numwant = OT_MAXMULTISCRAPE_COUNT;
445 463
446 /* Enough for http header + whole scrape string */ 464 /* Enough for http header + whole scrape string */
447 ws->reply_size = return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, ws->reply); 465 return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, &reply, ws->outbuf + G_OUTBUF_SIZE);
466 ws->reply_size = reply - ws->reply;
448 stats_issue_event(EVENT_SCRAPE, FLAG_TCP, ws->reply_size); 467 stats_issue_event(EVENT_SCRAPE, FLAG_TCP, ws->reply_size);
449 return ws->reply_size; 468 return ws->reply_size;
450} 469}
@@ -480,9 +499,20 @@ static ot_keywords keywords_announce[] = {{"port", 1}, {"left", 2}, {"event",
480#endif 499#endif
481 {"peer_id", 9}, {NULL, -3}}; 500 {"peer_id", 9}, {NULL, -3}};
482static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}}; 501static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}};
502
503/* For the replies that are one fixed string and nothing else, where the only
504 thing the caller wants back is how long it turned out */
505static ssize_t reply_literal(struct ot_workstruct *ws, const char *text) {
506 char *reply = ws->reply;
507
508 fmt_bytes(&reply, ws->outbuf + G_OUTBUF_SIZE, text, strlen(text));
509 return reply - ws->reply;
510}
511
483static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { 512static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) {
484 size_t numwant; 513 size_t numwant;
485 int tmp, scanon; 514 int64_t tmp;
515 int scanon;
486 unsigned short port = 0; 516 unsigned short port = 0;
487 char *write_ptr; 517 char *write_ptr;
488 ssize_t len; 518 ssize_t len;
@@ -501,7 +531,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
501 if (accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_PROXY)) { 531 if (accesslist_is_blessed(cookie->ip, OT_PERMISSION_MAY_PROXY)) {
502 ot_ip6 proxied_ip; 532 ot_ip6 proxied_ip;
503 char *fwd = http_header(ws->request, ws->header_size, "x-forwarded-for"); 533 char *fwd = http_header(ws->request, ws->header_size, "x-forwarded-for");
504 if (fwd && ip_scan(fwd, proxied_ip)) { 534 if (fwd && ip_parse(fwd, proxied_ip)) {
505 OT_SETIP(ws->peer, proxied_ip); 535 OT_SETIP(ws->peer, proxied_ip);
506 } else 536 } else
507 OT_SETIP(ws->peer, cookie->ip); 537 OT_SETIP(ws->peer, cookie->ip);
@@ -518,32 +548,32 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
518 scanon = 1; 548 scanon = 1;
519 549
520 while (scanon) { 550 while (scanon) {
521 switch (scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM)) { 551 switch (urlencoded_match_keyword(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
522 case -2: 552 case -2:
523 scanon = 0; 553 scanon = 0;
524 break; /* TERMINATOR */ 554 break; /* TERMINATOR */
525 case -1: 555 case -1:
526 HTTPERROR_400_PARAM; /* PARSE ERROR */ 556 HTTPERROR_400_PARAM; /* PARSE ERROR */
527 case -3: 557 case -3:
528 scan_urlencoded_skipvalue(&read_ptr); 558 urlencoded_skip_value(&read_ptr);
529 break; 559 break;
530 case 1: /* matched "port" */ 560 case 1: /* matched "port" */
531 len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE); 561 len = urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
532 if ((len <= 0) || scan_fixed_int(write_ptr, len, &tmp) || (tmp > 0xffff)) 562 if ((len <= 0) || scan_int(write_ptr, len, &tmp) || (tmp > 0xffff))
533 HTTPERROR_400_PARAM; 563 HTTPERROR_400_PARAM;
534 port = htons(tmp); 564 port = htons((uint16_t)tmp);
535 OT_SETPORT(&ws->peer, &port); 565 OT_SETPORT(&ws->peer, &port);
536 break; 566 break;
537 case 2: /* matched "left" */ 567 case 2: /* matched "left" */
538 if ((len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0) 568 if ((len = urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
539 HTTPERROR_400_PARAM; 569 HTTPERROR_400_PARAM;
540 if (scan_fixed_int(write_ptr, len, &tmp)) 570 if (scan_int(write_ptr, len, &tmp))
541 tmp = 0; 571 tmp = 0;
542 if (!tmp) 572 if (!tmp)
543 OT_PEERFLAG(&ws->peer) |= PEER_FLAG_SEEDING; 573 OT_PEERFLAG(&ws->peer) |= PEER_FLAG_SEEDING;
544 break; 574 break;
545 case 3: /* matched "event" */ 575 case 3: /* matched "event" */
546 switch (scan_find_keywords(keywords_announce_event, &read_ptr, SCAN_SEARCHPATH_VALUE)) { 576 switch (urlencoded_match_keyword(keywords_announce_event, &read_ptr, SCAN_SEARCHPATH_VALUE)) {
547 case -1: 577 case -1:
548 HTTPERROR_400_PARAM; 578 HTTPERROR_400_PARAM;
549 case 1: /* matched "completed" */ 579 case 1: /* matched "completed" */
@@ -557,18 +587,18 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
557 } 587 }
558 break; 588 break;
559 case 4: /* matched "numwant" */ 589 case 4: /* matched "numwant" */
560 len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE); 590 len = urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
561 if ((len <= 0) || scan_fixed_int(write_ptr, len, &tmp)) 591 if ((len <= 0) || scan_int(write_ptr, len, &tmp))
562 HTTPERROR_400_PARAM; 592 HTTPERROR_400_PARAM;
563 if (tmp < 0) 593 if (tmp < 0)
564 tmp = 50; 594 tmp = 50;
565 if (tmp > 200) 595 if (tmp > 200)
566 tmp = 200; 596 tmp = 200;
567 numwant = tmp; 597 numwant = (size_t)tmp;
568 break; 598 break;
569 case 5: /* matched "compact" */ 599 case 5: /* matched "compact" */
570 len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE); 600 len = urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
571 if ((len <= 0) || scan_fixed_int(write_ptr, len, &tmp)) 601 if ((len <= 0) || scan_int(write_ptr, len, &tmp))
572 HTTPERROR_400_PARAM; 602 HTTPERROR_400_PARAM;
573 if (!tmp) 603 if (!tmp)
574 HTTPERROR_400_COMPACT; 604 HTTPERROR_400_COMPACT;
@@ -577,7 +607,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
577 if (ws->hash) 607 if (ws->hash)
578 HTTPERROR_400_DOUBLEHASH; 608 HTTPERROR_400_DOUBLEHASH;
579 /* ignore this, when we have less than 20 bytes */ 609 /* ignore this, when we have less than 20 bytes */
580 if (scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20) 610 if (urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20)
581 HTTPERROR_400_PARAM; 611 HTTPERROR_400_PARAM;
582 ws->hash = (ot_hash *)write_ptr; 612 ws->hash = (ot_hash *)write_ptr;
583 break; 613 break;
@@ -585,9 +615,9 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
585 case 7: /* matched "ip" */ 615 case 7: /* matched "ip" */
586 { 616 {
587 char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply + 16; 617 char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply + 16;
588 len = scan_urlencoded_query(&read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE); 618 len = urlencoded_parse(&read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE);
589 tmp_buf2[len] = 0; 619 tmp_buf2[len] = 0;
590 if ((len <= 0) || !ip_scan(tmp_buf2, tmp_buf1)) 620 if ((len <= 0) || ip_parse(tmp_buf2, tmp_buf1) != (size_t)len)
591 HTTPERROR_400_PARAM; 621 HTTPERROR_400_PARAM;
592 OT_SETIP(&ws->peer, tmp_buf1); 622 OT_SETIP(&ws->peer, tmp_buf1);
593 } break; 623 } break;
@@ -601,21 +631,21 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
601 uint64_t value; 631 uint64_t value;
602 signed short parsed, bits; 632 signed short parsed, bits;
603 633
604 len = scan_urlencoded_query(&read_ptr, tmp_buf, SCAN_SEARCHPATH_VALUE); 634 len = urlencoded_parse(&read_ptr, tmp_buf, SCAN_SEARCHPATH_VALUE);
605 tmp_buf[len] = 0; 635 tmp_buf[len] = 0;
606 if (len <= 0) 636 if (len <= 0)
607 HTTPERROR_400_PARAM; 637 HTTPERROR_400_PARAM;
608 if (*tmp_buf == '-') { 638 if (*tmp_buf == '-') {
609 loglist_reset(); 639 loglist_reset();
610 return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n"); 640 return ws->reply_size = reply_literal(ws, "Successfully removed.\n");
611 } 641 }
612 parsed = ip_scan(tmp_buf, net.address); 642 parsed = ip_parse(tmp_buf, net.address);
613 if (!parsed) 643 if (!parsed)
614 HTTPERROR_400_PARAM; 644 HTTPERROR_400_PARAM;
615 if (tmp_buf[parsed++] != '/') 645 if (tmp_buf[parsed++] != '/')
616 bits = 128; 646 bits = 128;
617 else { 647 else {
618 parsed = scan_udec(tmp_buf + parsed, &value, 128); 648 parsed = scan_uint(tmp_buf + parsed, &value, 128);
619 if (!parsed) 649 if (!parsed)
620 HTTPERROR_400_PARAM; 650 HTTPERROR_400_PARAM;
621 bits = (signed short)value; 651 bits = (signed short)value;
@@ -624,13 +654,13 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
624 } 654 }
625 net.bits = bits; 655 net.bits = bits;
626 loglist_add_network(&net); 656 loglist_add_network(&net);
627 return ws->reply_size = sprintf(ws->reply, "Successfully added.\n"); 657 return ws->reply_size = reply_literal(ws, "Successfully added.\n");
628 //} 658 //}
629 } break; 659 } break;
630#endif 660#endif
631 case 9: /* matched "peer_id" */ 661 case 9: /* matched "peer_id" */
632 /* ignore this, when we have less than 20 bytes */ 662 /* ignore this, when we have less than 20 bytes */
633 if (scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20) 663 if (urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20)
634 HTTPERROR_400_PARAM; 664 HTTPERROR_400_PARAM;
635 ws->peer_id = write_ptr; 665 ws->peer_id = write_ptr;
636 break; 666 break;
@@ -647,7 +677,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct
647 677
648 /* Scanned whole query string */ 678 /* Scanned whole query string */
649 if (!ws->hash) 679 if (!ws->hash)
650 return ws->reply_size = sprintf(ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e"); 680 return ws->reply_size = reply_literal(ws, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e");
651 681
652 if (OT_PEERFLAG(&ws->peer) & PEER_FLAG_STOPPED) 682 if (OT_PEERFLAG(&ws->peer) & PEER_FLAG_STOPPED)
653 ws->reply_size = remove_peer_from_torrent(FLAG_TCP, ws); 683 ws->reply_size = remove_peer_from_torrent(FLAG_TCP, ws);
@@ -709,7 +739,7 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) {
709 In reality we abandoned requiring the url to be correct. This now 739 In reality we abandoned requiring the url to be correct. This now
710 only decodes url encoded characters, we check for announces and 740 only decodes url encoded characters, we check for announces and
711 scrapes by looking for "a*" or "sc" */ 741 scrapes by looking for "a*" or "sc" */
712 len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_PATH); 742 len = urlencoded_parse(&read_ptr, write_ptr = read_ptr, SCAN_PATH);
713 743
714 /* If parsing returned an error, leave with not found */ 744 /* If parsing returned an error, leave with not found */
715 if (g_redirecturl && (len == -2)) 745 if (g_redirecturl && (len == -2))
@@ -758,9 +788,11 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) {
758 reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf(ws->outbuf, 0, "%zd", ws->reply_size); 788 reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf(ws->outbuf, 0, "%zd", ws->reply_size);
759 ws->reply = ws->outbuf + reply_off; 789 ws->reply = ws->outbuf + reply_off;
760 790
761 /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete 791 /* 2. Now we write the header so that its terminating '\0' lands exactly one byte before the content starts. The bound is the
762 packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ 792 space step 1 reserved, so the '\0' falls where step 3 expects it. Complete packet size is increased by size of header plus
763 ws->reply_size += 1 + sprintf(ws->reply, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size); 793 one byte '\n', we will copy over '\0' in next step */
794 ws->reply_size += 1 + snprintf(ws->reply, (size_t)(SUCCESS_HTTP_HEADER_LENGTH - reply_off),
795 "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size);
764 796
765 /* 3. Finally we join both blocks neatly */ 797 /* 3. Finally we join both blocks neatly */
766 ws->outbuf[SUCCESS_HTTP_HEADER_LENGTH - 1] = '\n'; 798 ws->outbuf[SUCCESS_HTTP_HEADER_LENGTH - 1] = '\n';