]> granicus.if.org Git - curl/commitdiff
- David McCreedy fixed the Curl command line tool for HTTP on non-ASCII
authorDaniel Stenberg <daniel@haxx.se>
Sat, 27 Jan 2007 23:02:17 +0000 (23:02 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 27 Jan 2007 23:02:17 +0000 (23:02 +0000)
  platforms.

CHANGES
TODO-RELEASE
docs/KNOWN_BUGS
src/main.c

diff --git a/CHANGES b/CHANGES
index 5271bd0cd10c529c7059d7f17b74c6eaa5dd940b..74175abae2e1872b52509c051debe7d555097e88 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Daniel (28 January 2007)
+- David McCreedy fixed the Curl command line tool for HTTP on non-ASCII
+  platforms.
+
 Daniel (25 January 2007)
 - Added the --libcurl [file] option to curl. Append this option to any
   ordinary curl command line, and you will get a libcurl-using source code
index acda7fdf88d15a63a1c66fbf51b0ce9c490318d6..80f499a079da8fd7ee137919c5db32ec25f45795 100644 (file)
@@ -1,16 +1,4 @@
 To get fixed in 7.16.1 (planned release: January 2007)
 ======================
 
-69 - Jeff Pohlmeyer's curl_multi_socket crashing case. Recipe and instructions
-     here: http://curl.haxx.se/mail/lib-2007-01/0022.html
-
-78 - HTTP Pipelining, NULL content
-     http://curl.haxx.se/bug/view.cgi?id=1631566
-
-80 - Steffen Rumler's Race Condition in Curl_proxyCONNECT:
-     http://curl.haxx.se/mail/lib-2007-01/0045.html
-
-81 - Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
-     http://curl.haxx.se/mail/lib-2007-01/0103.html
-
 82 - 
index 2ccabb82f905d1a4c1b43185fb17219e21e7a255..90faf77fd6d62d1562d43795e7a2c3ba8681e3fd 100644 (file)
@@ -3,6 +3,18 @@ join in and help us correct one or more of these! Also be sure to check the
 changelog of the current development status, as one or more of these problems
 may have been fixed since this was written!
 
+41. Jeff Pohlmeyer's curl_multi_socket crashing case. Recipe and instructions
+  here: http://curl.haxx.se/mail/lib-2007-01/0022.html
+
+40. HTTP Pipelining, NULL content
+  http://curl.haxx.se/bug/view.cgi?id=1631566
+
+39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
+  http://curl.haxx.se/mail/lib-2007-01/0045.html
+
+38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
+  http://curl.haxx.se/mail/lib-2007-01/0103.html
+
 37. Having more than one connection to the same host when doing NTLM
   authentication (with performs multiple "passes" and authenticates a
   connection rather than a HTTP request), and particularly when using the
index d43228b6a7c3a93bef9187e5d1170a74aeb4be18..e350500251c5600d1851b9180a5213cff163ff04 100644 (file)
@@ -203,9 +203,112 @@ typedef enum {
 #define struct_stat struct stat
 #endif
 
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#ifdef CURL_DOES_CONVERSIONS
+#ifdef HAVE_ICONV
 iconv_t inbound_cd  = (iconv_t)-1;
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+iconv_t outbound_cd = (iconv_t)-1;
+
+/*
+ * convert_to_network() is an internal function to convert
+ * from the host encoding to ASCII on non-ASCII platforms.
+ */
+static CURLcode
+convert_to_network(char *buffer, size_t length)
+{
+  CURLcode rc;
+
+  /* translate from the host encoding to the network encoding */
+  char *input_ptr, *output_ptr;
+  size_t in_bytes, out_bytes;
+
+  /* open an iconv conversion descriptor if necessary */
+  if(outbound_cd == (iconv_t)-1) {
+    outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                             CURL_ICONV_CODESET_OF_HOST);
+    if(outbound_cd == (iconv_t)-1) {
+      return CURLE_CONV_FAILED;
+    }
+  }
+  /* call iconv */
+  input_ptr = output_ptr = buffer;
+  in_bytes = out_bytes = length;
+  rc = iconv(outbound_cd, &input_ptr,  &in_bytes,
+                          &output_ptr, &out_bytes);
+  if ((rc == -1) || (in_bytes != 0)) {
+    return CURLE_CONV_FAILED;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * convert_from_network() is an internal function
+ * for performing ASCII conversions on non-ASCII platforms.
+ */
+static CURLcode
+convert_from_network(char *buffer, size_t length)
+{
+  CURLcode rc;
+
+  /* translate from the network encoding to the host encoding */
+  char *input_ptr, *output_ptr;
+  size_t in_bytes, out_bytes;
+
+  /* open an iconv conversion descriptor if necessary */
+  if(inbound_cd == (iconv_t)-1) {
+    inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                            CURL_ICONV_CODESET_OF_NETWORK);
+    if(inbound_cd == (iconv_t)-1) {
+      return CURLE_CONV_FAILED;
+    }
+  }
+  /* call iconv */
+  input_ptr = output_ptr = buffer;
+  in_bytes = out_bytes = length;
+  rc = iconv(inbound_cd, &input_ptr,  &in_bytes,
+                         &output_ptr, &out_bytes);
+  if ((rc == -1) || (in_bytes != 0)) {
+    return CURLE_CONV_FAILED;
+  }
+
+  return CURLE_OK;
+}
+#endif /* HAVE_ICONV */
+
+static
+char convert_char(curl_infotype infotype, char this_char)
+{
+/* determine how this specific character should be displayed */
+  switch(infotype) {
+  case CURLINFO_DATA_IN:
+  case CURLINFO_DATA_OUT:
+  case CURLINFO_SSL_DATA_IN:
+  case CURLINFO_SSL_DATA_OUT:
+    /* data, treat as ASCII */
+    if ((this_char >= 0x20) && (this_char < 0x7f)) {
+      /* printable ASCII hex value: convert to host encoding */
+      convert_from_network(&this_char, 1);
+    }
+    else {
+      /* non-printable ASCII, use a replacement character */
+      return UNPRINTABLE_CHAR;
+    }
+    /* fall through to default */
+  default:
+    /* treat as host encoding */
+    if (ISPRINT(this_char)
+        &&  (this_char != '\t')
+        &&  (this_char != '\r')
+        &&  (this_char != '\n')) {
+      /* printable characters excluding tabs and line end characters */
+      return this_char;
+    }
+    break;
+  }
+  /* non-printable, use a replacement character  */
+  return UNPRINTABLE_CHAR;
+}
+#endif /* CURL_DOES_CONVERSIONS */
 
 #ifdef WIN32
 /*
@@ -434,9 +537,10 @@ static void main_free(void)
   curl_global_cleanup();
 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
   /* close iconv conversion descriptor */
-  if (inbound_cd != (iconv_t)-1) {
-     iconv_close(inbound_cd);
-  }
+  if(inbound_cd != (iconv_t)-1)
+    iconv_close(inbound_cd);
+  if(outbound_cd != (iconv_t)-1)
+    iconv_close(outbound_cd);
 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
 }
 
@@ -1088,6 +1192,9 @@ static int formparse(struct Configurable *config,
         }
       }
       else {
+#ifdef CURL_DOES_CONVERSIONS
+        convert_to_network(contp, strlen(contp));
+#endif
         info[i].option = CURLFORM_COPYCONTENTS;
         info[i].value = contp;
         i++;
@@ -1909,6 +2016,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
         else {
           GetStr(&postdata, nextarg);
         }
+#ifdef CURL_DOES_CONVERSIONS
+        if(subletter != 'b') { /* NOT forced binary, convert to ASCII */
+          convert_to_network(postdata, strlen(postdata));
+        }
+#endif
 
         if(config->postfields) {
           /* we already have a string, we append this one
@@ -1918,7 +2031,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
           config->postfields=malloc(newlen);
           if(!config->postfields)
             return PARAM_NO_MEM;
-          snprintf(config->postfields, newlen, "%s&%s", oldpost, postdata);
+          /* use ASCII value 0x26 for '&' to accommodate non-ASCII platforms */
+          snprintf(config->postfields, newlen, "%s\x26%s", oldpost, postdata);
           free(oldpost);
           free(postdata);
         }
@@ -2832,74 +2946,6 @@ void progressbarinit(struct ProgressData *bar,
   bar->out = config->errors;
 }
 
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
-/*
- * convert_from_network() is an internal function
- * for performing ASCII conversions on non-ASCII platforms.
- */
-CURLcode
-convert_from_network(char *buffer, size_t length)
-{
-  CURLcode rc;
-
-  /* translate from the network encoding to the host encoding */
-  char *input_ptr, *output_ptr;
-  size_t in_bytes, out_bytes;
-
-  /* open an iconv conversion descriptor if necessary */
-  if(inbound_cd == (iconv_t)-1) {
-    inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
-                            CURL_ICONV_CODESET_OF_NETWORK);
-    if(inbound_cd == (iconv_t)-1) {
-      return CURLE_CONV_FAILED;
-    }
-  }
-  /* call iconv */
-  input_ptr = output_ptr = buffer;
-  in_bytes = out_bytes = length;
-  rc = iconv(inbound_cd, &input_ptr,  &in_bytes,
-                         &output_ptr, &out_bytes);
-  if ((rc == -1) || (in_bytes != 0)) {
-    return CURLE_CONV_FAILED;
-  }
-
-  return CURLE_OK;
-}
-
-static
-char convert_char(curl_infotype infotype, char this_char)
-{
-/* determine how this specific character should be displayed */
-  switch(infotype) {
-  case CURLINFO_DATA_IN:
-  case CURLINFO_DATA_OUT:
-  case CURLINFO_SSL_DATA_IN:
-  case CURLINFO_SSL_DATA_OUT:
-    /* data, treat as ASCII */
-    if ((this_char >= 0x20) && (this_char < 0x7f)) {
-      /* printable ASCII hex value: convert to host encoding */
-      convert_from_network(&this_char, 1);
-    }
-    else {
-      /* non-printable ASCII, use a replacement character */
-      return UNPRINTABLE_CHAR;
-    }
-    /* fall through to default */
-  default:
-    /* treat as host encoding */
-    if (ISPRINT(this_char)
-        &&  (this_char != '\t')
-        &&  (this_char != '\r')
-        &&  (this_char != '\n')) {
-      /* printable characters excluding tabs and line end characters */
-      return this_char;
-    }
-    break;
-  }
-  /* non-printable, use a replacement character  */
-  return UNPRINTABLE_CHAR;
-}
-#endif /* CURL_DOES_CONVERSIONS */
 
 static
 void dump(char *timebuf, const char *text,
@@ -2937,14 +2983,20 @@ void dump(char *timebuf, const char *text,
         i+=(c+2-width);
         break;
       }
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#ifdef CURL_DOES_CONVERSIONS
+      /* repeat the 0D0A check above but use the host encoding for CRLF */
+      if ((tracetype == TRACE_ASCII) &&
+          (i+c+1 < size) && ptr[i+c]=='\r' && ptr[i+c+1]=='\n') {
+        i+=(c+2-width);
+        break;
+      }
       /* convert to host encoding and print this character */
       fprintf(stream, "%c", convert_char(infotype, ptr[i+c]));
 #else
       (void)infotype;
       fprintf(stream, "%c",
               (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR);
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+#endif /* CURL_DOES_CONVERSIONS */
       /* check again for 0D0A, to avoid an extra \n if it's at width */
       if ((tracetype == TRACE_ASCII) &&
           (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
@@ -3066,6 +3118,27 @@ int my_trace(CURL *handle, curl_infotype type,
     return 0;
   }
 
+#ifdef CURL_DOES_CONVERSIONS
+  /* Special processing is needed for CURLINFO_HEADER_OUT blocks
+   * if they contain both headers and data (separated by CRLFCRLF).
+   * We dump the header text and then switch type to CURLINFO_DATA_OUT.
+   */
+  if((type == CURLINFO_HEADER_OUT) && (size > 4)) {
+    int i;
+    for(i = 0; i < size - 4; i++) {
+      if(memcmp(&data[i], "\r\n\r\n", 4) == 0) {
+        /* dump everthing through the CRLFCRLF as a sent header */
+        text = "=> Send header";
+        dump(timebuf, text, output, data, i+4, config->tracetype, type);
+        data += i + 3;
+        size -= i + 4;
+        type = CURLINFO_DATA_OUT;
+        data += 1;
+        break;
+      }
+    }
+  }
+#endif /* CURL_DOES_CONVERSIONS */
 
   switch (type) {
   case CURLINFO_TEXT: