diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-26 22:32:52 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-26 22:32:52 +0100 |
| commit | 1f9494979268b62ed4b4588fb7d9e790c0e12100 (patch) | |
| tree | ed4f78369fe610b5c9188cb4159a23370d50a799 /ot_http.c | |
| parent | 6d5485b97cd46f81512e9198ac7c59c7ba1d9247 (diff) | |
replace all calls to sprintf with a format helper that advances a cursor. Also convert the meta-formatter (i.e. results printer) to this scheme
Diffstat (limited to 'ot_http.c')
| -rw-r--r-- | ot_http.c | 40 |
1 files changed, 29 insertions, 11 deletions
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "ot_scan.h" | 24 | #include "ot_scan.h" |
| 25 | #include "ot_event.h" | 25 | #include "ot_event.h" |
| 26 | #include "ot_fdstate.h" | 26 | #include "ot_fdstate.h" |
| 27 | #include "ot_fmt.h" | ||
| 27 | #include "ot_stats.h" | 28 | #include "ot_stats.h" |
| 28 | #include "ot_urlencoded.h" | 29 | #include "ot_urlencoded.h" |
| 29 | #include "trackerlogic.h" | 30 | #include "trackerlogic.h" |
| @@ -257,6 +258,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 257 | {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; | 258 | {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; |
| 258 | 259 | ||
| 259 | struct http_data *cookie = fdstate_cookie(sock); | 260 | struct http_data *cookie = fdstate_cookie(sock); |
| 261 | char *reply; | ||
| 260 | int mode = TASK_STATS_PEERS, scanon = 1, format = 0; | 262 | int mode = TASK_STATS_PEERS, scanon = 1, format = 0; |
| 261 | 263 | ||
| 262 | /* 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 |
| @@ -333,7 +335,9 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 333 | } | 335 | } |
| 334 | 336 | ||
| 335 | /* Simple stats can be answerred immediately */ | 337 | /* Simple stats can be answerred immediately */ |
| 336 | 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; | ||
| 337 | } | 341 | } |
| 338 | 342 | ||
| 339 | #ifdef WANT_MODEST_FULLSCRAPES | 343 | #ifdef WANT_MODEST_FULLSCRAPES |
| @@ -417,9 +421,10 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * | |||
| 417 | static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { | 421 | static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { |
| 418 | static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; | 422 | static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; |
| 419 | 423 | ||
| 420 | ot_hash *multiscrape_buf = (ot_hash *)ws->request; | 424 | ot_hash *multiscrape_buf = (ot_hash *)ws->request; |
| 421 | int scanon = 1; | 425 | char *reply = ws->reply; |
| 422 | size_t numwant = 0; | 426 | int scanon = 1; |
| 427 | size_t numwant = 0; | ||
| 423 | 428 | ||
| 424 | /* 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" */ |
| 425 | if (read_ptr[-1] != '?') { | 430 | if (read_ptr[-1] != '?') { |
| @@ -457,7 +462,8 @@ static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, | |||
| 457 | numwant = OT_MAXMULTISCRAPE_COUNT; | 462 | numwant = OT_MAXMULTISCRAPE_COUNT; |
| 458 | 463 | ||
| 459 | /* Enough for http header + whole scrape string */ | 464 | /* Enough for http header + whole scrape string */ |
| 460 | 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; | ||
| 461 | stats_issue_event(EVENT_SCRAPE, FLAG_TCP, ws->reply_size); | 467 | stats_issue_event(EVENT_SCRAPE, FLAG_TCP, ws->reply_size); |
| 462 | return ws->reply_size; | 468 | return ws->reply_size; |
| 463 | } | 469 | } |
| @@ -493,6 +499,16 @@ static ot_keywords keywords_announce[] = {{"port", 1}, {"left", 2}, {"event", | |||
| 493 | #endif | 499 | #endif |
| 494 | {"peer_id", 9}, {NULL, -3}}; | 500 | {"peer_id", 9}, {NULL, -3}}; |
| 495 | static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}}; | 501 | static 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 */ | ||
| 505 | static 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 | |||
| 496 | static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { | 512 | static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { |
| 497 | size_t numwant; | 513 | size_t numwant; |
| 498 | int64_t tmp; | 514 | int64_t tmp; |
| @@ -621,7 +637,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct | |||
| 621 | HTTPERROR_400_PARAM; | 637 | HTTPERROR_400_PARAM; |
| 622 | if (*tmp_buf == '-') { | 638 | if (*tmp_buf == '-') { |
| 623 | loglist_reset(); | 639 | loglist_reset(); |
| 624 | return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n"); | 640 | return ws->reply_size = reply_literal(ws, "Successfully removed.\n"); |
| 625 | } | 641 | } |
| 626 | parsed = ip_parse(tmp_buf, net.address); | 642 | parsed = ip_parse(tmp_buf, net.address); |
| 627 | if (!parsed) | 643 | if (!parsed) |
| @@ -638,7 +654,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct | |||
| 638 | } | 654 | } |
| 639 | net.bits = bits; | 655 | net.bits = bits; |
| 640 | loglist_add_network(&net); | 656 | loglist_add_network(&net); |
| 641 | return ws->reply_size = sprintf(ws->reply, "Successfully added.\n"); | 657 | return ws->reply_size = reply_literal(ws, "Successfully added.\n"); |
| 642 | //} | 658 | //} |
| 643 | } break; | 659 | } break; |
| 644 | #endif | 660 | #endif |
| @@ -661,7 +677,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct | |||
| 661 | 677 | ||
| 662 | /* Scanned whole query string */ | 678 | /* Scanned whole query string */ |
| 663 | if (!ws->hash) | 679 | if (!ws->hash) |
| 664 | 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"); |
| 665 | 681 | ||
| 666 | if (OT_PEERFLAG(&ws->peer) & PEER_FLAG_STOPPED) | 682 | if (OT_PEERFLAG(&ws->peer) & PEER_FLAG_STOPPED) |
| 667 | ws->reply_size = remove_peer_from_torrent(FLAG_TCP, ws); | 683 | ws->reply_size = remove_peer_from_torrent(FLAG_TCP, ws); |
| @@ -772,9 +788,11 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) { | |||
| 772 | 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); |
| 773 | ws->reply = ws->outbuf + reply_off; | 789 | ws->reply = ws->outbuf + reply_off; |
| 774 | 790 | ||
| 775 | /* 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 |
| 776 | 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 |
| 777 | 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); | ||
| 778 | 796 | ||
| 779 | /* 3. Finally we join both blocks neatly */ | 797 | /* 3. Finally we join both blocks neatly */ |
| 780 | ws->outbuf[SUCCESS_HTTP_HEADER_LENGTH - 1] = '\n'; | 798 | ws->outbuf[SUCCESS_HTTP_HEADER_LENGTH - 1] = '\n'; |
