diff options
| -rw-r--r-- | opentracker.c | 148 |
1 files changed, 80 insertions, 68 deletions
diff --git a/opentracker.c b/opentracker.c index c420d6f..65ea024 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -103,89 +103,101 @@ const char* http_header(struct http_data* r,const char* h) | |||
| 103 | 103 | ||
| 104 | void httpresponse(struct http_data* h,int64 s) | 104 | void httpresponse(struct http_data* h,int64 s) |
| 105 | { | 105 | { |
| 106 | char* c; | 106 | char *c, *d, *data; |
| 107 | array_cat0(&h->r); | 107 | array_cat0(&h->r); |
| 108 | 108 | ||
| 109 | c = array_start(&h->r); | 109 | c = array_start(&h->r); |
| 110 | 110 | ||
| 111 | if (byte_diff(c,4,"GET ")) | 111 | if (byte_diff(c,4,"GET ")) { |
| 112 | { | ||
| 113 | e400: | 112 | e400: |
| 114 | httperror(h,"400 Invalid Request","This server only understands GET."); | 113 | httperror(h,"400 Invalid Request","This server only understands GET."); |
| 114 | goto bailout; | ||
| 115 | } | 115 | } |
| 116 | else | ||
| 117 | { | ||
| 118 | char *d, *data; | ||
| 119 | |||
| 120 | // expect 'GET /uri?nnbjhg HTTP/1.*' | ||
| 121 | c+=4; | ||
| 122 | |||
| 123 | for (d=c; *d!=' '&&*d!='\t'&&*d!='\n'&&*d!='\r'; ++d) ; | ||
| 124 | |||
| 125 | if (*d!=' ') goto e400; | ||
| 126 | *d=0; | ||
| 127 | if (c[0]!='/') goto e404; | ||
| 128 | while (c[1]=='/') ++c; | ||
| 129 | |||
| 130 | data = c; | ||
| 131 | switch( scan_urlencoded_query( &c, data, SCAN_PATH ) ) { | ||
| 132 | case 6: /* scrape ? */ | ||
| 133 | if (!byte_diff(c,6,"scrape")) | ||
| 134 | goto e404; | ||
| 135 | break; | ||
| 136 | case 9: | ||
| 137 | if( !byte_diff(c,8,"announce")) | ||
| 138 | goto e404; | ||
| 139 | else { | ||
| 140 | // info_hash, left, port, numwant, compact | ||
| 141 | struct ot_peer peer; | ||
| 142 | byte_copy( peer.ip, 4, h->ip ); | ||
| 143 | peer.port = 6881; | ||
| 144 | 116 | ||
| 145 | while( 1 ) { | 117 | // expect 'GET /uri?nnbjhg HTTP/1.*' |
| 118 | c+=4; | ||
| 119 | |||
| 120 | for (d=c; *d!=' '&&*d!='\t'&&*d!='\n'&&*d!='\r'; ++d) ; | ||
| 121 | |||
| 122 | if (*d!=' ') goto e400; | ||
| 123 | *d=0; | ||
| 124 | if (c[0]!='/') goto e404; | ||
| 125 | while (c[1]=='/') ++c; | ||
| 126 | |||
| 127 | data = c; | ||
| 128 | switch( scan_urlencoded_query( &c, data, SCAN_PATH ) ) { | ||
| 129 | case 0: | ||
| 130 | e404: | ||
| 131 | httperror(h,"404 Not Found","No such file or directory."); | ||
| 132 | goto bailout; | ||
| 133 | case 6: /* scrape ? */ | ||
| 134 | if (!byte_diff(c,6,"scrape")) | ||
| 135 | goto e404; | ||
| 136 | break; | ||
| 137 | case 9: | ||
| 138 | if( !byte_diff(c,8,"announce")) | ||
| 139 | goto e404; | ||
| 140 | else { | ||
| 141 | // info_hash, left, port, numwant, compact | ||
| 142 | struct ot_peer peer; | ||
| 143 | ot_hash *hash = NULL; | ||
| 144 | byte_copy( peer.ip, 4, h->ip ); | ||
| 145 | peer.port = 6881; | ||
| 146 | |||
| 147 | while( 1 ) { | ||
| 148 | data = c; | ||
| 149 | switch( scan_urlencoded_query( &c, data, SCAN_SEARCHPATH_PARAM ) ) { | ||
| 150 | case -1: /* error */ | ||
| 151 | goto e404; | ||
| 152 | case 4: | ||
| 153 | if(!byte_diff(c,4,"port")) | ||
| 154 | /* scan int */ c; | ||
| 155 | else if(!byte_diff(c,4,"left")) | ||
| 156 | /* scan int */ c; | ||
| 157 | break; | ||
| 158 | case 7: | ||
| 159 | if(!byte_diff(c,7,"numwant")) | ||
| 160 | /* scan int */ c; | ||
| 161 | else if(!byte_diff(c,7,"compact")) | ||
| 162 | /* scan flag */ c; | ||
| 163 | break; | ||
| 164 | case 9: /* info_hash= */ | ||
| 165 | if(!byte_diff(c,9,"info_hash")) { | ||
| 146 | data = c; | 166 | data = c; |
| 147 | switch( scan_urlencoded_query( &c, data, SCAN_SEARCHPATH_PARAM ) ) { | 167 | /* ignore this, when we have less than 20 bytes */ |
| 148 | case -1: /* error */ | 168 | switch( scan_urlencoded_query( &c, data, SCAN_SEARCHPATH_VALUE ) ) |
| 169 | case -1: | ||
| 149 | httperror(h,"404 Not Found","No such file or directory."); | 170 | httperror(h,"404 Not Found","No such file or directory."); |
| 150 | goto e404; | 171 | goto bailout; |
| 151 | case 4: | 172 | case 20: |
| 152 | if(!byte_diff(c,4,"port")) | 173 | hash = (ot_hash*)data; |
| 153 | /* scan int */ c; | ||
| 154 | else if(!byte_diff(c,4,"left")) | ||
| 155 | /* scan int */ c; | ||
| 156 | break; | 174 | break; |
| 157 | case 7: | 175 | default: |
| 158 | if(!byte_diff(c,7,"numwant")) | 176 | continue; |
| 159 | /* scan int */ c; | ||
| 160 | else if(!byte_diff(c,7,"compact")) | ||
| 161 | /* scan flag */ c; | ||
| 162 | break; | ||
| 163 | case 9: /* info_hash */ | ||
| 164 | if(!byte_diff(c,9,"info_hash")) c; | ||
| 165 | /* scan 20 bytes */ | ||
| 166 | break; | ||
| 167 | } | ||
| 168 | } | 177 | } |
| 178 | break; | ||
| 169 | } | 179 | } |
| 170 | break; | ||
| 171 | default: /* neither scrape nor announce */ | ||
| 172 | httperror(h,"404 Not Found","No such file or directory."); | ||
| 173 | goto e404; | ||
| 174 | } | 180 | } |
| 175 | 181 | } | |
| 176 | c=h->hdrbuf=(char*)malloc(500); | 182 | break; |
| 177 | c+=fmt_str(c,"HTTP/1.1 Coming Up\r\nContent-Type: text/plain"); | 183 | default: /* neither scrape nor announce */ |
| 178 | c+=fmt_str(c,"\r\nContent-Length: "); | 184 | httperror(h,"404 Not Found","No such file or directory."); |
| 179 | /* ANSWER SIZE*/ | 185 | goto bailout; |
| 180 | c+=fmt_ulonglong(c, 100 ); | ||
| 181 | c+=fmt_str(c,"\r\nLast-Modified: "); | ||
| 182 | /* MODIFY DATE | ||
| 183 | c+=fmt_httpdate(c,s.st_mtime); */ | ||
| 184 | c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); | ||
| 185 | iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); | ||
| 186 | iob_addbuf(&h->iob,tracker_answer, tracker_answer_size); | ||
| 187 | } | 186 | } |
| 188 | e404: | 187 | |
| 188 | c=h->hdrbuf=(char*)malloc(500); | ||
| 189 | c+=fmt_str(c,"HTTP/1.1 Coming Up\r\nContent-Type: text/plain"); | ||
| 190 | c+=fmt_str(c,"\r\nContent-Length: "); | ||
| 191 | /* ANSWER SIZE*/ | ||
| 192 | c+=fmt_ulonglong(c, 100 ); | ||
| 193 | c+=fmt_str(c,"\r\nLast-Modified: "); | ||
| 194 | /* MODIFY DATE | ||
| 195 | c+=fmt_httpdate(c,s.st_mtime); */ | ||
| 196 | c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); | ||
| 197 | iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); | ||
| 198 | iob_addbuf(&h->iob,tracker_answer, tracker_answer_size); | ||
| 199 | |||
| 200 | bailout: | ||
| 189 | io_dontwantread(s); | 201 | io_dontwantread(s); |
| 190 | io_wantwrite(s); | 202 | io_wantwrite(s); |
| 191 | } | 203 | } |
