diff options
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/opentracker.c b/opentracker.c index a2ada33..57c7e9a 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | /* Globals */ | 44 | /* Globals */ |
| 45 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; | 45 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; |
| 46 | static const size_t SUCCESS_HTTP_HEADER_LENGHT_CONTENT_ENCODING = 32; | ||
| 46 | static const size_t SUCCESS_HTTP_SIZE_OFF = 17; | 47 | static const size_t SUCCESS_HTTP_SIZE_OFF = 17; |
| 47 | static uint32_t g_adminip_addresses[OT_ADMINIP_MAX]; | 48 | static uint32_t g_adminip_addresses[OT_ADMINIP_MAX]; |
| 48 | static unsigned int g_adminip_count = 0; | 49 | static unsigned int g_adminip_count = 0; |
| @@ -73,15 +74,14 @@ static size_t ot_sockets_count = 0; | |||
| 73 | 74 | ||
| 74 | #ifdef _DEBUG_HTTPERROR | 75 | #ifdef _DEBUG_HTTPERROR |
| 75 | static char debug_request[8192]; | 76 | static char debug_request[8192]; |
| 76 | #define _DEBUG_HTTPERROR_PARAM( param ) , param | ||
| 77 | #else | ||
| 78 | #define _DEBUG_HTTPERROR_PARAM( param ) | ||
| 79 | #endif | 77 | #endif |
| 80 | 78 | ||
| 81 | typedef enum { | 79 | typedef enum { |
| 82 | STRUCT_HTTP_FLAG_ARRAY_USED = 1, | 80 | STRUCT_HTTP_FLAG_ARRAY_USED = 1, |
| 83 | STRUCT_HTTP_FLAG_IOB_USED = 2, | 81 | STRUCT_HTTP_FLAG_IOB_USED = 2, |
| 84 | STRUCT_HTTP_FLAG_WAITINGFORTASK = 4 | 82 | STRUCT_HTTP_FLAG_WAITINGFORTASK = 4, |
| 83 | STRUCT_HTTP_FLAG_GZIP = 8, | ||
| 84 | STRUCT_HTTP_FLAG_BZIP2 = 16 | ||
| 85 | } STRUCT_HTTP_FLAG; | 85 | } STRUCT_HTTP_FLAG; |
| 86 | 86 | ||
| 87 | struct http_data { | 87 | struct http_data { |
| @@ -100,7 +100,7 @@ static int ot_ip_compare( const void *a, const void *b ) { return memcmp( a,b,4 | |||
| 100 | int main( int argc, char **argv ); | 100 | int main( int argc, char **argv ); |
| 101 | 101 | ||
| 102 | static void httperror( const int64 s, const char *title, const char *message ); | 102 | static void httperror( const int64 s, const char *title, const char *message ); |
| 103 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM(size_t l ) ); | 103 | static void httpresponse( const int64 s, char *data, size_t l ); |
| 104 | 104 | ||
| 105 | static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector ); | 105 | static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector ); |
| 106 | static void senddata( const int64 s, char *buffer, const size_t size ); | 106 | static void senddata( const int64 s, char *buffer, const size_t size ); |
| @@ -162,7 +162,7 @@ static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovec | |||
| 162 | iovec_free( &iovec_entries, &iovector ); | 162 | iovec_free( &iovec_entries, &iovector ); |
| 163 | HTTPERROR_500; | 163 | HTTPERROR_500; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /* If this socket collected request in a buffer, | 166 | /* If this socket collected request in a buffer, |
| 167 | free it now */ | 167 | free it now */ |
| 168 | if( h->flag & STRUCT_HTTP_FLAG_ARRAY_USED ) { | 168 | if( h->flag & STRUCT_HTTP_FLAG_ARRAY_USED ) { |
| @@ -173,20 +173,24 @@ static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovec | |||
| 173 | /* If we came here, wait for the answer is over */ | 173 | /* If we came here, wait for the answer is over */ |
| 174 | h->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; | 174 | h->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 175 | 175 | ||
| 176 | /* Our answers never are 0 bytes. Return an error. */ | 176 | /* Our answers never are 0 vectors. Return an error. */ |
| 177 | if( !iovec_entries || !iovector[0].iov_len ) { | 177 | if( !iovec_entries ) { |
| 178 | iovec_free( &iovec_entries, &iovector ); | ||
| 179 | HTTPERROR_500; | 178 | HTTPERROR_500; |
| 180 | } | 179 | } |
| 181 | 180 | ||
| 182 | /* Prepare space for http header */ | 181 | /* Prepare space for http header */ |
| 183 | header = malloc( SUCCESS_HTTP_HEADER_LENGTH ); | 182 | header = malloc( SUCCESS_HTTP_HEADER_LENGTH + SUCCESS_HTTP_HEADER_LENGHT_CONTENT_ENCODING ); |
| 184 | if( !header ) { | 183 | if( !header ) { |
| 185 | iovec_free( &iovec_entries, &iovector ); | 184 | iovec_free( &iovec_entries, &iovector ); |
| 186 | HTTPERROR_500; | 185 | HTTPERROR_500; |
| 187 | } | 186 | } |
| 188 | 187 | ||
| 189 | header_size = sprintf( header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r\n", size ); | 188 | if( h->flag & STRUCT_HTTP_FLAG_GZIP ) |
| 189 | header_size = sprintf( header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Encoding: gzip\r\nContent-Length: %zd\r\n\r\n", size ); | ||
| 190 | else if( h->flag & STRUCT_HTTP_FLAG_BZIP2 ) | ||
| 191 | header_size = sprintf( header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Encoding: bzip2\r\nContent-Length: %zd\r\n\r\n", size ); | ||
| 192 | else | ||
| 193 | header_size = sprintf( header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r\n", size ); | ||
| 190 | 194 | ||
| 191 | iob_reset( &h->batch ); | 195 | iob_reset( &h->batch ); |
| 192 | iob_addbuf_free( &h->batch, header, header_size ); | 196 | iob_addbuf_free( &h->batch, header, header_size ); |
| @@ -241,9 +245,9 @@ static void senddata( const int64 s, char *buffer, size_t size ) { | |||
| 241 | } | 245 | } |
| 242 | } | 246 | } |
| 243 | 247 | ||
| 244 | static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size_t l ) ) { | 248 | static void httpresponse( const int64 s, char *data, size_t l ) { |
| 245 | struct http_data* h = io_getcookie( s ); | 249 | struct http_data* h = io_getcookie( s ); |
| 246 | char *c; | 250 | char *c, *d=data; |
| 247 | ot_peer peer; | 251 | ot_peer peer; |
| 248 | ot_torrent *torrent; | 252 | ot_torrent *torrent; |
| 249 | ot_hash *hash = NULL; | 253 | ot_hash *hash = NULL; |
| @@ -253,6 +257,9 @@ static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size | |||
| 253 | ssize_t len; | 257 | ssize_t len; |
| 254 | size_t reply_size = 0, reply_off; | 258 | size_t reply_size = 0, reply_off; |
| 255 | 259 | ||
| 260 | /* Touch l and d in case it is unused */ | ||
| 261 | l = l; d = d; | ||
| 262 | |||
| 256 | #ifdef _DEBUG_HTTPERROR | 263 | #ifdef _DEBUG_HTTPERROR |
| 257 | if( l >= sizeof( debug_request ) ) | 264 | if( l >= sizeof( debug_request ) ) |
| 258 | l = sizeof( debug_request) - 1; | 265 | l = sizeof( debug_request) - 1; |
| @@ -379,6 +386,12 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); | |||
| 379 | } | 386 | } |
| 380 | 387 | ||
| 381 | if( mode == TASK_STATS_TPB ) { | 388 | if( mode == TASK_STATS_TPB ) { |
| 389 | #ifdef WANT_COMPRESSION_GZIP | ||
| 390 | if( strnstr( d, "gzip", l ) ) { | ||
| 391 | h->flag |= STRUCT_HTTP_FLAG_GZIP; | ||
| 392 | format |= TASK_FLAG_GZIP; | ||
| 393 | } | ||
| 394 | #endif | ||
| 382 | /* Pass this task to the worker thread */ | 395 | /* Pass this task to the worker thread */ |
| 383 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; | 396 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 384 | fullscrape_deliver( s, format ); | 397 | fullscrape_deliver( s, format ); |
| @@ -403,9 +416,17 @@ LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now | |||
| 403 | #ifdef _DEBUG_HTTPERROR | 416 | #ifdef _DEBUG_HTTPERROR |
| 404 | write( 2, debug_request, l ); | 417 | write( 2, debug_request, l ); |
| 405 | #endif | 418 | #endif |
| 419 | format = 0; | ||
| 420 | #ifdef WANT_COMPRESSION_GZIP | ||
| 421 | if( strnstr( d, "gzip", l ) ) { | ||
| 422 | h->flag |= STRUCT_HTTP_FLAG_GZIP; | ||
| 423 | format = TASK_FLAG_GZIP; | ||
| 424 | } | ||
| 425 | #endif | ||
| 426 | |||
| 406 | /* Pass this task to the worker thread */ | 427 | /* Pass this task to the worker thread */ |
| 407 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; | 428 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 408 | fullscrape_deliver( s, TASK_FULLSCRAPE ); | 429 | fullscrape_deliver( s, TASK_FULLSCRAPE | format ); |
| 409 | io_dontwantread( s ); | 430 | io_dontwantread( s ); |
| 410 | return; | 431 | return; |
| 411 | } | 432 | } |
| @@ -655,7 +676,7 @@ static void handle_read( const int64 clientsocket ) { | |||
| 655 | /* If we get the whole request in one packet, handle it without copying */ | 676 | /* If we get the whole request in one packet, handle it without copying */ |
| 656 | if( !array_start( &h->request ) ) { | 677 | if( !array_start( &h->request ) ) { |
| 657 | if( memchr( static_inbuf, '\n', l ) ) | 678 | if( memchr( static_inbuf, '\n', l ) ) |
| 658 | return httpresponse( clientsocket, static_inbuf _DEBUG_HTTPERROR_PARAM( l ) ); | 679 | return httpresponse( clientsocket, static_inbuf, l ); |
| 659 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; | 680 | h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; |
| 660 | return array_catb( &h->request, static_inbuf, l ); | 681 | return array_catb( &h->request, static_inbuf, l ); |
| 661 | } | 682 | } |
| @@ -670,7 +691,7 @@ static void handle_read( const int64 clientsocket ) { | |||
| 670 | return httperror( clientsocket, "500 request too long", "You sent too much headers"); | 691 | return httperror( clientsocket, "500 request too long", "You sent too much headers"); |
| 671 | 692 | ||
| 672 | if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) | 693 | if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) |
| 673 | return httpresponse( clientsocket, array_start( &h->request ) _DEBUG_HTTPERROR_PARAM( array_bytes( &h->request ) ) ); | 694 | return httpresponse( clientsocket, array_start( &h->request ), array_bytes( &h->request ) ); |
| 674 | } | 695 | } |
| 675 | 696 | ||
| 676 | static void handle_write( const int64 clientsocket ) { | 697 | static void handle_write( const int64 clientsocket ) { |
| @@ -722,9 +743,9 @@ static void handle_timeouted( void ) { | |||
| 722 | } | 743 | } |
| 723 | 744 | ||
| 724 | static void server_mainloop( ) { | 745 | static void server_mainloop( ) { |
| 725 | time_t next_timeout_check = g_now + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 746 | time_t next_timeout_check = g_now + OT_CLIENT_TIMEOUT_CHECKINTERVAL; |
| 726 | struct iovec *iovector; | 747 | struct iovec *iovector; |
| 727 | int iovec_entries; | 748 | int iovec_entries; |
| 728 | 749 | ||
| 729 | for( ; ; ) { | 750 | for( ; ; ) { |
| 730 | int64 i; | 751 | int64 i; |
