Commit 4a091bbd authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Bug report #1204435 identified a problem with malformed URLs like

"http://somehost?data" as it added a slash too much in the request ("GET
/?data/"...). Added test case 260 to verify.
parent e99a6b81
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -2382,8 +2382,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
    strcpy(conn->protostr, "file"); /* store protocol string lowercase */
  }
  else {
    /* Set default path */
    strcpy(conn->path, "/");
    /* clear path */
    conn->path[0]=0;

    if (2 > sscanf(data->change.url,
                   "%15[^\n:]://%[^\n/]%[^\n]",
@@ -2444,13 +2444,26 @@ static CURLcode CreateConnection(struct SessionHandle *data,
    tmp = strchr(conn->host.name, '?');

  if(tmp) {
    /* The right part of the ?-letter needs to be moved to prefix
       the current path buffer! */
    size_t len = strlen(tmp);
    /* move the existing path plus the zero byte */
    memmove(conn->path+len+1, conn->path, strlen(conn->path)+1);
    /* We must insert a slash before the '?'-letter in the URL. If the URL had
       a slash after the '?', that is where the path currently begins and the
       '?string' is still part of the host name.

       We must move the trailing part from the host name and put it first in
       the path. And have it all prefixed with a slash.
    */

    size_t hostlen = strlen(tmp);
    size_t pathlen = strlen(conn->path);

    /* move the existing path plus the zero byte forward, to make room for
       the host-name part */
    memmove(conn->path+hostlen+1, conn->path, pathlen+1);

     /* now copy the trailing host part in front of the existing path */
    memcpy(conn->path+1, tmp, hostlen);

    conn->path[0]='/'; /* prepend the missing slash */
    memcpy(conn->path+1, tmp, len); /* now copy the prefix part */

    *tmp=0; /* now cut off the hostname at the ? */
  }

+1 −1
Original line number Diff line number Diff line
@@ -32,4 +32,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
 test231 test232 test228 test229 test233 test234 test235 test236 test520   \
 test237 test238 test239 test243 test245 test246 test247 test248 test249   \
 test250 test251 test252 test253 test254 test255 test521 test522 test523   \
 test256 test257 test258 test259
 test256 test257 test258 test259 test260

tests/data/test260

0 → 100644
+53 −0
Original line number Diff line number Diff line
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>

#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes

<foo>
</data>
</reply>

#
# Client-side
<client>
<server>
http
</server>
 <name>
HTTP GET URL without slash but with questionmark
 </name>
 <command>
"http://%HOSTIP:%HTTPPORT?260"
</command>
</client>

#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /?260 HTTP/1.1
Host: 127.0.0.1:%HTTPPORT
Accept: */*

</protocol>
</verify>
+5 −1
Original line number Diff line number Diff line
@@ -227,6 +227,10 @@ int ProcessRequest(struct httprequest *req)

      ptr++; /* skip the slash */

      /* skip all non-numericals following the slash */
      while(*ptr && !isdigit(*ptr))
        ptr++;

      req->testno = strtol(ptr, &ptr, 10);

      if(req->testno > 10000) {
@@ -247,7 +251,7 @@ int ProcessRequest(struct httprequest *req)
      if(!stream) {
        logmsg("Couldn't open test file %d", req->testno);
        req->open = FALSE; /* closes connection */
        return 0;
        return 1; /* done */
      }
      else {
        char *cmd = NULL;