summaryrefslogtreecommitdiff
path: root/btpd/btpd-0.13.patch
blob: 21c2f32115f20cb408289faa92a1c776b621d519 (plain)
    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);

Generated by cgit