contrib/btpd/btpd-0.13.patch
Juergen Daubert cada11e477 btpd: assume maintainership
- added patch to fix bug with BNBT tracker
- added man-page
2008-04-10 19:14:50 +02:00

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);