]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Support human-readable file size printing.
[wget] / src / http.c
index 646a031e4e7c9ad4d164de321dd1597dd6ccc415..85d73404a315cd3ca13336c22eb159ef628ac273 100644 (file)
@@ -84,7 +84,7 @@ extern int output_stream_regular;
 
 \f
 static int cookies_loaded_p;
-struct cookie_jar *wget_cookie_jar;
+static struct cookie_jar *wget_cookie_jar;
 
 #define TEXTHTML_S "text/html"
 #define TEXTXHTML_S "application/xhtml+xml"
@@ -432,6 +432,13 @@ response_head_terminator (const char *hunk, int oldlen, int peeklen)
   return NULL;
 }
 
+/* The maximum size of a single HTTP response we care to read.  This
+   is not meant to impose an arbitrary limit, but to protect the user
+   from Wget slurping up available memory upon encountering malicious
+   or buggy server output.  Define it to 0 to remove the limit.  */
+
+#define HTTP_RESPONSE_MAX_SIZE 65536
+
 /* Read the HTTP request head from FD and return it.  The error
    conditions are the same as with fd_read_hunk.
 
@@ -443,7 +450,8 @@ response_head_terminator (const char *hunk, int oldlen, int peeklen)
 static char *
 read_http_response_head (int fd)
 {
-  return fd_read_hunk (fd, response_head_terminator, 512);
+  return fd_read_hunk (fd, response_head_terminator, 512,
+                      HTTP_RESPONSE_MAX_SIZE);
 }
 
 struct response {
@@ -1081,8 +1089,15 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
      is done. */
   int keep_alive;
 
-  /* Whether keep-alive should be inhibited. */
-  int inhibit_keep_alive = !opt.http_keep_alive || opt.ignore_length;
+  /* Whether keep-alive should be inhibited.
+
+     RFC 2068 requests that 1.0 clients not send keep-alive requests
+     to proxies.  This is because many 1.0 proxies do not interpret
+     the Connection header and transfer it to the remote server,
+     causing it to not close the connection and leave both the proxy
+     and the client hanging.  */
+  int inhibit_keep_alive =
+    !opt.http_keep_alive || opt.ignore_length /*|| proxy != NULL*/;
 
   /* Headers sent when using POST. */
   wgint post_data_size = 0;
@@ -1341,14 +1356,23 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
         look up conn->host in some cases.  If that lookup failed, we
         don't need to bother with connect_to_host.  */
       if (host_lookup_failed)
-       return HOSTERR;
+       {
+         request_free (req);
+         return HOSTERR;
+       }
 
       sock = connect_to_host (conn->host, conn->port);
       if (sock == E_HOST)
-       return HOSTERR;
+       {
+         request_free (req);
+         return HOSTERR;
+       }
       else if (sock < 0)
-       return (retryable_socket_connect_error (errno)
-               ? CONERROR : CONIMPOSSIBLE);
+       {
+         request_free (req);
+         return (retryable_socket_connect_error (errno)
+                 ? CONERROR : CONIMPOSSIBLE);
+       }
 
 #ifdef HAVE_SSL
       if (proxy && u->scheme == SCHEME_HTTPS)
@@ -1397,6 +1421,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
          resp = resp_new (head);
          statcode = resp_status (resp, &message);
          resp_free (resp);
+         xfree (head);
          if (statcode != 200)
            {
            failed_tunnel:
@@ -1574,6 +1599,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
     hs->error = xstrdup (_("(no description)"));
   else
     hs->error = xstrdup (message);
+  xfree (message);
 
   type = resp_header_strdup (resp, "Content-Type");
   if (type)
@@ -1615,6 +1641,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
        contrange = first_byte_pos;
     }
   resp_free (resp);
+  xfree (head);
 
   /* 20x responses are counted among successful by default.  */
   if (H_20X (statcode))
@@ -1713,9 +1740,20 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
          logputs (LOG_VERBOSE, _("Length: "));
          if (contlen != -1)
            {
-             logputs (LOG_VERBOSE, legible (contlen + contrange));
+             logputs (LOG_VERBOSE, with_thousand_seps (contlen + contrange));
+             if (contlen + contrange >= 1024)
+               logprintf (LOG_VERBOSE, " (%s)",
+                          human_readable (contlen + contrange));
              if (contrange)
-               logprintf (LOG_VERBOSE, _(" (%s to go)"), legible (contlen));
+               {
+                 if (contlen >= 1024)
+                   logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
+                              with_thousand_seps (contlen),
+                              human_readable (contlen));
+                 else
+                   logprintf (LOG_VERBOSE, _(", %s remaining"),
+                              with_thousand_seps (contlen));
+               }
            }
          else
            logputs (LOG_VERBOSE,
@@ -2824,7 +2862,17 @@ create_authorization_line (const char *au, const char *user,
   return NULL;
 }
 \f
+void
+save_cookies (void)
+{
+  if (wget_cookie_jar)
+    cookie_jar_save (wget_cookie_jar, opt.cookies_output);
+}
+
 void
 http_cleanup (void)
 {
+  xfree_null (pconn.host);
+  if (wget_cookie_jar)
+    cookie_jar_delete (wget_cookie_jar);
 }