From 428c1a2b3cb4a0a3d1d9f08e85498db3951925f3 Mon Sep 17 00:00:00 2001 From: hniksic Date: Tue, 26 Apr 2005 06:34:33 -0700 Subject: [PATCH] [svn] Fix various cookie-related problems. --- src/ChangeLog | 15 +++++++++++++++ src/cookies.c | 15 ++++++++++++++- src/http.c | 43 +++++++++++++++++++++++++++++++------------ src/main.c | 2 +- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 883a41af..9ae9dee7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2005-04-26 Hrvoje Niksic + + * cookies.c (cookie_handle_set_cookie): Delete the part of the + path after the trailing slash. + + * http.c (gethttp): Call cookie_handle_set_cookie with path that + begins with '/'. + +2005-04-26 Hrvoje Niksic + + * http.c (gethttp): Call skip_short_body only if keep_alive is in + use. + (gethttp): Send the User-Agent header with the CONNECT request as + well. + 2005-04-25 Hrvoje Niksic * main.c (option_data): Removed support for the undocumented flag diff --git a/src/cookies.c b/src/cookies.c index d0d9e610..45d45159 100644 --- a/src/cookies.c +++ b/src/cookies.c @@ -870,9 +870,19 @@ cookie_handle_set_cookie (struct cookie_jar *jar, } if (!cookie->path) - cookie->path = xstrdup (path); + { + /* The cookie doesn't set path: set it to the URL path, sans the + file part ("/dir/file" truncated to "/dir/"). */ + char *trailing_slash = strrchr (path, '/'); + if (trailing_slash) + cookie->path = strdupdelim (path, trailing_slash + 1); + else + /* no slash in the string -- can this even happen? */ + cookie->path = xstrdup (path); + } else { + /* The cookie sets its own path; verify that it is legal. */ if (!check_path_match (cookie->path, path)) { DEBUGP (("Attempt to fake the path: %s, %s\n", @@ -881,6 +891,9 @@ cookie_handle_set_cookie (struct cookie_jar *jar, } } + /* Now store the cookie, or discard an existing cookie, if + discarding was requested. */ + if (cookie->discard_requested) { discard_matching_cookie (jar, cookie); diff --git a/src/http.c b/src/http.c index 6a5cf1f9..77861d89 100644 --- a/src/http.c +++ b/src/http.c @@ -1113,6 +1113,14 @@ time_t http_atotm PARAMS ((const char *)); && (ISSPACE (line[sizeof (string_constant) - 1]) \ || !line[sizeof (string_constant) - 1])) +#define SET_USER_AGENT(req) \ + if (opt.useragent) \ + request_set_header (req, "User-Agent", opt.useragent, rel_none); \ + else \ + request_set_header (req, "User-Agent", \ + aprintf ("Wget/%s", version_string), rel_value); + + /* Retrieve a document through HTTP protocol. It recognizes status code, and correctly handles redirections. It closes the network socket. If it receives an error from the functions below it, it @@ -1245,11 +1253,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) aprintf ("bytes=%s-", number_to_static_string (hs->restval)), rel_value); - if (opt.useragent) - request_set_header (req, "User-Agent", opt.useragent, rel_none); - else - request_set_header (req, "User-Agent", - aprintf ("Wget/%s", version_string), rel_value); + SET_USER_AGENT (req); request_set_header (req, "Accept", "*/*", rel_none); /* Find the username and password for authentication. */ @@ -1455,6 +1459,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) struct request *connreq = request_new (); request_set_method (connreq, "CONNECT", aprintf ("%s:%d", u->host, u->port)); + SET_USER_AGENT (req); if (proxyauth) { request_set_header (connreq, "Proxy-Authorization", @@ -1464,6 +1469,10 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) the regular request below. */ proxyauth = NULL; } + /* Examples in rfc2817 use the Host header in CONNECT + requests. I don't see how that gains anything, given + that the contents of Host would be exactly the same as + the contents of CONNECT. */ write_error = request_send (connreq, sock); request_free (connreq); @@ -1622,10 +1631,13 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) if (statcode == HTTP_STATUS_UNAUTHORIZED) { /* Authorization is required. */ - if (skip_short_body (sock, contlen)) - CLOSE_FINISH (sock); - else - CLOSE_INVALIDATE (sock); + if (keep_alive) + { + if (skip_short_body (sock, contlen)) + CLOSE_FINISH (sock); + else + CLOSE_INVALIDATE (sock); + } pconn.authorized = 0; if (auth_finished || !(user && passwd)) { @@ -1714,6 +1726,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) /* Handle (possibly multiple instances of) the Set-Cookie header. */ { + char *pth = NULL; int scpos; const char *scbeg, *scend; /* The jar should have been created by now. */ @@ -1723,10 +1736,16 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) &scbeg, &scend)) != -1; ++scpos) { - char *set_cookie = strdupdelim (scbeg, scend); - cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, u->path, + char *set_cookie; BOUNDED_TO_ALLOCA (scbeg, scend, set_cookie); + if (pth == NULL) + { + /* u->path doesn't begin with /, which cookies.c expects. */ + pth = (char *) alloca (1 + strlen (u->path) + 1); + pth[0] = '/'; + strcpy (pth + 1, u->path); + } + cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, pth, set_cookie); - xfree (set_cookie); } } diff --git a/src/main.c b/src/main.c index fcbe53a5..e340dc83 100644 --- a/src/main.c +++ b/src/main.c @@ -245,7 +245,7 @@ struct cmdline_option option_data[] = { IF_SSL ("sslcertkey"), 0, OPT_VALUE, "sslcertkey", -1 }, { IF_SSL ("sslcerttype"), 0, OPT_VALUE, "sslcerttype", -1 }, { IF_SSL ("sslcheckcert"), 0, OPT_VALUE, "sslcheckcert", -1 }, - { IF_SSL ("sslprotocol"), 0, OPT_VALUE, "sslprotocol", -1 }, + { IF_SSL ("secure-protocol"), 0, OPT_VALUE, "secureprotocol", -1 }, { "strict-comments", 0, OPT_BOOLEAN, "strictcomments", -1 }, { "timeout", 'T', OPT_VALUE, "timeout", -1 }, { "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 },