Commit 0fb5a65a authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

- David McCreedy provided libcurl changes for doing HTTP communication on

  non-ASCII platforms. It does add some complexity, most notably with more
  #ifdefs, but I want to see this supported added and I can't see how we can
  add it without the extra stuff added.
parent c8afb02b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@
                                  Changelog

Daniel (14 January 2007)
- David McCreedy provided libcurl changes for doing HTTP communication on
  non-ASCII platforms. It does add some complexity, most notably with more
  #ifdefs, but I want to see this supported added and I can't see how we can
  add it without the extra stuff added.

- Setting CURLOPT_COOKIELIST to "ALL" when no cookies at all was present,
  libcurl would crash when trying to read a NULL pointer.

+3 −2
Original line number Diff line number Diff line
@@ -5,15 +5,16 @@ Curl and libcurl 7.16.1
 Available command line options:           112
 Available curl_easy_setopt() options:     133
 Number of public functions in libcurl:    54
 Amount of public web site mirrors:        38
 Amount of public web site mirrors:        39
 Number of known libcurl bindings:         35
 Number of contributors:                   524

This release includes the following changes:
 
 o Support for SCP and SFTP were added
 o Support for SCP and SFTP were added (powered by libssh2)
 o CURLOPT_CLOSEPOLICY is now deprecated
 o --ftp-ssl-ccc and CURLOPT_FTP_SSL_CCC were added
 o HTTP support for non-ASCII platforms

This release includes the following bugfixes:

+81 −25
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
/*
  Debug the form generator stand-alone by compiling this source file with:

  gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
  gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c

  run the 'formdata' executable the output should end with:
  All Tests seem to have worked ...
@@ -63,7 +63,7 @@ Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...

@@ -73,7 +73,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -87,7 +87,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
Content-Disposition: attachment; filename="inet_ntoa_r.h"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="Makefile.b32.resp"
Content-Disposition: attachment; filename="Makefile.b32"
Content-Type: text/plain
...
Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -118,6 +118,8 @@ Content-Disposition: form-data; name="FILECONTENT"
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
#endif
#include "urldata.h" /* for struct SessionHandle */
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "formdata.h"
#include "strequal.h"
#include "memory.h"
@@ -452,7 +454,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       * Set the Name property.
       */
    case CURLFORM_PTRNAME:
#ifdef CURL_DOES_CONVERSIONS
      /* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
         have safe memory for the eventual conversion */
#else
      current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
#endif
    case CURLFORM_COPYNAME:
      if (current_form->name)
        return_value = CURL_FORMADD_OPTION_TWICE;
@@ -835,7 +842,7 @@ static CURLcode AddFormData(struct FormData **formp,
    *formp = newform;

  if (size) {
    if(type == FORM_DATA)
    if((type == FORM_DATA) || (type == FORM_CONTENT))
      *size += length;
    else {
      /* Since this is a file to be uploaded here, add the size of the actual
@@ -872,10 +879,11 @@ static CURLcode AddFormDataf(struct FormData **formp,
 * Curl_formclean() is used from http.c, this cleans a built FormData linked
 * list
 */
void Curl_formclean(struct FormData *form)
void Curl_formclean(struct FormData **form_ptr)
{
  struct FormData *next;
  struct FormData *next, *form;

  form = *form_ptr;
  if(!form)
    return;

@@ -885,7 +893,39 @@ void Curl_formclean(struct FormData *form)
    free(form);       /* free the struct */

  } while ((form = next) != NULL); /* continue */

  *form_ptr = NULL;
}

#ifdef CURL_DOES_CONVERSIONS
/*
 * Curl_formcovert() is used from http.c, this converts any
   form items that need to be sent in the network encoding.
   Returns CURLE_OK on success.
 */
CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
{
  struct FormData *next;
  CURLcode rc;

  if(!form)
    return CURLE_OK;

  if(!data)
    return CURLE_BAD_FUNCTION_ARGUMENT;

  do {
    next=form->next;  /* the following form line */
    if (form->type == FORM_DATA) {
      rc = Curl_convert_to_network(data, form->line, form->length);
      /* Curl_convert_to_network calls failf if unsuccessful */
      if (rc != CURLE_OK)
        return rc;
    }
  } while ((form = next) != NULL); /* continue */
  return CURLE_OK;
}
#endif /* CURL_DOES_CONVERSIONS */

/*
 * curl_formget()
@@ -917,18 +957,18 @@ int curl_formget(struct curl_httppost *form, void *arg,
          if (temp.fp) {
            fclose(temp.fp);
          }
          Curl_formclean(data);
          Curl_formclean(&data);
          return -1;
        }
      } while (read == sizeof(buffer));
    } else {
      if (ptr->length != append(arg, ptr->line, ptr->length)) {
        Curl_formclean(data);
        Curl_formclean(&data);
        return -1;
      }
    }
  }
  Curl_formclean(data);
  Curl_formclean(&data);
  return 0;
}

@@ -1179,7 +1219,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
        curList = curList->next;
      }
      if (result) {
        Curl_formclean(firstform);
        Curl_formclean(&firstform);
        free(boundary);
        return result;
      }
@@ -1194,7 +1234,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
      if(file->contenttype &&
         !checkprefix("text/", file->contenttype)) {
        /* this is not a text content, mention our binary encoding */
        size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
        result = AddFormDataf(&form, &size,
                              "\r\nContent-Transfer-Encoding: binary");
        if (result)
          break;
      }
#endif

@@ -1232,21 +1275,26 @@ CURLcode Curl_getFormData(struct FormData **finalform,
            size_t nread;
            char buffer[512];
            while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
              result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
              result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
              if (result)
                break;
            }
          }

          if (result) {
            Curl_formclean(firstform);
            Curl_formclean(&firstform);
            free(boundary);
            return result;
          }

        }
        else {
          Curl_formclean(firstform);
#ifdef _FORM_DEBUG
          fprintf(stderr,
                  "\n==> Curl_getFormData couldn't open/read \"%s\"\n",
                  file->contents);
#endif
          Curl_formclean(&firstform);
          free(boundary);
          *finalform = NULL;
          return CURLE_READ_ERROR;
@@ -1255,7 +1303,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
      }
      else if (post->flags & HTTPPOST_BUFFER) {
        /* include contents of buffer */
        result = AddFormData(&form, FORM_DATA, post->buffer,
        result = AddFormData(&form, FORM_CONTENT, post->buffer,
                             post->bufferlength, &size);
          if (result)
            break;
@@ -1263,14 +1311,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,

      else {
        /* include the contents we got */
        result = AddFormData(&form, FORM_DATA, post->contents,
        result = AddFormData(&form, FORM_CONTENT, post->contents,
                             post->contentslength, &size);
        if (result)
          break;
      }
    } while ((file = file->more) != NULL); /* for each specified file for this field */
    if (result) {
      Curl_formclean(firstform);
      Curl_formclean(&firstform);
      free(boundary);
      return result;
    }
@@ -1288,7 +1336,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,

  } while ((post = post->next) != NULL); /* for each field */
  if (result) {
    Curl_formclean(firstform);
    Curl_formclean(&firstform);
    free(boundary);
    return result;
  }
@@ -1298,7 +1346,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
                       "\r\n--%s--\r\n",
                       boundary);
  if (result) {
    Curl_formclean(firstform);
    Curl_formclean(&firstform);
    free(boundary);
    return result;
  }
@@ -1397,7 +1445,7 @@ size_t Curl_FormReader(char *buffer,

    form->data = form->data->next; /* advance */

  } while(form->data && (form->data->type == FORM_DATA));
  } while(form->data && (form->data->type != FORM_FILE));
  /* If we got an empty line and we have more data, we proceed to the next
     line immediately to avoid returning zero before we've reached the end.
     This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
@@ -1464,7 +1512,7 @@ int main()
  char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
  char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
  char value7[] = "inet_ntoa_r.h";
  char value8[] = "Makefile.b32.resp";
  char value8[] = "Makefile.b32";
  char type2[] = "image/gif";
  char type6[] = "text/plain";
  char type7[] = "text/html";
@@ -1473,7 +1521,8 @@ int main()
  int value5length = strlen(value4);
  int value6length = strlen(value5);
  int errors = 0;
  int size;
  CURLcode rc;
  size_t size;
  size_t nread;
  char buffer[4096];
  struct curl_httppost *httppost=NULL;
@@ -1549,7 +1598,14 @@ int main()
                  CURLFORM_END))
    ++errors;

  form=Curl_getFormData(httppost, &size);
  rc = Curl_getFormData(&form, httppost, NULL, &size);
  if(rc != CURLE_OK) {
    if(rc != CURLE_READ_ERROR) {
      const char *errortext = curl_easy_strerror(rc);
      fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext);
    }
    return 0;
  }

  Curl_FormInit(&formread, form);

@@ -1557,7 +1613,7 @@ int main()
    nread = Curl_FormReader(buffer, 1, sizeof(buffer),
                            (FILE *)&formread);

    if(-1 == nread)
    if(nread < 1)
      break;
    fwrite(buffer, nread, 1, stdout);
  } while(1);
+7 −3
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@
 ***************************************************************************/

enum formtype {
  FORM_DATA, /* regular data */
  FORM_FILE  /* 'line' points to a file name we should read from */
  FORM_DATA,    /* form metadata (convert to network encoding if necessary) */
  FORM_CONTENT, /* form content  (never convert) */
  FORM_FILE     /* 'line' points to a file name we should read from 
                    to create the form data (never convert) */
};

/* plain and simple linked list with lines to send */
@@ -87,7 +89,9 @@ char *Curl_formpostheader(void *formp, size_t *len);

char *Curl_FormBoundary(void);

void Curl_formclean(struct FormData *);
void Curl_formclean(struct FormData **);

CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);

#endif
+31 −7
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "formdata.h"
#include "progress.h"
#include "base64.h"
@@ -154,7 +155,7 @@ static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
                        &authorization) > 0) {
    if(*userp)
      free(*userp);
    *userp = aprintf( "%sAuthorization: Basic %s\015\012",
    *userp = aprintf( "%sAuthorization: Basic %s\r\n",
                      proxy?"Proxy-":"",
                      authorization);
    free(authorization);
@@ -873,6 +874,20 @@ CURLcode add_buffer_send(send_buffer *in,
  ptr = in->buffer;
  size = in->size_used;

#ifdef CURL_DOES_CONVERSIONS
  if(size - included_body_bytes > 0) {
    res = Curl_convert_to_network(conn->data, ptr, size - included_body_bytes);
    /* Curl_convert_to_network calls failf if unsuccessful */
    if(res != CURLE_OK) {
      /* conversion failed, free memory and return to the caller */
      if(in->buffer)
        free(in->buffer);
      free(in);
      return res;
    }
  }
#endif /* CURL_DOES_CONVERSIONS */

  if(conn->protocol & PROT_HTTPS) {
    /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
       when we speak HTTPS, as if only a fraction of it is sent now, this data
@@ -1512,7 +1527,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
  if(HTTPREQ_POST_FORM == data->set.httpreq) {
    k->bytecount = http->readbytecount + http->writebytecount;

    Curl_formclean(http->sendit); /* Now free that whole lot */
    Curl_formclean(&http->sendit); /* Now free that whole lot */
    if(http->form.fp) {
      /* a file being uploaded was left opened, close it! */
      fclose(http->form.fp);
@@ -1699,7 +1714,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)

  Curl_safefree(conn->allocptr.ref);
  if(data->change.referer && !checkheaders(data, "Referer:"))
    conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
  else
    conn->allocptr.ref = NULL;

@@ -1710,7 +1725,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     data->set.encoding) {
    Curl_safefree(conn->allocptr.accept_encoding);
    conn->allocptr.accept_encoding =
      aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
      aprintf("Accept-Encoding: %s\r\n", data->set.encoding);
    if(!conn->allocptr.accept_encoding)
      return CURLE_OUT_OF_MEMORY;
  }
@@ -2194,10 +2209,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                                     &http->readbytecount,
                                     FIRSTSOCKET,
                                     &http->writebytecount);

      if(result) {
        Curl_formclean(&http->sendit); /* free that whole lot */
        return result;
      }
#ifdef CURL_DOES_CONVERSIONS
/* time to convert the form data... */
      result = Curl_formconvert(data, http->sendit);
      if(result) {
        Curl_formclean(http->sendit); /* free that whole lot */
        Curl_formclean(&http->sendit); /* free that whole lot */
        return result;
      }
#endif /* CURL_DOES_CONVERSIONS */
      break;

    case HTTPREQ_PUT: /* Let's PUT the data to the server! */
@@ -2316,8 +2340,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                                  (size_t)postsize);
            if(CURLE_OK == result)
              result = add_buffer(req_buffer,
                                  "\r\n0\r\n\r\n", 7); /* end of a chunked
                                                          transfer stream */
                                  "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
                                  /* CR  LF   0  CR  LF  CR  LF */
            included_body = postsize + 7;
          }
          if(result)
Loading