write_error = fd_write (fd, request_string, size - 1, -1);
if (write_error < 0)
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
- strerror (errno));
+ fd_errstr (fd));
return write_error;
}
/* Don't normally report the error since this is an
optimization that should be invisible to the user. */
DEBUGP (("] aborting (%s).\n",
- ret < 0 ? strerror (errno) : "EOF received"));
+ ret < 0 ? fd_errstr (fd) : "EOF received"));
return false;
}
contlen -= ret;
}
/* Finally, check whether the connection is still open. This is
- important because most server implement a liberal (short) timeout
+ important because most servers implement liberal (short) timeout
on persistent connections. Wget can of course always reconnect
if the connection doesn't work out, but it's nicer to know in
advance. This test is a logical followup of the first test, but
- is "expensive" and therefore placed at the end of the list. */
+ is "expensive" and therefore placed at the end of the list.
+
+ (Current implementation of test_socket_open has a nice side
+ effect that it treats sockets with pending data as "closed".
+ This is exactly what we want: if a broken server sends message
+ body in response to HEAD, or if it sends more than conent-length
+ data, we won't reuse the corrupted connection.) */
if (!test_socket_open (pconn.socket))
{
wgint contlen; /* expected length */
wgint restval; /* the restart value */
int res; /* the result of last read */
+ char *rderrmsg; /* error message from read error */
char *newloc; /* new location (redirection) */
char *remote_time; /* remote time-stamp string */
char *error; /* textual HTTP error */
xfree_null (hs->newloc);
xfree_null (hs->remote_time);
xfree_null (hs->error);
+ xfree_null (hs->rderrmsg);
/* Guard against being called twice. */
hs->newloc = NULL;
hs->len = 0;
hs->contlen = -1;
hs->res = -1;
+ hs->rderrmsg = NULL;
hs->newloc = NULL;
hs->remote_time = NULL;
hs->error = NULL;
request_free (connreq);
if (write_error < 0)
{
- logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
- strerror (errno));
CLOSE_INVALIDATE (sock);
return WRITEFAILED;
}
if (!head)
{
logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
- strerror (errno));
+ fd_errstr (sock));
CLOSE_INVALIDATE (sock);
return HERR;
}
if (write_error < 0)
{
- logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
- strerror (errno));
CLOSE_INVALIDATE (sock);
request_free (req);
return WRITEFAILED;
else
{
logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
- strerror (errno));
+ fd_errstr (sock));
CLOSE_INVALIDATE (sock);
request_free (req);
return HERR;
hs->error = xstrdup (_("(no description)"));
else
hs->error = xstrdup (message);
- xfree (message);
+ xfree_null (message);
type = resp_header_strdup (resp, "Content-Type");
if (type)
xfree_null (type);
if (head_only)
/* Pre-1.10 Wget used CLOSE_INVALIDATE here. Now we trust the
- servers not to send body in response to a HEAD request. If
- you encounter such a server (more likely a broken CGI), use
+ servers not to send body in response to a HEAD request, and
+ those that do will likely be caught by test_socket_open.
+ If not, they can be worked around using
`--no-http-keep-alive'. */
CLOSE_FINISH (sock);
else if (keep_alive && skip_short_body (sock, contlen))
/* Download the request body. */
flags = 0;
- if (keep_alive)
+ if (contlen != -1)
+ /* If content-length is present, read that much; otherwise, read
+ until EOF. The HTTP spec doesn't require the server to
+ actually close the connection when it's done sending data. */
flags |= rb_read_exactly;
if (hs->restval > 0 && contrange == 0)
/* If the server ignored our range request, instruct fd_read_body
if (hs->res >= 0)
CLOSE_FINISH (sock);
else
- CLOSE_INVALIDATE (sock);
+ {
+ if (hs->res < 0)
+ hs->rderrmsg = xstrdup (fd_errstr (sock));
+ CLOSE_INVALIDATE (sock);
+ }
- {
- /* Close or flush the file. We have to be careful to check for
- error here. Checking the result of fwrite() is not enough --
- errors could go unnoticed! */
- int flush_res;
- if (!output_stream)
- flush_res = fclose (fp);
- else
- flush_res = fflush (fp);
- if (flush_res == EOF)
- hs->res = -2;
- }
+ if (!output_stream)
+ fclose (fp);
if (hs->res == -2)
return FWRITEERR;
return RETRFINISHED;
if ((tmr != (time_t) (-1))
&& !opt.spider
&& ((hstat.len == hstat.contlen) ||
- ((hstat.res == 0) &&
- ((hstat.contlen == -1) ||
- (hstat.len >= hstat.contlen && !opt.kill_longer)))))
+ ((hstat.res == 0) && (hstat.contlen == -1))))
{
/* #### This code repeats in http.c and ftp.c. Move it to a
function! */
free_hstat (&hstat);
continue;
}
- else if (!opt.kill_longer) /* meaning we got more than expected */
- {
- logprintf (LOG_VERBOSE,
- _("%s (%s) - `%s' saved [%s/%s]\n\n"),
- tms, tmrate, locf,
- number_to_static_string (hstat.len),
- number_to_static_string (hstat.contlen));
- logprintf (LOG_NONVERBOSE,
- "%s URL:%s [%s/%s] -> \"%s\" [%d]\n",
- tms, u->url,
- number_to_static_string (hstat.len),
- number_to_static_string (hstat.contlen),
- locf, count);
- ++opt.numurls;
- total_downloaded_bytes += hstat.len;
-
- /* Remember that we downloaded the file for later ".orig" code. */
- if (*dt & ADDED_HTML_EXTENSION)
- downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
- else
- downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
-
- free_hstat (&hstat);
- xfree_null (dummy);
- return RETROK;
- }
- else /* the same, but not accepted */
- {
- logprintf (LOG_VERBOSE,
- _("%s (%s) - Connection closed at byte %s/%s. "),
- tms, tmrate,
- number_to_static_string (hstat.len),
- number_to_static_string (hstat.contlen));
- printwhat (count, opt.ntry);
- free_hstat (&hstat);
- continue;
- }
+ else
+ /* Getting here would mean reading more data than
+ requested with content-length, which we never do. */
+ abort ();
}
else /* now hstat.res can only be -1 */
{
logprintf (LOG_VERBOSE,
_("%s (%s) - Read error at byte %s (%s)."),
tms, tmrate, number_to_static_string (hstat.len),
- strerror (errno));
+ hstat.rderrmsg);
printwhat (count, opt.ntry);
free_hstat (&hstat);
continue;
tms, tmrate,
number_to_static_string (hstat.len),
number_to_static_string (hstat.contlen),
- strerror (errno));
+ hstat.rderrmsg);
printwhat (count, opt.ntry);
free_hstat (&hstat);
continue;