diff --git a/opentracker.c b/opentracker.c index 16f2f1e..0034ec5 100644 --- a/opentracker.c +++ b/opentracker.c @@ -31,177 +31,272 @@ struct http_data { io_batch iob; char* hdrbuf; int hlen; + char ip[16]; }; -int header_complete(struct http_data* r) { - long i; - long l=array_bytes(&r->r); - const char* c=array_start(&r->r); - for (i=0; i+1r); + const char* c = array_start(&r->r); + + for (i=0; i+1hdrbuf=(char*)malloc(strlen(message)+strlen(title)+200); - if (!c) { - r->hdrbuf="HTTP/1.0 500 internal error\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nout of memory\n"; - r->hlen=strlen(r->hdrbuf); - } else { - c+=fmt_str(c,"HTTP/1.0 "); - c+=fmt_str(c,title); - c+=fmt_str(c,"\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: "); - c+=fmt_ulong(c,strlen(message)+strlen(title)+16-4); - c+=fmt_str(c,"\r\n\r\n"); - c+=fmt_str(c,title+4); - c+=fmt_str(c,"\n"); - r->hlen=c - r->hdrbuf; - } - iob_addbuf(&r->iob,r->hdrbuf,r->hlen); +void httperror(struct http_data* r,const char* title,const char* message) +{ + char* c; + c=r->hdrbuf=(char*)malloc(strlen(message)+strlen(title)+200); + + if (!c) + { + r->hdrbuf="HTTP/1.0 500 internal error\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nout of memory\n"; + r->hlen=strlen(r->hdrbuf); + } + else + { + c+=fmt_str(c,"HTTP/1.0 "); + c+=fmt_str(c,title); + c+=fmt_str(c,"\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: "); + c+=fmt_ulong(c,strlen(message)+strlen(title)+16-4); + c+=fmt_str(c,"\r\n\r\n"); + c+=fmt_str(c,title+4); + c+=fmt_str(c,"\n"); + r->hlen=c - r->hdrbuf; + } + iob_addbuf(&r->iob,r->hdrbuf,r->hlen); } -const char* http_header(struct http_data* r,const char* h) { - long i; - long l=array_bytes(&r->r); - long sl=strlen(h); - const char* c=array_start(&r->r); - for (i=0; i+sl+2r); + long sl = strlen(h); + const char* c = array_start(&r->r); + + for (i=0; i+sl+2r); - c=array_start(&h->r); - if (byte_diff(c,4,"GET ")) { +void httpresponse(struct http_data* h,int64 s) +{ + char* c; + array_cat0(&h->r); + + c = array_start(&h->r); + + if (byte_diff(c,4,"GET ")) + { e400: - httperror(h,"400 Invalid Request","This server only understands GET."); - } else { - char *d; - int64 fd; - struct stat s; - c+=4; - for (d=c; *d!=' '&&*d!='\t'&&*d!='\n'&&*d!='\r'; ++d) ; - if (*d!=' ') goto e400; - *d=0; - if (c[0]!='/') goto e404; - while (c[1]=='/') ++c; - if (!io_readfile(&fd,c+1)) { + httperror(h,"400 Invalid Request","This server only understands GET."); + } + else + { + char *d; + int64 fd; + struct stat s; + + // expect 'GET /uri?nnbjhg HTTP/1.*' + c+=4; + + for (d=c; *d!=' '&&*d!='\t'&&*d!='\n'&&*d!='\r'; ++d) ; + + if (*d!=' ') goto e400; + *d=0; + if (c[0]!='/') goto e404; + while (c[1]=='/') ++c; + + if (!byte_diff(c,9,"announce?")) + { + // info_hash, left, port, numwant, compact + struct ot_peer peer; + byte_copy( peer.ip, h->ip, 4); + peer.port = 6881; + + c+=9; + while( *c!=' ' ) { + if(!byte_diff(c,10,"info_hash=")) + { + // String is expected to be URL encoded, so expect + // (%[0-9A-F][0-9A-F]){20} + int s = scan_urlencoded( + + } + else if(!byte_diff(c,8,"numwant=")) + { + + } + else if(!byte_diff(c,8,"compact=")) + { + + } + else if(!byte_diff(c,5,"port=")) + { + + } + else if(!byte_diff(c,5,"left=")) + { + + } + + while( *++c!=' ' && *c!='&'); + } + } + else if (!byte_diff(c,7,"scrape?")) + { + + } + else + { + httperror(h,"404 Not Found","No such file or directory."); + goto e404; + } + + c=h->hdrbuf=(char*)malloc(500); + c+=fmt_str(c,"HTTP/1.1 Coming Up\r\nContent-Type: text/plain"); + c+=fmt_str(c,"\r\nContent-Length: "); + /* ANSWER SIZE*/ + c+=fmt_ulonglong(c,s.st_size); + c+=fmt_str(c,"\r\nLast-Modified: "); + /* MODIFY DATE */ + c+=fmt_httpdate(c,s.st_mtime); + c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); + iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); + iob_addbuf(&h->iob,tracker_answer, tzracker_answer_size); + } e404: - httperror(h,"404 Not Found","No such file or directory."); - } else { - if (fstat(fd,&s)==-1) { - io_close(fd); - goto e404; - } - c=h->hdrbuf=(char*)malloc(500); - c+=fmt_str(c,"HTTP/1.1 Coming Up\r\nContent-Type: text/plain"); - c+=fmt_str(c,"\r\nContent-Length: "); -/* ANSWER SIZE*/ - c+=fmt_ulonglong(c,s.st_size); - c+=fmt_str(c,"\r\nLast-Modified: "); -/* MODIFY DATE */ - c+=fmt_httpdate(c,s.st_mtime); - c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); - iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); - iob_addfile(&h->iob,fd,0,s.st_size); - } - } - io_dontwantread(s); - io_wantwrite(s); + io_dontwantread(s); + io_wantwrite(s); } -int main() { - int s=socket_tcp6(); - uint32 scope_id; - char ip[16]; - uint16 port; - if (socket_bind6_reuse(s,V6any,8000,0)==-1) - panic("socket_bind6_reuse"); - if (socket_listen(s,16)==-1) - panic("socket_listen"); - if (!io_fd(s)) - panic("io_fd"); - io_wantread(s); - for (;;) { - int64 i; - io_wait(); - while ((i=io_canread())!=-1) { - if (i==s) { - int n; - while ((n=socket_accept6(s,ip,&port,&scope_id))!=-1) { - if (io_fd(n)) { - struct http_data* h=(struct http_data*)malloc(sizeof(struct http_data)); - io_wantread(n); - if (h) { - byte_zero(h,sizeof(struct http_data)); - io_setcookie(n,h); - } else - io_close(n); - } else - io_close(n); - buffer_putnlflush(buffer_2); - } - if (errno==EAGAIN) - io_eagain(s); - else - carp("socket_accept6"); - } else { - char buf[8192]; - struct http_data* h=io_getcookie(i); - int l=io_tryread(i,buf,sizeof buf); - if (l==-3) { - if (h) { - array_reset(&h->r); - iob_reset(&h->iob); - free(h->hdrbuf); h->hdrbuf=0; - } - io_close(i); - } else if (l==0) { - if (h) { - array_reset(&h->r); - iob_reset(&h->iob); - free(h->hdrbuf); h->hdrbuf=0; - } - io_close(i); - } else if (l>0) { - array_catb(&h->r,buf,l); - if (array_failed(&h->r)) { - httperror(h,"500 Server Error","request too long."); +int main() +{ + int s=socket_tcp6(); + uint32 scope_id; + char ip[16]; + uint16 port; + + if (socket_bind6_reuse(s,V6any,8000,0)==-1) + panic("socket_bind6_reuse"); + + if (socket_listen(s,16)==-1) + panic("socket_listen"); + + if (!io_fd(s)) + panic("io_fd"); + + io_wantread(s); + + for (;;) + { + int64 i; + io_wait(); + + while ((i=io_canread())!=-1) + { + if (i==s) // ist es der serversocket? + { + int n; + while ((n=socket_accept6(s,ip,&port,&scope_id))!=-1) + { + if (io_fd(n)) + { + struct http_data* h=(struct http_data*)malloc(sizeof(struct http_data)); + io_wantread(n); + + if (h) + { + byte_zero(h,sizeof(struct http_data)); + byte_copy(h->ip,ip,sizeof(ip)); + io_setcookie(n,h); + } else + io_close(n); + } else + io_close(n); + buffer_putnlflush(buffer_2); + } + if (errno==EAGAIN) + io_eagain(s); + else + carp("socket_accept6"); + } + else + { + char buf[8192]; + struct http_data* h=io_getcookie(i); + + int l=io_tryread(i,buf,sizeof buf); + if (l<=0) + { + if (h) + { + array_reset(&h->r); + iob_reset(&h->iob); + free(h->hdrbuf); h->hdrbuf=0; + } + io_close(i); + } + else + { + array_catb(&h->r,buf,l); + + if (array_failed(&h->r)) + { + httperror(h,"500 Server Error","request too long."); emerge: - io_dontwantread(i); - io_wantwrite(i); - } else if (array_bytes(&h->r)>8192) { - httperror(h,"500 request too long","You sent too much headers"); - goto emerge; - } else if ((l=header_complete(h))) - httpresponse(h,i); + io_dontwantread(i); + io_wantwrite(i); + } + else if (array_bytes(&h->r)>8192) + { + httperror(h,"500 request too long","You sent too much headers"); + goto emerge; + } + else if ((l=header_complete(h))) + { + httpresponse(h,i); + } + } + } + } + + while ((i=io_canwrite())!=-1) + { + struct http_data* h=io_getcookie(i); + + int64 r=iob_send(i,&h->iob); + + if (r==-1) + io_eagain(i); + else + if (r<=0) + { + array_trunc(&h->r); + iob_reset(&h->iob); + free(h->hdrbuf); h->hdrbuf=0; + io_close(i); + } + } } - } - } - while ((i=io_canwrite())!=-1) { - struct http_data* h=io_getcookie(i); - int64 r=iob_send(i,&h->iob); - if (r==-1) io_eagain(i); else - if (r<=0) { - array_trunc(&h->r); - iob_reset(&h->iob); - free(h->hdrbuf); h->hdrbuf=0; - io_close(i); - } - } - } - return 0; + return 0; }