Commit fbc44075 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

- David McCreedy fixed the Curl command line tool for HTTP on non-ASCII

  platforms.
parent a79e5d79
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+0 −12
Original line number Diff line number Diff line
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 - 
+12 −0
Original line number Diff line number Diff line
@@ -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
+149 −76
Original line number Diff line number Diff line
@@ -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) {
  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++;
@@ -1910,6 +2017,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
          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
             with a separating &-letter */
@@ -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: