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

introduced the new add_buffer() concept that makes the HTTP request to get

sent in only one shot
parent 398d2169
Loading
Loading
Loading
Loading
+76 −66
Original line number Diff line number Diff line
@@ -340,8 +340,14 @@ CURLcode http(struct connectdata *conn)
    http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";

  do {
    send_buffer *req_buffer;
    struct curl_slist *headers=data->headers;
    sendf(data->firstsocket, data,

    /* initialize a dynamic send-buffer */
    req_buffer = add_buffer_init();

    /* add the main request stuff */
    add_bufferf(req_buffer,
                "%s " /* GET/HEAD/POST/PUT */
                "%s HTTP/1.0\r\n" /* path */
                "%s" /* proxyuserpwd */
@@ -376,19 +382,16 @@ CURLcode http(struct connectdata *conn)
      while(co) {
        if(co->value && strlen(co->value)) {
          if(0 == count) {
            sendf(data->firstsocket, data,
                  "Cookie:");
            add_bufferf(req_buffer, "Cookie:");
          }
          sendf(data->firstsocket, data,
                "%s%s=%s", count?"; ":"", co->name,
                co->value);
          add_bufferf(req_buffer,
                      "%s%s=%s", count?"; ":"", co->name, co->value);
          count++;
        }
        co = co->next; /* next cookie please */
      }
      if(count) {
        sendf(data->firstsocket, data,
              "\r\n");
        add_buffer(req_buffer, "\r\n", 2);
      }
      cookie_freelist(co); /* free the cookie list */
      co=NULL;
@@ -419,15 +422,15 @@ CURLcode http(struct connectdata *conn)
      switch(data->timecondition) {
      case TIMECOND_IFMODSINCE:
      default:
        sendf(data->firstsocket, data,
        add_bufferf(req_buffer,
                    "If-Modified-Since: %s\r\n", buf);
        break;
      case TIMECOND_IFUNMODSINCE:
        sendf(data->firstsocket, data,
        add_bufferf(req_buffer,
                    "If-Unmodified-Since: %s\r\n", buf);
        break;
      case TIMECOND_LASTMOD:
        sendf(data->firstsocket, data,
        add_bufferf(req_buffer,
                    "Last-Modified: %s\r\n", buf);
        break;
      }
@@ -445,9 +448,7 @@ CURLcode http(struct connectdata *conn)
        if(*ptr) {
          /* only send this if the contents was non-blank */

          sendf(data->firstsocket, data,
                "%s\015\012",
                headers->data);
          add_bufferf(req_buffer, "%s\r\n", headers->data);
        }
      }
      headers = headers->next;
@@ -468,12 +469,13 @@ CURLcode http(struct connectdata *conn)
                       generated form data */
      data->in = (FILE *)&http->form;

      sendf(data->firstsocket, data,
            "Content-Length: %d\r\n",
            http->postsize-2);
      add_bufferf(req_buffer,
                  "Content-Length: %d\r\n", http->postsize-2);

      /* set upload size to the progress meter */
      pgrsSetUploadSize(data, http->postsize);

      add_buffer_send(data->firstsocket, conn, req_buffer);
      result = Transfer(conn, data->firstsocket, -1, TRUE,
                        &http->readbytecount,
                          data->firstsocket,
@@ -487,16 +489,20 @@ CURLcode http(struct connectdata *conn)
      /* Let's PUT the data to the server! */

      if(data->infilesize>0) {
        sendf(data->firstsocket, data,
        add_bufferf(req_buffer,
                    "Content-Length: %d\r\n\r\n", /* file size */
                    data->infilesize );
      }
      else
        sendf(data->firstsocket, data,
              "\015\012");
        add_bufferf(req_buffer, "\015\012");

      /* set the upload size to the progress meter */
      pgrsSetUploadSize(data, data->infilesize);

      /* this sends the buffer and frees all the buffer resources */
      add_buffer_send(data->firstsocket, conn, req_buffer);

      /* prepare for transfer */
      result = Transfer(conn, data->firstsocket, -1, TRUE,
                        &http->readbytecount,
                        data->firstsocket,
@@ -512,30 +518,34 @@ CURLcode http(struct connectdata *conn)
        if(!checkheaders(data, "Content-Length:"))
          /* we allow replacing this header, although it isn't very wise to
             actually set your own */
          sendf(data->firstsocket, data,
          add_bufferf(req_buffer,
                      "Content-Length: %d\r\n",
                      (data->postfieldsize?data->postfieldsize:
                       strlen(data->postfields)) );

        if(!checkheaders(data, "Content-Type:"))
          sendf(data->firstsocket, data,
          add_bufferf(req_buffer,
                      "Content-Type: application/x-www-form-urlencoded\r\n");

        /* and here comes the actual data */
        if(data->postfieldsize) {
          ssend(data->firstsocket, conn, "\r\n", 2);
          ssend(data->firstsocket, conn, data->postfields, data->postfieldsize);
          ssend(data->firstsocket, conn, "\r\n", 2);
          add_buffer(req_buffer, "\r\n", 2);
          add_buffer(req_buffer, data->postfields,
                     data->postfieldsize);
          add_buffer(req_buffer, "\r\n", 2);
        }
        sendf(data->firstsocket, data,
        else {
          add_bufferf(req_buffer,
                      "\r\n"
                      "%s\r\n",
                      data->postfields );
        }
      }
      else
        sendf(data->firstsocket, data, "\r\n");
        add_buffer(req_buffer, "\r\n", 2);

      /* HTTP GET/HEAD download: */
      add_buffer_send(data->firstsocket, conn, req_buffer);
      result = Transfer(conn, data->firstsocket, -1, TRUE, bytecount,
                        -1, NULL); /* nothing to upload */
    }
+85 −5
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@

#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"

#include <curl/mprintf.h>

@@ -89,7 +90,7 @@ void failf(struct UrlData *data, char *fmt, ...)
}

/* sendf() sends the formated data to the server */
int sendf(int fd, struct UrlData *data, char *fmt, ...)
size_t sendf(int fd, struct UrlData *data, char *fmt, ...)
{
  size_t bytes_written;
  char *s;
@@ -118,7 +119,7 @@ int sendf(int fd, struct UrlData *data, char *fmt, ...)
/*
 * ftpsendf() sends the formated string as a ftp command to a ftp server
 */
int ftpsendf(int fd, struct connectdata *conn, char *fmt, ...)
size_t ftpsendf(int fd, struct connectdata *conn, char *fmt, ...)
{
  size_t bytes_written;
  char *s;
@@ -154,9 +155,6 @@ size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
  size_t bytes_written;
  struct UrlData *data=conn->data; /* conn knows data, not vice versa */

  if(data->bits.verbose)
    fprintf(data->err, "> [binary output]\n");

#ifdef USE_SSLEAY
  if (data->use_ssl) {
    bytes_written = SSL_write(data->ssl, mem, len);
@@ -177,6 +175,88 @@ size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
  return bytes_written;
}

/*
 * add_buffer_init() returns a fine buffer struct
 */
send_buffer *add_buffer_init(void)
{
  send_buffer *blonk;
  blonk=(send_buffer *)malloc(sizeof(send_buffer));
  if(blonk) {
    memset(blonk, 0, sizeof(send_buffer));
    return blonk;
  }
  return NULL; /* failed, go home */
}

/*
 * add_buffer_send() sends a buffer and frees all associated memory.
 */
size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
{
  if(in->buffer)
    free(in->buffer);
  free(in);

  if(conn->data->bits.verbose) {
    fputs("> ", conn->data->err);
    /* this data _may_ contain binary stuff */
    fwrite(in->buffer, in->size_used, 1, conn->data->err);
  }

  return ssend(sockfd, conn, in->buffer, in->size_used);
}


/* 
 * add_bufferf() builds a buffer from the formatted input
 */
CURLcode add_bufferf(send_buffer *in, char *fmt, ...)
{
  CURLcode result = CURLE_OUT_OF_MEMORY;
  char *s;
  va_list ap;
  va_start(ap, fmt);
  s = mvaprintf(fmt, ap); /* this allocs a new string to append */
  va_end(ap);

  if(s) {
    result = add_buffer(in, s, strlen(s));
    free(s);
  }
  return result;
}

/*
 * add_buffer() appends a memory chunk to the existing one
 */
CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
{
  char *new_rb;
  int new_size;

  if(size > 0) {
    if(!in->buffer ||
       ((in->size_used + size) > (in->size_max - 1))) {
      new_size = (in->size_used+size)*2;
      if(in->buffer)
        /* we have a buffer, enlarge the existing one */
        new_rb = (char *)realloc(in->buffer, new_size);
      else
        /* create a new buffer */
        new_rb = (char *)malloc(new_size);

      if(!new_rb)
        return CURLE_OUT_OF_MEMORY;

      in->buffer = new_rb;
      in->size_max = new_size;
    }
    memcpy(&in->buffer[in->size_used], inptr, size);
      
    in->size_used += size;
  }

  return CURLE_OK;
}
+14 −0
Original line number Diff line number Diff line
@@ -46,4 +46,18 @@ size_t ssend(int fd, struct connectdata *, void *fmt, size_t len);
void infof(struct UrlData *, char *fmt, ...);
void failf(struct UrlData *, char *fmt, ...);

struct send_buffer {
  char *buffer;
  long size_max;
  long size_used;
};
typedef struct send_buffer send_buffer;


send_buffer *add_buffer_init(void);
CURLcode add_buffer(send_buffer *in, void *inptr, size_t size);
CURLcode add_bufferf(send_buffer *in, char *fmt, ...);
size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in);


#endif