diff options
| -rw-r--r-- | CHANGES | 39 | ||||
| -rw-r--r-- | RELEASE-NOTES | 9 | ||||
| -rw-r--r-- | lib/file.c | 2 | ||||
| -rw-r--r-- | lib/ftp.c | 6 | ||||
| -rw-r--r-- | lib/http.c | 94 | ||||
| -rw-r--r-- | lib/transfer.c | 21 | ||||
| -rw-r--r-- | lib/url.c | 6 | ||||
| -rw-r--r-- | lib/urldata.h | 4 | ||||
| -rw-r--r-- | tests/data/test154 | 90 | ||||
| -rw-r--r-- | tests/data/test155 | 114 | ||||
| -rw-r--r-- | tests/data/test156 | 79 | ||||
| -rw-r--r-- | tests/data/test157 | 38 | ||||
| -rw-r--r-- | tests/data/test88 | 4 | 
13 files changed, 459 insertions, 47 deletions
| @@ -7,6 +7,45 @@                                    Changelog  Daniel (6 April 2004) +- Gisle Vanem's fixed bug #927979 reported by Nathan O'Sullivan. The problem +  made libcurl on Windows leak a small amount of memory in each name resolve +  when not used as a DLL. + +- New authentication code added, particularly noticable when doing POST or PUT +  with Digest or NTLM. libcurl will now use HEAD to negotiate the +  authentication and when done perform the requested POST. Previously libcurl +  sent POST immediately and expected the server to reply a final status code +  with an error and then libcurl would not send the request-body but instead +  send then next request in the sequence. + +  The reason for this change is due to IIS6 barfing on libcurl when we attempt +  to POST with NTLM authentication. The reason for the problems is found in +  RFC2616 section 8.2.3 regarding how servers should deal with the 100 +  continue request-header: + +        If it responds with a final status code, it MAY close the transport +        connection or it MAY continue to read and discard the rest of the +        request. + +  Previous versions of IIS clearly did close the connection in this case, +  while this newer version decided it should "read and discard". That would've +  forced us to send the whole POST (or PUT) data only to have it discarded and +  then be forced to send it again. To avoid that huge penality, we switch to +  using HEAD until we are authenticated and then send the POST. + +  The only actual drawback I can think of (except for the odd sites that might +  treat HEAD differently than they would treat POST/PUT when given the same +  URL) is that if you do POST with CURLAUTH_ANY set and the site requires NO +  authentication, libcurl will still use a HEAD in a first round and then do a +  POST. + +  If you do a HEAD or a GET on a site using CURLAUTH_ANY, libcurl will send +  an un-authenticated request at once, which then is the only request if the +  site requires no auth. + +  Alan Pinstein helped me work out the protocol details by figuring out why +  libcurl failed and what IIS6 expects. +  - The --limit-rate logic was corrected and now it works a lot better for    higher speeds, such as '10m' or similar. Reported in bug report #930249. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 193fbe1c6..089c5960f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -13,6 +13,9 @@ This release includes the following changes:  This release includes the following bugfixes: + o fixed minor memory leak in libcurl for Windows when staticly linked + o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better + o --limit-rate with high speed rates is a lot more accurate now   o curl_strnqual.3 "refer-to" man page fix   o fixed a minor very old progress meter final update bug   o added checks for a working NI_WITHSCOPEID before that is used @@ -40,8 +43,8 @@ Other curl-related news since the previous public release:  This release would not have looked like this without help, code, reports and  advice from friends like these: - Thomas Schwinge, Marty Kuhrt, Günter Knauf, Kevin Roth, Glen Nakamura, - Gisle Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, - Mitz Wark, Andrés García, Robin Kay + Thomas Schwinge, Marty Kuhrt, Günter Knauf, Kevin Roth, Glen Nakamura, Gisle + Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz + Wark, Andrés García, Robin Kay, Alan Pinstein, David Byron, Nathan O'Sullivan          Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/file.c b/lib/file.c index 72e835272..3977a73e5 100644 --- a/lib/file.c +++ b/lib/file.c @@ -196,7 +196,7 @@ CURLcode Curl_file(struct connectdata *conn)    /* If we have selected NOBODY and HEADER, it means that we only want file       information. Which for FILE can't be much more than the file size and       date. */ -  if(data->set.no_body && data->set.include_header && fstated) { +  if(conn->bits.no_body && data->set.include_header && fstated) {      CURLcode result;      sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); @@ -1838,7 +1838,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)        return result;    } -  else if(!data->set.no_body) { +  else if(!conn->bits.no_body) {      /* Retrieve file or directory */      bool dirlist=FALSE;      curl_off_t downloadsize=-1; @@ -2209,7 +2209,7 @@ CURLcode ftp_perform(struct connectdata *conn,    /* If we have selected NOBODY and HEADER, it means that we only want file       information. Which in FTP can't be much more than the file size and       date. */ -  if(data->set.no_body && data->set.include_header && ftp->file) { +  if(conn->bits.no_body && data->set.include_header && ftp->file) {      /* The SIZE command is _not_ RFC 959 specified, and therefor many servers         may not support it! It is however the only way we have to get a file's         size! */ @@ -2272,7 +2272,7 @@ CURLcode ftp_perform(struct connectdata *conn,      return CURLE_OK;    } -  if(data->set.no_body) +  if(conn->bits.no_body)      /* doesn't really transfer any data */      ftp->no_transfer = TRUE;    /* Get us a second connection up and connected */ diff --git a/lib/http.c b/lib/http.c index 41b1ef7c4..3c2eceff3 100644 --- a/lib/http.c +++ b/lib/http.c @@ -186,6 +186,17 @@ void Curl_http_auth_act(struct connectdata *conn)        conn->newurl = strdup(data->change.url); /* clone URL */      data->state.authavail = CURLAUTH_NONE; /* clear it here */    } +  else if(!data->state.authdone && (data->info.httpcode < 400)) { +    /* no (known) authentication available, +       authentication is not "done" yet and +       no authentication seems to be required and +       we didn't try HEAD or GET */ +    if((data->set.httpreq != HTTPREQ_GET) && +       (data->set.httpreq != HTTPREQ_HEAD)) { +      conn->newurl = strdup(data->change.url); /* clone URL */ +      data->state.authdone = TRUE; +    } +  }  }  /** @@ -204,13 +215,16 @@ static CURLcode http_auth_headers(struct connectdata *conn,    char *auth=NULL;    curlassert(data); -  data->state.authdone = FALSE; /* default is no */    if(!data->state.authstage) { -    if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) +    if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) { +      data->state.authdone = FALSE;        Curl_http_auth_stage(data, 407); -    else if(conn->bits.user_passwd) +    } +    else if(conn->bits.user_passwd) { +      data->state.authdone = FALSE;        Curl_http_auth_stage(data, 401); +    }      else {        data->state.authdone = TRUE;        return CURLE_OK; /* no authentication with no user or password */ @@ -1139,6 +1153,7 @@ CURLcode Curl_http(struct connectdata *conn)    const char *te = ""; /* tranfer-encoding */    char *ptr;    char *request; +  Curl_HttpReq httpreq = data->set.httpreq;    if(!conn->proto.http) {      /* Only allocate this struct if we don't already have it! */ @@ -1157,19 +1172,40 @@ CURLcode Curl_http(struct connectdata *conn)    if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&         data->set.upload) { -    data->set.httpreq = HTTPREQ_PUT; +    httpreq = HTTPREQ_PUT;    } -  request = data->set.customrequest? -    data->set.customrequest: -    (data->set.no_body?(char *)"HEAD": -     ((HTTPREQ_POST == data->set.httpreq) || -      (HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST": -     (HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET"); +  /* Now set the 'request' pointer to the proper request string */ +  if(data->set.customrequest) +    request = data->set.customrequest; +  else { +    if(conn->bits.no_body) +      request = (char *)"HEAD"; +    else { +      curlassert((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); +      switch(httpreq) { +      case HTTPREQ_POST: +      case HTTPREQ_POST_FORM: +        request = (char *)"POST"; +        break; +      case HTTPREQ_PUT: +        request = (char *)"PUT"; +        break; +      case HTTPREQ_GET: +        request = (char *)"GET"; +        break; +      case HTTPREQ_HEAD: +        request = (char *)"HEAD"; +        break; +      default: /* this should never happen */ +        break; +      } +    } +  } -  /* The User-Agent string has been built in url.c already, because it might -     have been used in the proxy connect, but if we have got a header with -     the user-agent string specified, we erase the previously made string +  /* The User-Agent string might have been allocated in url.c already, because +     it might have been used in the proxy connect, but if we have got a header +     with the user-agent string specified, we erase the previously made string       here. */    if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {      free(conn->allocptr.uagent); @@ -1181,6 +1217,16 @@ CURLcode Curl_http(struct connectdata *conn)    if(result)      return result; +  if(!data->state.authdone && (httpreq != HTTPREQ_GET)) { +    /* Until we are authenticated, we switch over to HEAD. Unless its a GET +       we want to do. The explanation for this is rather long and boring, but +       the point is that it can't be done otherwise without risking having to +       send the POST or PUT data multiple times. */ +    httpreq = HTTPREQ_HEAD; +    request = (char *)"HEAD"; +    conn->bits.no_body = TRUE; +  } +    Curl_safefree(conn->allocptr.ref);    if(data->change.referer && !checkheaders(data, "Referer:"))      conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer); @@ -1193,7 +1239,7 @@ CURLcode Curl_http(struct connectdata *conn)    else      conn->allocptr.cookie = NULL; -  if(!conn->bits.upload_chunky && (data->set.httpreq != HTTPREQ_GET)) { +  if(!conn->bits.upload_chunky && (httpreq != HTTPREQ_GET)) {      /* not a chunky transfer yet, but data is to be sent */      ptr = checkheaders(data, "Transfer-Encoding:");      if(ptr) { @@ -1284,7 +1330,7 @@ CURLcode Curl_http(struct connectdata *conn)      /* The path sent to the proxy is in fact the entire URL */      ppath = data->change.url;    } -  if(HTTPREQ_POST_FORM == data->set.httpreq) { +  if(HTTPREQ_POST_FORM == httpreq) {      /* we must build the whole darned post sequence first, so that we have         a size of the whole shebang before we start to send it */       result = Curl_getFormData(&http->sendit, data->set.httppost, @@ -1303,9 +1349,9 @@ CURLcode Curl_http(struct connectdata *conn)    if(!checkheaders(data, "Accept:"))      http->p_accept = "Accept: */*\r\n"; -  if(( (HTTPREQ_POST == data->set.httpreq) || -       (HTTPREQ_POST_FORM == data->set.httpreq) || -       (HTTPREQ_PUT == data->set.httpreq) ) && +  if(( (HTTPREQ_POST == httpreq) || +       (HTTPREQ_POST_FORM == httpreq) || +       (HTTPREQ_PUT == httpreq) ) &&       conn->resume_from) {      /**********************************************************************       * Resuming upload in HTTP means that we PUT or POST and that we have @@ -1368,14 +1414,14 @@ CURLcode Curl_http(struct connectdata *conn)       * or uploading and we always let customized headers override our internal       * ones if any such are specified.       */ -    if((data->set.httpreq == HTTPREQ_GET) && +    if((httpreq == HTTPREQ_GET) &&         !checkheaders(data, "Range:")) {        /* if a line like this was already allocated, free the previous one */        if(conn->allocptr.rangeline)          free(conn->allocptr.rangeline);        conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);      } -    else if((data->set.httpreq != HTTPREQ_GET) && +    else if((httpreq != HTTPREQ_GET) &&              !checkheaders(data, "Content-Range:")) {        if(conn->resume_from) { @@ -1538,11 +1584,11 @@ CURLcode Curl_http(struct connectdata *conn)      http->postdata = NULL;  /* nothing to post at this point */      Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */ -    /* If 'authdone' is still FALSE, we must not set the write socket index to -       the Curl_transfer() call below, as we're not ready to actually upload -       any data yet. */ +    /* If 'authdone' is FALSE, we must not set the write socket index to the +       Curl_transfer() call below, as we're not ready to actually upload any +       data yet. */ -    switch(data->set.httpreq) { +    switch(httpreq) {      case HTTPREQ_POST_FORM:        if(Curl_FormInit(&http->form, http->sendit)) { diff --git a/lib/transfer.c b/lib/transfer.c index 4e5d71137..82c367978 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -498,7 +498,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,                   * If we requested a "no body", this is a good time to get                   * out and return home.                   */ -                if(data->set.no_body) +                if(conn->bits.no_body)                    stop_reading = TRUE;                  else {                    /* If we know the expected size of this document, we set the @@ -555,10 +555,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,                /* This is the first header, it MUST be the error code line                   or else we consiser this to be the body right away! */                int httpversion_major; -              int nc=sscanf (k->p, " HTTP/%d.%d %3d", -                             &httpversion_major, -                             &k->httpversion, -                             &k->httpcode); +              int nc=sscanf(k->p, " HTTP/%d.%d %3d", +                            &httpversion_major, +                            &k->httpversion, +                            &k->httpcode);                if (nc==3) {                  k->httpversion += 10 * httpversion_major;                } @@ -566,7 +566,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,                  /* this is the real world, not a Nirvana                     NCSA 1.5.x returns this crap when asked for HTTP/1.1                  */ -                nc=sscanf (k->p, " HTTP %3d", &k->httpcode); +                nc=sscanf(k->p, " HTTP %3d", &k->httpcode);                  k->httpversion = 10;                 /* If user has set option HTTP200ALIASES, @@ -1274,7 +1274,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,       * returning.       */ -    if(!(data->set.no_body) && (conn->size != -1) && +    if(!(conn->bits.no_body) && (conn->size != -1) &&         (k->bytecount != conn->size) &&         !conn->newurl) {        failf(data, "transfer closed with %" FORMAT_OFF_T @@ -1331,7 +1331,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)        Curl_pgrsSetDownloadSize(data, conn->size);    }    /* we want header and/or body, if neither then don't do this! */ -  if(conn->bits.getheader || !data->set.no_body) { +  if(conn->bits.getheader || !conn->bits.no_body) {      FD_ZERO (&k->readfd);               /* clear it */      if(conn->sockfd != CURL_SOCKET_BAD) { @@ -1420,7 +1420,6 @@ void Curl_single_fdset(struct connectdata *conn,  static CURLcode  Transfer(struct connectdata *conn)  { -  struct SessionHandle *data = conn->data;    CURLcode result;    struct Curl_transfer_keeper *k = &conn->keep;    bool done=FALSE; @@ -1435,7 +1434,7 @@ Transfer(struct connectdata *conn)      return CURLE_OK;    /* we want header and/or body, if neither then don't do this! */ -  if(!conn->bits.getheader && data->set.no_body) +  if(!conn->bits.getheader && conn->bits.no_body)      return CURLE_OK;    k->writefdp = &k->writefd; /* store the address of the set */ @@ -1859,7 +1858,7 @@ CURLcode Curl_follow(struct SessionHandle *data,      if(data->set.httpreq != HTTPREQ_GET) {        data->set.httpreq = HTTPREQ_GET; /* enforce GET request */        infof(data, "Disables POST, goes with %s\n", -            data->set.no_body?"HEAD":"GET"); +            data->set.opt_no_body?"HEAD":"GET");      }      break;    case 304: /* Not Modified */ @@ -463,7 +463,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)      /*       * Do not include the body part in the output data stream.       */ -    data->set.no_body = va_arg(param, long)?TRUE:FALSE; +    data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;      break;    case CURLOPT_FAILONERROR:      /* @@ -2066,6 +2066,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,    conn->bits.user_passwd = data->set.userpwd?1:0;    conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; +  conn->bits.no_body = data->set.opt_no_body;    /* This initing continues below, see the comment "Continue connectdata     * initialization here" */ @@ -2924,6 +2925,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,      conn->bits.user_passwd = old_conn->bits.user_passwd;      conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; +    /* get the newly set value, not the old one */ +    conn->bits.no_body = old_conn->bits.no_body; +      /* If we speak over a proxy, we need to copy the host name too, as it         might be another remote host even when re-using a connection */      strcpy(conn->gname, old_conn->gname); /* safe strcpy() */ diff --git a/lib/urldata.h b/lib/urldata.h index 196c45f16..4ed66243d 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -302,6 +302,7 @@ struct ConnectBits {                           call */    bool retry;         /* this connection is about to get closed and then                           re-attempted at another connection. */ +  bool no_body;       /* CURLOPT_NO_BODY (or similar) was set */  };  /* @@ -644,6 +645,7 @@ typedef enum {    HTTPREQ_POST,    HTTPREQ_POST_FORM, /* we make a difference internally */    HTTPREQ_PUT, +  HTTPREQ_HEAD,    HTTPREQ_CUSTOM,    HTTPREQ_LAST /* last in list */  } Curl_HttpReq; @@ -866,7 +868,7 @@ struct UserDefined {    bool http_set_referer;    bool http_auto_referer; /* set "correct" referer when following location: */ -  bool no_body; +  bool opt_no_body;      /* as set with CURLOPT_NO_BODY */    bool set_port;    bool upload;    enum CURL_NETRC_OPTION diff --git a/tests/data/test154 b/tests/data/test154 new file mode 100644 index 000000000..e9321a308 --- /dev/null +++ b/tests/data/test154 @@ -0,0 +1,90 @@ +# Server-side +<reply> +<servercmd> +auth_required +</servercmd> +<data> +HTTP/1.1 401 Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +WWW-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Basic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Digest realm="gimme all yer s3cr3ts", nonce="11223344"
 +Content-Type: text/html; charset=iso-8859-1
 +
 +This is not the real page +</data> + +# This is supposed to be returned when the server gets a +# Authorization: Digest line passed-in from the client +<data1000> +HTTP/1.1 200 OK swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Content-Length: 23
 +
 +This IS the real page! +</data1000> + +<datacheck> +HTTP/1.1 401 Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +WWW-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Basic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Digest realm="gimme all yer s3cr3ts", nonce="11223344"
 +Content-Type: text/html; charset=iso-8859-1
 +
 +HTTP/1.1 200 OK swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Content-Length: 23
 +
 +This IS the real page! +</datacheck> + +</reply> + +# Client-side +<client> +<server> +http +</server> + <name> +HTTP PUT with --anyauth authorization (picking Digest) + </name> + <command> +http://%HOSTIP:%HOSTPORT/154 -T log/put154 -u testuser:testpass --anyauth +</command> +<file name="log/put154"> +This is data we upload with PUT +a second line +line three +four is the number of lines +</file> +</client> + +# Verify data after the test has been "shot" +<verify> +<strip> +^User-Agent:.* +</strip> +<protocol> +HEAD /154 HTTP/1.1
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +
 +PUT /154 HTTP/1.1
 +Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/154", response="b71551e12d1c456e47d8388ecb2edeca"
 +User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +Content-Length: 85
 +Expect: 100-continue
 +
 +This is data we upload with PUT +a second line +line three +four is the number of lines +</protocol> +</verify> diff --git a/tests/data/test155 b/tests/data/test155 new file mode 100644 index 000000000..720ca29be --- /dev/null +++ b/tests/data/test155 @@ -0,0 +1,114 @@ +# Server-side +<reply> +<servercmd> +auth_required +</servercmd> +<data> +HTTP/1.1 401 NTLM Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +WWW-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Basic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: NTLM
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +moo +</data> + +# This is supposed to be returned when the server gets a first +# Authorization: NTLM line passed-in from the client +<data1001> +HTTP/1.1 401 Type-1 received, send back type-2
 +Server: Microsoft-IIS/5.0
 +Content-Length: 34
 +Content-Type: text/html; charset=iso-8859-1
 +WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
 +
 +This is not the real page either! +</data1001> + +# This is supposed to be returned when the server gets the second +# Authorization: NTLM line passed-in from the client +<data1002> +HTTP/1.1 200 Type-3 Recevied and all Things are fine swsclose
 +Server: Microsoft-IIS/5.0
 +Content-Type: text/html; charset=iso-8859-1
 +
 +Finally, this is the real page! +</data1002> + +<datacheck> +HTTP/1.1 401 NTLM Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +WWW-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: Basic realm="gimme all yer s3cr3ts"
 +WWW-Authenticate: NTLM
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +HTTP/1.1 401 Type-1 received, send back type-2
 +Server: Microsoft-IIS/5.0
 +Content-Length: 34
 +Content-Type: text/html; charset=iso-8859-1
 +WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
 +
 +HTTP/1.1 200 Type-3 Recevied and all Things are fine swsclose
 +Server: Microsoft-IIS/5.0
 +Content-Type: text/html; charset=iso-8859-1
 + +Finally, this is the real page!
 +</datacheck> + +</reply> + +# Client-side +<client> +<server> +http +</server> + <name> +HTTP PUT with --anyauth authorization (picking NTLM) + </name> + <command> +http://%HOSTIP:%HOSTPORT/155 -T log/put155 -u testuser:testpass --anyauth +</command> +<file name="log/put155"> +This is data we upload with PUT +a second line +line three +four is the number of lines +</file> +</client> + +# Verify data after the test has been "shot" +<verify> +<strip> +^User-Agent:.* +</strip> +<protocol> +HEAD /155 HTTP/1.1
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +
 +HEAD /155 HTTP/1.1
 +Authorization: NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +
 +PUT /155 HTTP/1.1
 +Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEgAAAAYABgAYAAAAAAAAABAAAAACAAIAEAAAAAAAAAASAAAAAAAAAB4AAAAAYIAAHRlc3R1c2VyWmRDApEJkUyGOPS3DjvASModEeW/N/FBqYVyF4y6/y/7F6qmEQ7lXjXFF3tH1145
 +User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +Content-Length: 85
 +Expect: 100-continue
 +
 +This is data we upload with PUT +a second line +line three +four is the number of lines +</protocol> +</verify> diff --git a/tests/data/test156 b/tests/data/test156 new file mode 100644 index 000000000..94ac0ed98 --- /dev/null +++ b/tests/data/test156 @@ -0,0 +1,79 @@ +# Server-side +<reply> +<data> +HTTP/1.1 200 No Authorization Required swsclose swsbounce
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +</data> + +<data1> +HTTP/1.1 200 No Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +PUT received fine. Thank you very much +</data1> + +<datacheck> +HTTP/1.1 200 No Authorization Required swsclose swsbounce
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +HTTP/1.1 200 No Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +PUT received fine. Thank you very much +</datacheck> + +</reply> + +# Client-side +<client> +<server> +http +</server> + <name> +HTTP PUT with --anyauth (when the server requires none) + </name> + <command> +http://%HOSTIP:%HOSTPORT/156 -T log/put156 -u testuser:testpass --anyauth +</command> +<file name="log/put156"> +This is data we upload with PUT +a second line +line three +four is the number of lines +</file> +</client> + +# Verify data after the test has been "shot" +<verify> +<strip> +^User-Agent:.* +</strip> +<protocol> +HEAD /156 HTTP/1.1
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +
 +PUT /156 HTTP/1.1
 +User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +Content-Length: 85
 +Expect: 100-continue
 +
 +This is data we upload with PUT +a second line +line three +four is the number of lines +</protocol> +</verify> diff --git a/tests/data/test157 b/tests/data/test157 new file mode 100644 index 000000000..3f6ed3691 --- /dev/null +++ b/tests/data/test157 @@ -0,0 +1,38 @@ +# Server-side +<reply> +<data> +HTTP/1.1 200 No Authorization Required swsclose
 +Server: Apache/1.3.27 (Darwin) PHP/4.1.2
 +Content-Type: text/html; charset=iso-8859-1
 +Connection: close
 +
 +GET received and served just fine. Thank you very much +</data> +</reply> + +# Client-side +<client> +<server> +http +</server> + <name> +HTTP GET with --anyauth (when the server requires none) + </name> + <command> +http://%HOSTIP:%HOSTPORT/157 -u testuser:testpass --anyauth +</command> +</client> + +# Verify data after the test has been "shot" +<verify> +<strip> +^User-Agent:.* +</strip> +<protocol> +GET /157 HTTP/1.1
 +Host: 127.0.0.1:8999
 +Pragma: no-cache
 +Accept: */*
 +
 +</protocol> +</verify> diff --git a/tests/data/test88 b/tests/data/test88 index 401de7ba0..f1caba4bc 100644 --- a/tests/data/test88 +++ b/tests/data/test88 @@ -62,12 +62,10 @@ four is the number of lines  ^User-Agent:.*  </strip>  <protocol> -PUT /88 HTTP/1.1
 +HEAD /88 HTTP/1.1
  Host: 127.0.0.1:8999
  Pragma: no-cache
  Accept: */*
 -Content-Length: 85
 -Expect: 100-continue
  PUT /88 HTTP/1.1
  Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/88", response="78a49fa53d0c228778297687d4168e71"
 | 
