diff options
| -rw-r--r-- | ot_http.c | 14 |
1 files changed, 12 insertions, 2 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_vector.h" | ||
| 27 | #include "ot_fmt.h" | 28 | #include "ot_fmt.h" |
| 28 | #include "ot_stats.h" | 29 | #include "ot_stats.h" |
| 29 | #include "ot_urlencoded.h" | 30 | #include "ot_urlencoded.h" |
| @@ -233,7 +234,6 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 233 | {"scrp", TASK_STATS_SCRAPE}, | 234 | {"scrp", TASK_STATS_SCRAPE}, |
| 234 | {"udp4", TASK_STATS_UDP}, | 235 | {"udp4", TASK_STATS_UDP}, |
| 235 | {"tcp4", TASK_STATS_TCP}, | 236 | {"tcp4", TASK_STATS_TCP}, |
| 236 | {"busy", TASK_STATS_BUSY_NETWORKS}, | ||
| 237 | {"torr", TASK_STATS_TORRENTS}, | 237 | {"torr", TASK_STATS_TORRENTS}, |
| 238 | {"fscr", TASK_STATS_FULLSCRAPE}, | 238 | {"fscr", TASK_STATS_FULLSCRAPE}, |
| 239 | {"s24s", TASK_STATS_SLASH24S}, | 239 | {"s24s", TASK_STATS_SLASH24S}, |
| @@ -418,13 +418,15 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * | |||
| 418 | } | 418 | } |
| 419 | #endif | 419 | #endif |
| 420 | 420 | ||
| 421 | static int compare_hash(const void *left, const void *right) { return memcmp(left, right, sizeof(ot_hash)); } | ||
| 422 | |||
| 421 | static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { | 423 | static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { |
| 422 | static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; | 424 | static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; |
| 423 | 425 | ||
| 424 | ot_hash *multiscrape_buf = (ot_hash *)ws->request; | 426 | ot_hash *multiscrape_buf = (ot_hash *)ws->request; |
| 425 | char *reply = ws->reply; | 427 | char *reply = ws->reply; |
| 426 | int scanon = 1; | 428 | int scanon = 1; |
| 427 | size_t numwant = 0; | 429 | size_t i, unique, numwant = 0; |
| 428 | 430 | ||
| 429 | /* This is to hack around stupid clients that send "scrape ?info_hash" */ | 431 | /* This is to hack around stupid clients that send "scrape ?info_hash" */ |
| 430 | if (read_ptr[-1] != '?') { | 432 | if (read_ptr[-1] != '?') { |
| @@ -461,6 +463,14 @@ static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, | |||
| 461 | if (numwant > OT_MAXMULTISCRAPE_COUNT) | 463 | if (numwant > OT_MAXMULTISCRAPE_COUNT) |
| 462 | numwant = OT_MAXMULTISCRAPE_COUNT; | 464 | numwant = OT_MAXMULTISCRAPE_COUNT; |
| 463 | 465 | ||
| 466 | /* A bencoded dictionary has its keys in order and names each one once, so | ||
| 467 | the answer cannot just follow the order the client asked in */ | ||
| 468 | qsort(multiscrape_buf, numwant, sizeof(ot_hash), compare_hash); | ||
| 469 | for (i = unique = 1; i < numwant; ++i) | ||
| 470 | if (memcmp(multiscrape_buf[i], multiscrape_buf[unique - 1], sizeof(ot_hash))) | ||
| 471 | memcpy(multiscrape_buf[unique++], multiscrape_buf[i], sizeof(ot_hash)); | ||
| 472 | numwant = unique; | ||
| 473 | |||
| 464 | /* Enough for http header + whole scrape string */ | 474 | /* Enough for http header + whole scrape string */ |
| 465 | return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, &reply, ws->outbuf + G_OUTBUF_SIZE); | 475 | return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, &reply, ws->outbuf + G_OUTBUF_SIZE); |
| 466 | ws->reply_size = reply - ws->reply; | 476 | ws->reply_size = reply - ws->reply; |
