summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c59
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 */
45static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; 45static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80;
46static const size_t SUCCESS_HTTP_HEADER_LENGHT_CONTENT_ENCODING = 32;
46static const size_t SUCCESS_HTTP_SIZE_OFF = 17; 47static const size_t SUCCESS_HTTP_SIZE_OFF = 17;
47static uint32_t g_adminip_addresses[OT_ADMINIP_MAX]; 48static uint32_t g_adminip_addresses[OT_ADMINIP_MAX];
48static unsigned int g_adminip_count = 0; 49static 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
75static char debug_request[8192]; 76static 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
81typedef enum { 79typedef 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
87struct http_data { 87struct http_data {
@@ -100,7 +100,7 @@ static int ot_ip_compare( const void *a, const void *b ) { return memcmp( a,b,4
100int main( int argc, char **argv ); 100int main( int argc, char **argv );
101 101
102static void httperror( const int64 s, const char *title, const char *message ); 102static void httperror( const int64 s, const char *title, const char *message );
103static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM(size_t l ) ); 103static void httpresponse( const int64 s, char *data, size_t l );
104 104
105static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector ); 105static void sendiovecdata( const int64 s, int iovec_entries, struct iovec *iovector );
106static void senddata( const int64 s, char *buffer, const size_t size ); 106static 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
244static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size_t l ) ) { 248static 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
404write( 2, debug_request, l ); 417write( 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
676static void handle_write( const int64 clientsocket ) { 697static void handle_write( const int64 clientsocket ) {
@@ -722,9 +743,9 @@ static void handle_timeouted( void ) {
722} 743}
723 744
724static void server_mainloop( ) { 745static 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;