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,
- "%s " /* GET/HEAD/POST/PUT */
- "%s HTTP/1.0\r\n" /* path */
- "%s" /* proxyuserpwd */
- "%s" /* userpwd */
- "%s" /* range */
- "%s" /* user agent */
- "%s" /* cookie */
- "%s" /* host */
- "%s" /* pragma */
- "%s" /* accept */
- "%s", /* referer */
-
- data->customrequest?data->customrequest:
- (data->bits.no_body?"HEAD":
- (data->bits.http_post || data->bits.http_formpost)?"POST":
- (data->bits.http_put)?"PUT":"GET"),
- ppath,
- (data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
- (data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"",
- (data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"",
- (data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"",
- (data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */
- (data->ptr_host?data->ptr_host:""), /* Host: host */
- http->p_pragma?http->p_pragma:"",
- http->p_accept?http->p_accept:"",
- (data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
- );
+
+ /* 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 */
+ "%s" /* userpwd */
+ "%s" /* range */
+ "%s" /* user agent */
+ "%s" /* cookie */
+ "%s" /* host */
+ "%s" /* pragma */
+ "%s" /* accept */
+ "%s", /* referer */
+
+ data->customrequest?data->customrequest:
+ (data->bits.no_body?"HEAD":
+ (data->bits.http_post || data->bits.http_formpost)?"POST":
+ (data->bits.http_put)?"PUT":"GET"),
+ ppath,
+ (data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
+ (data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"",
+ (data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"",
+ (data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"",
+ (data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */
+ (data->ptr_host?data->ptr_host:""), /* Host: host */
+ http->p_pragma?http->p_pragma:"",
+ http->p_accept?http->p_accept:"",
+ (data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
+ );
if(co) {
int count=0;
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;
switch(data->timecondition) {
case TIMECOND_IFMODSINCE:
default:
- sendf(data->firstsocket, data,
- "If-Modified-Since: %s\r\n", buf);
+ add_bufferf(req_buffer,
+ "If-Modified-Since: %s\r\n", buf);
break;
case TIMECOND_IFUNMODSINCE:
- sendf(data->firstsocket, data,
- "If-Unmodified-Since: %s\r\n", buf);
+ add_bufferf(req_buffer,
+ "If-Unmodified-Since: %s\r\n", buf);
break;
case TIMECOND_LASTMOD:
- sendf(data->firstsocket, data,
- "Last-Modified: %s\r\n", buf);
+ add_bufferf(req_buffer,
+ "Last-Modified: %s\r\n", buf);
break;
}
}
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;
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,
/* Let's PUT the data to the server! */
if(data->infilesize>0) {
- sendf(data->firstsocket, data,
- "Content-Length: %d\r\n\r\n", /* file size */
- data->infilesize );
+ 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,
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,
- "Content-Length: %d\r\n",
- (data->postfieldsize?data->postfieldsize:
- strlen(data->postfields)) );
+ 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,
- "Content-Type: application/x-www-form-urlencoded\r\n");
+ 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);
+ }
+ else {
+ add_bufferf(req_buffer,
+ "\r\n"
+ "%s\r\n",
+ data->postfields );
}
- sendf(data->firstsocket, data,
- "\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 */
}
#include <curl/curl.h>
#include "urldata.h"
+#include "sendf.h"
#include <curl/mprintf.h>
}
/* 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;
/*
* 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;
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);
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;
+}
+