summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c55
1 files changed, 21 insertions, 34 deletions
diff --git a/opentracker.c b/opentracker.c
index 4d65564..d22a3b2 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -10,7 +10,6 @@
10#include "array.h" 10#include "array.h"
11#include "case.h" 11#include "case.h"
12#include "fmt.h" 12#include "fmt.h"
13#include "iob.h"
14#include "str.h" 13#include "str.h"
15#include <string.h> 14#include <string.h>
16#include <sys/types.h> 15#include <sys/types.h>
@@ -32,8 +31,9 @@ unsigned long const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5;
32static unsigned int ot_overall_connections = 0; 31static unsigned int ot_overall_connections = 0;
33static time_t ot_start_time; 32static time_t ot_start_time;
34static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; 33static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80;
35static char reply[8192]; 34static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17;
36static size_t reply_size; 35// To always have space for error messages
36static char static_reply[8192];
37 37
38static void carp(const char* routine) { 38static void carp(const char* routine) {
39 buffer_puts(buffer_2,routine); 39 buffer_puts(buffer_2,routine);
@@ -49,7 +49,6 @@ static void panic(const char* routine) {
49 49
50struct http_data { 50struct http_data {
51 array r; 51 array r;
52 io_batch iob;
53 unsigned long ip; 52 unsigned long ip;
54}; 53};
55 54
@@ -66,23 +65,24 @@ int header_complete(struct http_data* r) {
66} 65}
67 66
68// whoever sends data is not interested in its input-array 67// whoever sends data is not interested in its input-array
69void senddata(int64 s,struct http_data* h) { 68void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) {
70 size_t written_size; 69 size_t written_size;
71 70
72 if( h ) array_reset(&h->r); 71 if( h ) array_reset(&h->r);
73 written_size = write( s, reply, reply_size ); 72 written_size = write( s, buffer, size );
74 if( ( written_size < 0 ) || ( written_size == reply_size ) ) { 73 if( ( written_size < 0 ) || ( written_size == size ) ) {
75 free(h); io_close( s ); 74 free(h); io_close( s );
76 } else { 75 } else {
76 // here we would take a copy of the buffer and remember it
77 fprintf( stderr, "Should have handled this.\n" ); 77 fprintf( stderr, "Should have handled this.\n" );
78 free(h); io_close( s ); 78 free(h); io_close( s );
79 } 79 }
80} 80}
81 81
82void httperror(int64 s,struct http_data* h,const char* title,const char* message) { 82void httperror(int64 s,struct http_data* h,const char* title,const char* message) {
83 reply_size = sprintf( reply, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", 83 size_t reply_size = sprintf( static_reply, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n",
84 title, strlen(message)+strlen(title)+16-4,title+4); 84 title, strlen(message)+strlen(title)+16-4,title+4);
85 senddata(s,h); 85 senddata(s,h,static_reply,reply_size);
86} 86}
87 87
88// bestimmten http parameter auslesen und adresse zurueckgeben 88// bestimmten http parameter auslesen und adresse zurueckgeben
@@ -114,10 +114,9 @@ void httpresponse(int64 s,struct http_data* h)
114 ot_hash *hash = NULL; 114 ot_hash *hash = NULL;
115 int numwant, tmp, scanon; 115 int numwant, tmp, scanon;
116 unsigned short port = htons(6881); 116 unsigned short port = htons(6881);
117 size_t reply_size = 0;
117 118
118 reply_size = 0;
119 array_cat0(&h->r); 119 array_cat0(&h->r);
120
121 c = array_start(&h->r); 120 c = array_start(&h->r);
122 121
123 if (byte_diff(c,4,"GET ")) { 122 if (byte_diff(c,4,"GET ")) {
@@ -170,7 +169,7 @@ e400_param:
170 return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes."); 169 return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes.");
171 170
172 // Enough for http header + whole scrape string 171 // Enough for http header + whole scrape string
173 if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) 172 if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
174 goto e500; 173 goto e500;
175 break; 174 break;
176 case 8: 175 case 8:
@@ -262,14 +261,14 @@ e400_param:
262 261
263 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { 262 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
264 remove_peer_from_torrent( hash, &peer ); 263 remove_peer_from_torrent( hash, &peer );
265 MEMMOVE( reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); 264 MEMMOVE( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 );
266 } else { 265 } else {
267 torrent = add_peer_to_torrent( hash, &peer ); 266 torrent = add_peer_to_torrent( hash, &peer );
268 if( !torrent ) { 267 if( !torrent ) {
269e500: 268e500:
270 return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later."); 269 return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later.");
271 } 270 }
272 if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) 271 if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
273 goto e500; 272 goto e500;
274 } 273 }
275 break; 274 break;
@@ -278,7 +277,7 @@ e500:
278 goto e404; 277 goto e404;
279 { 278 {
280 unsigned long seconds_elapsed = time( NULL ) - ot_start_time; 279 unsigned long seconds_elapsed = time( NULL ) - ot_start_time;
281 reply_size = sprintf( reply + SUCCESS_HTTP_HEADER_LENGTH, 280 reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH,
282 "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.", 281 "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.",
283 ot_overall_connections, ot_overall_connections, seconds_elapsed, 282 ot_overall_connections, ot_overall_connections, seconds_elapsed,
284 seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) ); 283 seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
@@ -290,12 +289,14 @@ e404:
290 } 289 }
291 290
292 if( reply_size ) { 291 if( reply_size ) {
293 MEMMOVE( reply, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: X \r\n\r\n", SUCCESS_HTTP_HEADER_LENGTH ); 292 size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size );
294 fmt_ulonglong( reply+59, (long long)reply_size ); 293 reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size );
294 static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n';
295 senddata( s, h, static_reply + reply_off, reply_size );
296 } else {
297 if( h ) array_reset(&h->r);
298 free( h ); io_close( s );
295 } 299 }
296 reply_size += SUCCESS_HTTP_HEADER_LENGTH;
297 io_dontwantread(s);
298 senddata(s,h);
299} 300}
300 301
301void graceful( int s ) { 302void graceful( int s ) {
@@ -462,20 +463,6 @@ allparsed:
462 } 463 }
463 } 464 }
464 } 465 }
465
466 while ((i=io_canwrite())!=-1) {
467 struct http_data* h=io_getcookie(i);
468
469 int64 r=iob_send(i,&h->iob);
470 if (r==-1)
471 io_eagain(i);
472 else
473 if ((r<=0)||(h->iob.bytesleft==0)) {
474 iob_reset(&h->iob);
475 free(h);
476 io_close(i);
477 }
478 }
479 } 466 }
480 return 0; 467 return 0;
481} 468}