1 http://lists.stargirl.org/pipermail/btpd-users/2007-June/000250.html
2
3 On Wed, June 27, 2007 10:27, Richard Nyberg said:
4 > On Tue, June 26, 2007 12:29, barone rosso said:
5 >> the tracker is Macnbits, http://beta.macnbits.com/home.php , a BNBT
6 >> tracker based. I have the same problem with all torrents relased by
7 >> this tracker.
8 >>
9 > This tracker almost manages to talk HTTP, but not quite. As specified
10 > in RFC 2616, the line endings in HTTP is encoded with CRLF. This
11 > tracker only sends LF.
12 >
13 > Quoted from http://tools.ietf.org/html/rfc2616 section 3.7.1:
14 > "a bare CR or LF MUST NOT be substituted for CRLF within any of
15 > the HTTP control structures (such as header fields and multipart
16 > boundaries)."
17 >
18 > You should talk to the tracker admins and try to get them to fix it.
19 >
20 > Nevertheless, this is probably a common error - curl deals with it -
21 > so one should perhaps make btpd parse it as well.
22
23 Please try the attached patch. It should tolerate both types of
24 new lines.
25
26 -Richard
27
28 Index: misc/http_client.c
29 ===================================================================
30 --- misc/http_client.c (revision 357)
31 +++ misc/http_client.c (working copy)
32 @@ -132,11 +132,24 @@
33 http_free(req);
34 }
35
36 +static char *
37 +strnl(char *str, int *nlsize)
38 +{
39 + char *nl = strchr(str, '\n');
40 + if (nl != NULL && nl > str && *(nl - 1) == '\r') {
41 + *nlsize = 2;
42 + return nl - 1;
43 + } else {
44 + *nlsize = 1;
45 + return nl;
46 + }
47 +}
48 +
49 static int
50 headers_parse(struct http_req *req, char *buf, char *end)
51 {
52 - int code, majv, minv;
53 - char *cur, *crlf;
54 + int code, majv, minv, nlsize;
55 + char *cur, *nl;
56 char name[128], value[872];
57 struct http_response res;
58
59 @@ -151,12 +164,12 @@
60 if (req->cancel)
61 return 1;
62
63 - cur = strstr(buf, "\r\n") + 2;
64 - crlf = strstr(cur, "\r\n");
65 + cur = strchr(buf, '\n') + 1;
66 + nl = strnl(cur, &nlsize);
67 while (cur < end) {
68 int i;
69 char *colon = strchr(cur, ':');
70 - if (colon == NULL || colon > crlf)
71 + if (colon == NULL || colon > nl)
72 return 0;
73 snprintf(name, sizeof(name), "%.*s", (int)(colon - cur), cur);
74
75 @@ -165,15 +178,15 @@
76 val_loop:
77 while (isblank(*cur))
78 cur++;
79 - while (cur < crlf) {
80 + while (cur < nl) {
81 if (i < sizeof(value) - 1) {
82 value[i] = *cur;
83 i++;
84 }
85 cur++;
86 }
87 - cur += 2;
88 - crlf = strstr(cur, "\r\n");
89 + cur += nlsize;
90 + nl = strnl(cur, &nlsize);
91 if (isblank(*cur)) {
92 if (i < sizeof(value) - 1) {
93 value[i] = ' ';
94 @@ -222,7 +235,11 @@
95 case PS_HEAD:
96 if (len == 0)
97 goto error;
98 - if ((end = evbuffer_find(req->buf, "\r\n\r\n", 4)) == NULL) {
99 + if ((end = evbuffer_find(req->buf, "\r\n\r\n", 4)) != NULL)
100 + dlen = 4;
101 + else if ((end = evbuffer_find(req->buf, "\n\n", 2)) != NULL)
102 + dlen = 2;
103 + else {
104 if (req->buf->off < (1 << 15))
105 return 1;
106 else
107 @@ -235,7 +252,7 @@
108 goto error;
109 if (req->cancel)
110 goto cancel;
111 - evbuffer_drain(req->buf, end - (char *)req->buf->buffer + 4);
112 + evbuffer_drain(req->buf, end - (char *)req->buf->buffer + dlen);
113 goto again;
114 case PS_CHUNK_SIZE:
115 assert(req->chunked);
|