summaryrefslogtreecommitdiff
path: root/ot_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_http.c')
-rw-r--r--ot_http.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/ot_http.c b/ot_http.c
index 36819c7..2216453 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -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
421static int compare_hash(const void *left, const void *right) { return memcmp(left, right, sizeof(ot_hash)); }
422
421static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { 423static 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;
@@ -727,6 +737,24 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) {
727 /* Tell subroutines where to put reply data */ 737 /* Tell subroutines where to put reply data */
728 ws->reply = ws->outbuf + SUCCESS_HTTP_HEADER_LENGTH; 738 ws->reply = ws->outbuf + SUCCESS_HTTP_HEADER_LENGTH;
729 739
740 /* Find out if the client wants to keep this connection alive, before any
741 subroutine gets to answer: an error reply finishes with the connection
742 on its way out, and ws outlives the connection it was serving */
743 ws->keep_alive = 0;
744#ifdef WANT_KEEPALIVE
745 if ((write_ptr = http_header(ws->request, ws->header_size, "connection")) && (*write_ptr == 'K' || *write_ptr == 'k'))
746 ws->keep_alive = 1;
747#endif
748 {
749 struct http_data *connection = fdstate_cookie(sock);
750 if (connection) {
751 if (ws->keep_alive)
752 connection->flag |= STRUCT_HTTP_FLAG_KEEPALIVE;
753 else
754 connection->flag &= ~STRUCT_HTTP_FLAG_KEEPALIVE;
755 }
756 }
757
730 /* This one implicitely tests strlen < 5, too -- remember, it is \n terminated */ 758 /* This one implicitely tests strlen < 5, too -- remember, it is \n terminated */
731 if (memcmp(read_ptr, "GET /", 5)) 759 if (memcmp(read_ptr, "GET /", 5))
732 HTTPERROR_400; 760 HTTPERROR_400;
@@ -763,14 +791,6 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) {
763 else 791 else
764 HTTPERROR_404; 792 HTTPERROR_404;
765 793
766 /* Find out if the client wants to keep this connection alive */
767 ws->keep_alive = 0;
768#ifdef WANT_KEEPALIVE
769 read_ptr = http_header(ws->request, ws->header_size, "connection");
770 if (read_ptr && (*read_ptr == 'K' || *read_ptr == 'k'))
771 ws->keep_alive = 1;
772#endif
773
774 /* If routines handled sending themselves, just return */ 794 /* If routines handled sending themselves, just return */
775 if (ws->reply_size == -2) 795 if (ws->reply_size == -2)
776 return 0; 796 return 0;