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 | } |