X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fhttp.c;h=9f274dc618abc8c65acbfe2e001206acf7ff7c54;hp=25ad4740f8c35f2419a77d2e2648550162879ce0;hb=e9cc8b2f7c4678b832ad56f7119bba86a8db08ef;hpb=54fd8de415cd31e015cf3a391818d3c83fce21c6 diff --git a/src/http.c b/src/http.c index 25ad4740..9f274dc6 100644 --- a/src/http.c +++ b/src/http.c @@ -147,27 +147,20 @@ struct request { extern int numurls; -/* Create a new, empty request. At least request_set_method must be - called before the request can be used. */ +/* Create a new, empty request. Set the request's method and its + arguments. METHOD should be a literal string (or it should outlive + the request) because it will not be freed. ARG will be freed by + request_free. */ static struct request * -request_new (void) +request_new (const char *method, char *arg) { struct request *req = xnew0 (struct request); req->hcapacity = 8; req->headers = xnew_array (struct request_header, req->hcapacity); - return req; -} - -/* Set the request's method and its arguments. METH should be a - literal string (or it should outlive the request) because it will - not be freed. ARG will be freed by request_free. */ - -static void -request_set_method (struct request *req, const char *meth, char *arg) -{ - req->method = meth; + req->method = method; req->arg = arg; + return req; } /* Return the method string passed with the last call to @@ -1758,20 +1751,13 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy, conn = u; /* Prepare the request to send. */ - - req = request_new (); { char *meth_arg; const char *meth = "GET"; if (head_only) meth = "HEAD"; else if (opt.method) - { - char *q; - for (q = opt.method; *q; ++q) - *q = c_toupper (*q); - meth = opt.method; - } + meth = opt.method; /* Use the full path, i.e. one that includes the leading slash and the query string. E.g. if u->path is "foo/bar" and u->query is "param=value", full_path will be "/foo/bar?param=value". */ @@ -1786,7 +1772,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy, meth_arg = xstrdup (u->url); else meth_arg = url_full_path (u); - request_set_method (req, meth, meth_arg); + req = request_new (meth, meth_arg); } request_set_header (req, "Referer", (char *) hs->referer, rel_none); @@ -1997,6 +1983,10 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy, exec_name, quote (relevant->host)); return HOSTERR; } + else if (sock != -1) + { + sock = -1; + } } if (sock < 0) @@ -2019,8 +2009,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy, { /* When requesting SSL URLs through proxies, use the CONNECT method to request passthrough. */ - struct request *connreq = request_new (); - request_set_method (connreq, "CONNECT", + struct request *connreq = request_new ("CONNECT", aprintf ("%s:%d", u->host, u->port)); SET_USER_AGENT (connreq); if (proxyauth) @@ -2656,12 +2645,35 @@ read_header: /* From RFC2616: The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client. - + A 307 should be redirected using the same method, in other words, a POST should be preserved and not - converted to a GET in that case. */ - if (statcode == HTTP_STATUS_TEMPORARY_REDIRECT) - return NEWLOCATION_KEEP_POST; + converted to a GET in that case. + + With strict adherence to RFC2616, POST requests are not + converted to a GET request on 301 Permanent Redirect + or 302 Temporary Redirect. + + A switch may be provided later based on the HTTPbis draft + that allows clients to convert POST requests to GET + requests on 301 and 302 response codes. */ + switch (statcode) + { + case HTTP_STATUS_TEMPORARY_REDIRECT: + return NEWLOCATION_KEEP_POST; + break; + case HTTP_STATUS_MOVED_PERMANENTLY: + if (opt.method && strcasecmp (opt.method, "post") != 0) + return NEWLOCATION_KEEP_POST; + break; + case HTTP_STATUS_MOVED_TEMPORARILY: + if (opt.method && strcasecmp (opt.method, "post") != 0) + return NEWLOCATION_KEEP_POST; + break; + default: + return NEWLOCATION; + break; + } return NEWLOCATION; } } @@ -3691,7 +3703,8 @@ digest_authentication_encode (const char *au, const char *user, param_token name, value; - realm = opaque = nonce = qop = algorithm = NULL; + realm = opaque = nonce = qop = NULL; + algorithm = "MD5"; au += 6; /* skip over `Digest' */ while (extract_param (&au, &name, &value, ',')) @@ -3773,7 +3786,7 @@ digest_authentication_encode (const char *au, const char *user, md5_finish_ctx (&ctx, hash); dump_hash (a2buf, hash); - if (!strcmp(qop, "auth") || !strcmp (qop, "auth-int")) + if (qop && (!strcmp(qop, "auth") || !strcmp (qop, "auth-int"))) { /* RFC 2617 Digest Access Authentication */ /* generate random hex string */ @@ -3823,7 +3836,7 @@ digest_authentication_encode (const char *au, const char *user, res = xmalloc (res_size); - if (!strcmp(qop,"auth")) + if (qop && !strcmp (qop, "auth")) { res_len = snprintf (res, res_size, "Digest "\ "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""\