forked from ports/contrib
116 lines
3.4 KiB
Diff
116 lines
3.4 KiB
Diff
http://lists.stargirl.org/pipermail/btpd-users/2007-June/000250.html
|
|
|
|
On Wed, June 27, 2007 10:27, Richard Nyberg said:
|
|
> On Tue, June 26, 2007 12:29, barone rosso said:
|
|
>> the tracker is Macnbits, http://beta.macnbits.com/home.php , a BNBT
|
|
>> tracker based. I have the same problem with all torrents relased by
|
|
>> this tracker.
|
|
>>
|
|
> This tracker almost manages to talk HTTP, but not quite. As specified
|
|
> in RFC 2616, the line endings in HTTP is encoded with CRLF. This
|
|
> tracker only sends LF.
|
|
>
|
|
> Quoted from http://tools.ietf.org/html/rfc2616 section 3.7.1:
|
|
> "a bare CR or LF MUST NOT be substituted for CRLF within any of
|
|
> the HTTP control structures (such as header fields and multipart
|
|
> boundaries)."
|
|
>
|
|
> You should talk to the tracker admins and try to get them to fix it.
|
|
>
|
|
> Nevertheless, this is probably a common error - curl deals with it -
|
|
> so one should perhaps make btpd parse it as well.
|
|
|
|
Please try the attached patch. It should tolerate both types of
|
|
new lines.
|
|
|
|
-Richard
|
|
|
|
Index: misc/http_client.c
|
|
===================================================================
|
|
--- misc/http_client.c (revision 357)
|
|
+++ misc/http_client.c (working copy)
|
|
@@ -132,11 +132,24 @@
|
|
http_free(req);
|
|
}
|
|
|
|
+static char *
|
|
+strnl(char *str, int *nlsize)
|
|
+{
|
|
+ char *nl = strchr(str, '\n');
|
|
+ if (nl != NULL && nl > str && *(nl - 1) == '\r') {
|
|
+ *nlsize = 2;
|
|
+ return nl - 1;
|
|
+ } else {
|
|
+ *nlsize = 1;
|
|
+ return nl;
|
|
+ }
|
|
+}
|
|
+
|
|
static int
|
|
headers_parse(struct http_req *req, char *buf, char *end)
|
|
{
|
|
- int code, majv, minv;
|
|
- char *cur, *crlf;
|
|
+ int code, majv, minv, nlsize;
|
|
+ char *cur, *nl;
|
|
char name[128], value[872];
|
|
struct http_response res;
|
|
|
|
@@ -151,12 +164,12 @@
|
|
if (req->cancel)
|
|
return 1;
|
|
|
|
- cur = strstr(buf, "\r\n") + 2;
|
|
- crlf = strstr(cur, "\r\n");
|
|
+ cur = strchr(buf, '\n') + 1;
|
|
+ nl = strnl(cur, &nlsize);
|
|
while (cur < end) {
|
|
int i;
|
|
char *colon = strchr(cur, ':');
|
|
- if (colon == NULL || colon > crlf)
|
|
+ if (colon == NULL || colon > nl)
|
|
return 0;
|
|
snprintf(name, sizeof(name), "%.*s", (int)(colon - cur), cur);
|
|
|
|
@@ -165,15 +178,15 @@
|
|
val_loop:
|
|
while (isblank(*cur))
|
|
cur++;
|
|
- while (cur < crlf) {
|
|
+ while (cur < nl) {
|
|
if (i < sizeof(value) - 1) {
|
|
value[i] = *cur;
|
|
i++;
|
|
}
|
|
cur++;
|
|
}
|
|
- cur += 2;
|
|
- crlf = strstr(cur, "\r\n");
|
|
+ cur += nlsize;
|
|
+ nl = strnl(cur, &nlsize);
|
|
if (isblank(*cur)) {
|
|
if (i < sizeof(value) - 1) {
|
|
value[i] = ' ';
|
|
@@ -222,7 +235,11 @@
|
|
case PS_HEAD:
|
|
if (len == 0)
|
|
goto error;
|
|
- if ((end = evbuffer_find(req->buf, "\r\n\r\n", 4)) == NULL) {
|
|
+ if ((end = evbuffer_find(req->buf, "\r\n\r\n", 4)) != NULL)
|
|
+ dlen = 4;
|
|
+ else if ((end = evbuffer_find(req->buf, "\n\n", 2)) != NULL)
|
|
+ dlen = 2;
|
|
+ else {
|
|
if (req->buf->off < (1 << 15))
|
|
return 1;
|
|
else
|
|
@@ -235,7 +252,7 @@
|
|
goto error;
|
|
if (req->cancel)
|
|
goto cancel;
|
|
- evbuffer_drain(req->buf, end - (char *)req->buf->buffer + 4);
|
|
+ evbuffer_drain(req->buf, end - (char *)req->buf->buffer + dlen);
|
|
goto again;
|
|
case PS_CHUNK_SIZE:
|
|
assert(req->chunked);
|