]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Move fnmatch() to cmpt.c and don't use it under GNU libc.
[wget] / src / http.c
index b10960ac916ee832ea53eba7e018adc70c59b78d..cd48d9b9d94c2d01a1f1b1070b59a26ea7077e43 100644 (file)
@@ -16,7 +16,17 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
 
 #include <config.h>
 
@@ -52,7 +62,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "retr.h"
 #include "headers.h"
 #include "connect.h"
-#include "fnmatch.h"
 #include "netrc.h"
 #ifdef HAVE_SSL
 # include "gen_sslfunc.h"
@@ -61,6 +70,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #ifdef USE_DIGEST
 # include "gen-md5.h"
 #endif
+#include "convert.h"
 
 extern char *version_string;
 
@@ -72,6 +82,7 @@ static int cookies_loaded_p;
 struct cookie_jar *wget_cookie_jar;
 
 #define TEXTHTML_S "text/html"
+#define TEXTXHTML_S "application/xhtml+xml"
 #define HTTP_ACCEPT "*/*"
 
 /* Some status code validation macros: */
@@ -175,8 +186,7 @@ parse_http_status_line (const char *line, const char **reason_phrase_ptr)
 
 /* Send the contents of FILE_NAME to SOCK/SSL.  Make sure that exactly
    PROMISED_SIZE bytes are sent over the wire -- if the file is
-   longer, read only that much; if the file is shorter, pad it with
-   zeros.  */
+   longer, read only that much; if the file is shorter, report an error.  */
 
 static int
 post_file (int sock, void *ssl, const char *file_name, long promised_size)
@@ -194,8 +204,8 @@ post_file (int sock, void *ssl, const char *file_name, long promised_size)
 
   fp = fopen (file_name, "rb");
   if (!fp)
-    goto pad;
-  while (written < promised_size)
+    return -1;
+  while (!feof (fp) && written < promised_size)
     {
       int towrite;
       int length = fread (chunk, 1, sizeof (chunk), fp);
@@ -217,29 +227,14 @@ post_file (int sock, void *ssl, const char *file_name, long promised_size)
     }
   fclose (fp);
 
- pad:
+  /* If we've written less than was promised, report a (probably
+     nonsensical) error rather than break the promise.  */
   if (written < promised_size)
     {
-      /* This highly unlikely case can happen only if the file has
-        shrunk under us.  To uphold the promise that exactly
-        promised_size bytes would be delivered, pad the remaining
-        data with zeros.  #### Should we abort instead?  */
-      DEBUGP (("padding %ld bytes ... ", promised_size - written));
-      memset (chunk, '\0', sizeof (chunk));
-      while (written < promised_size)
-       {
-         int towrite = WMIN (promised_size - written, sizeof (chunk));
-#ifdef HAVE_SSL
-         if (ssl)
-           write_error = ssl_iwrite (ssl, chunk, towrite);
-         else
-#endif
-           write_error = iwrite (sock, chunk, towrite);
-         if (write_error < 0)
-           return -1;
-         written += towrite;
-       }
+      errno = EINVAL;
+      return -1;
     }
+
   assert (written == promised_size);
   DEBUGP (("done]\n"));
   return 0;
@@ -574,7 +569,7 @@ struct http_stat
   char *remote_time;           /* remote time-stamp string */
   char *error;                 /* textual HTTP error */
   int statcode;                        /* status code */
-  long dltime;                 /* time of the download */
+  double dltime;               /* time of the download in msecs */
   int no_truncate;             /* whether truncating the file is
                                   forbidden. */
   const char *referer;         /* value of the referer header. */
@@ -755,7 +750,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
       address_list_release (al);
 
       if (sock < 0)
-       return errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+       return CONNECT_ERROR (errno);
 
 #ifdef HAVE_SSL
      if (conn->scheme == SCHEME_HTTPS)
@@ -1019,7 +1014,7 @@ Accept: %s\r\n\
 #endif
            write_error = iwrite (sock, opt.post_data, post_data_size);
        }
-      else if (opt.post_file_name)
+      else if (opt.post_file_name && post_data_size != 0)
        {
 #ifdef HAVE_SSL
          if (conn->scheme == SCHEME_HTTPS)
@@ -1329,7 +1324,9 @@ Accept: %s\r\n\
   /* If content-type is not given, assume text/html.  This is because
      of the multitude of broken CGI's that "forget" to generate the
      content-type.  */
-  if (!type || 0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)))
+  if (!type ||
+        0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)) ||
+        0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S)))
     *dt |= TEXTHTML;
   else
     *dt &= ~TEXTHTML;
@@ -1508,8 +1505,12 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
 
          #### A possible solution to this would be to remember the
         file position in the output document and to seek to that
-        position, instead of rewinding.  */
-      if (!hs->restval && global_download_count == 0)
+        position, instead of rewinding.
+
+         We don't truncate stdout, since that breaks
+        "wget -O - [...] >> foo".
+      */
+      if (!hs->restval && global_download_count == 0 && opt.dfp != stdout)
        {
          /* This will silently fail for streams that don't correspond
             to regular files, but that's OK.  */
@@ -1600,12 +1601,12 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
     hstat.local_file = local_file;
   else if (local_file)
     {
-      *local_file = url_filename (u);
+      *local_file = url_file_name (u);
       hstat.local_file = local_file;
     }
   else
     {
-      dummy = url_filename (u);
+      dummy = url_file_name (u);
       hstat.local_file = &dummy;
     }
 
@@ -2213,7 +2214,7 @@ http_atotm (const char *time_string)
      GNU strptime does not have this problem because it recognizes
      both international and local dates.  */
 
-  for (i = 0; i < ARRAY_SIZE (time_formats); i++)
+  for (i = 0; i < countof (time_formats); i++)
     if (check_end (strptime (time_string, time_formats[i], &t)))
       return mktime_from_utc (&t);
 
@@ -2343,8 +2344,8 @@ dump_hash (unsigned char *buf, const unsigned char *hash)
 
   for (i = 0; i < MD5_HASHLEN; i++, hash++)
     {
-      *buf++ = XDIGIT_TO_xchar (*hash >> 4);
-      *buf++ = XDIGIT_TO_xchar (*hash & 0xf);
+      *buf++ = XNUM_TO_digit (*hash >> 4);
+      *buf++ = XNUM_TO_digit (*hash & 0xf);
     }
   *buf = '\0';
 }
@@ -2375,7 +2376,7 @@ digest_authentication_encode (const char *au, const char *user,
       int i;
 
       au += skip_lws (au);
-      for (i = 0; i < ARRAY_SIZE (options); i++)
+      for (i = 0; i < countof (options); i++)
        {
          int skip = extract_header_attr (au, options[i].name,
                                          options[i].variable);
@@ -2392,7 +2393,7 @@ digest_authentication_encode (const char *au, const char *user,
              break;
            }
        }
-      if (i == ARRAY_SIZE (options))
+      if (i == countof (options))
        {
          while (*au && *au != '=')
            au++;