mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
introduced the new add_buffer() concept that makes the HTTP request to get
sent in only one shot
This commit is contained in:
parent
398d21696f
commit
d3f9b2a490
140
lib/http.c
140
lib/http.c
@ -340,35 +340,41 @@ CURLcode http(struct connectdata *conn)
|
|||||||
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
|
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
send_buffer *req_buffer;
|
||||||
struct curl_slist *headers=data->headers;
|
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:
|
/* initialize a dynamic send-buffer */
|
||||||
(data->bits.no_body?"HEAD":
|
req_buffer = add_buffer_init();
|
||||||
(data->bits.http_post || data->bits.http_formpost)?"POST":
|
|
||||||
(data->bits.http_put)?"PUT":"GET"),
|
/* add the main request stuff */
|
||||||
ppath,
|
add_bufferf(req_buffer,
|
||||||
(data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
|
"%s " /* GET/HEAD/POST/PUT */
|
||||||
(data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"",
|
"%s HTTP/1.0\r\n" /* path */
|
||||||
(data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"",
|
"%s" /* proxyuserpwd */
|
||||||
(data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"",
|
"%s" /* userpwd */
|
||||||
(data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */
|
"%s" /* range */
|
||||||
(data->ptr_host?data->ptr_host:""), /* Host: host */
|
"%s" /* user agent */
|
||||||
http->p_pragma?http->p_pragma:"",
|
"%s" /* cookie */
|
||||||
http->p_accept?http->p_accept:"",
|
"%s" /* host */
|
||||||
(data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
|
"%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) {
|
if(co) {
|
||||||
int count=0;
|
int count=0;
|
||||||
@ -376,19 +382,16 @@ CURLcode http(struct connectdata *conn)
|
|||||||
while(co) {
|
while(co) {
|
||||||
if(co->value && strlen(co->value)) {
|
if(co->value && strlen(co->value)) {
|
||||||
if(0 == count) {
|
if(0 == count) {
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer, "Cookie:");
|
||||||
"Cookie:");
|
|
||||||
}
|
}
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"%s%s=%s", count?"; ":"", co->name,
|
"%s%s=%s", count?"; ":"", co->name, co->value);
|
||||||
co->value);
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
co = co->next; /* next cookie please */
|
co = co->next; /* next cookie please */
|
||||||
}
|
}
|
||||||
if(count) {
|
if(count) {
|
||||||
sendf(data->firstsocket, data,
|
add_buffer(req_buffer, "\r\n", 2);
|
||||||
"\r\n");
|
|
||||||
}
|
}
|
||||||
cookie_freelist(co); /* free the cookie list */
|
cookie_freelist(co); /* free the cookie list */
|
||||||
co=NULL;
|
co=NULL;
|
||||||
@ -419,16 +422,16 @@ CURLcode http(struct connectdata *conn)
|
|||||||
switch(data->timecondition) {
|
switch(data->timecondition) {
|
||||||
case TIMECOND_IFMODSINCE:
|
case TIMECOND_IFMODSINCE:
|
||||||
default:
|
default:
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"If-Modified-Since: %s\r\n", buf);
|
"If-Modified-Since: %s\r\n", buf);
|
||||||
break;
|
break;
|
||||||
case TIMECOND_IFUNMODSINCE:
|
case TIMECOND_IFUNMODSINCE:
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"If-Unmodified-Since: %s\r\n", buf);
|
"If-Unmodified-Since: %s\r\n", buf);
|
||||||
break;
|
break;
|
||||||
case TIMECOND_LASTMOD:
|
case TIMECOND_LASTMOD:
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"Last-Modified: %s\r\n", buf);
|
"Last-Modified: %s\r\n", buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,9 +448,7 @@ CURLcode http(struct connectdata *conn)
|
|||||||
if(*ptr) {
|
if(*ptr) {
|
||||||
/* only send this if the contents was non-blank */
|
/* only send this if the contents was non-blank */
|
||||||
|
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer, "%s\r\n", headers->data);
|
||||||
"%s\015\012",
|
|
||||||
headers->data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
headers = headers->next;
|
headers = headers->next;
|
||||||
@ -468,12 +469,13 @@ CURLcode http(struct connectdata *conn)
|
|||||||
generated form data */
|
generated form data */
|
||||||
data->in = (FILE *)&http->form;
|
data->in = (FILE *)&http->form;
|
||||||
|
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"Content-Length: %d\r\n",
|
"Content-Length: %d\r\n", http->postsize-2);
|
||||||
http->postsize-2);
|
|
||||||
|
|
||||||
|
/* set upload size to the progress meter */
|
||||||
pgrsSetUploadSize(data, http->postsize);
|
pgrsSetUploadSize(data, http->postsize);
|
||||||
|
|
||||||
|
add_buffer_send(data->firstsocket, conn, req_buffer);
|
||||||
result = Transfer(conn, data->firstsocket, -1, TRUE,
|
result = Transfer(conn, data->firstsocket, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
data->firstsocket,
|
data->firstsocket,
|
||||||
@ -487,16 +489,20 @@ CURLcode http(struct connectdata *conn)
|
|||||||
/* Let's PUT the data to the server! */
|
/* Let's PUT the data to the server! */
|
||||||
|
|
||||||
if(data->infilesize>0) {
|
if(data->infilesize>0) {
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"Content-Length: %d\r\n\r\n", /* file size */
|
"Content-Length: %d\r\n\r\n", /* file size */
|
||||||
data->infilesize );
|
data->infilesize );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer, "\015\012");
|
||||||
"\015\012");
|
|
||||||
|
|
||||||
|
/* set the upload size to the progress meter */
|
||||||
pgrsSetUploadSize(data, data->infilesize);
|
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,
|
result = Transfer(conn, data->firstsocket, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
data->firstsocket,
|
data->firstsocket,
|
||||||
@ -512,30 +518,34 @@ CURLcode http(struct connectdata *conn)
|
|||||||
if(!checkheaders(data, "Content-Length:"))
|
if(!checkheaders(data, "Content-Length:"))
|
||||||
/* we allow replacing this header, although it isn't very wise to
|
/* we allow replacing this header, although it isn't very wise to
|
||||||
actually set your own */
|
actually set your own */
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"Content-Length: %d\r\n",
|
"Content-Length: %d\r\n",
|
||||||
(data->postfieldsize?data->postfieldsize:
|
(data->postfieldsize?data->postfieldsize:
|
||||||
strlen(data->postfields)) );
|
strlen(data->postfields)) );
|
||||||
|
|
||||||
if(!checkheaders(data, "Content-Type:"))
|
if(!checkheaders(data, "Content-Type:"))
|
||||||
sendf(data->firstsocket, data,
|
add_bufferf(req_buffer,
|
||||||
"Content-Type: application/x-www-form-urlencoded\r\n");
|
"Content-Type: application/x-www-form-urlencoded\r\n");
|
||||||
|
|
||||||
/* and here comes the actual data */
|
/* and here comes the actual data */
|
||||||
if(data->postfieldsize) {
|
if(data->postfieldsize) {
|
||||||
ssend(data->firstsocket, conn, "\r\n", 2);
|
add_buffer(req_buffer, "\r\n", 2);
|
||||||
ssend(data->firstsocket, conn, data->postfields, data->postfieldsize);
|
add_buffer(req_buffer, data->postfields,
|
||||||
ssend(data->firstsocket, conn, "\r\n", 2);
|
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
|
else
|
||||||
sendf(data->firstsocket, data, "\r\n");
|
add_buffer(req_buffer, "\r\n", 2);
|
||||||
|
|
||||||
/* HTTP GET/HEAD download: */
|
/* HTTP GET/HEAD download: */
|
||||||
|
add_buffer_send(data->firstsocket, conn, req_buffer);
|
||||||
result = Transfer(conn, data->firstsocket, -1, TRUE, bytecount,
|
result = Transfer(conn, data->firstsocket, -1, TRUE, bytecount,
|
||||||
-1, NULL); /* nothing to upload */
|
-1, NULL); /* nothing to upload */
|
||||||
}
|
}
|
||||||
|
90
lib/sendf.c
90
lib/sendf.c
@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ void failf(struct UrlData *data, char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sendf() sends the formated data to the server */
|
/* 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;
|
size_t bytes_written;
|
||||||
char *s;
|
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
|
* 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;
|
size_t bytes_written;
|
||||||
char *s;
|
char *s;
|
||||||
@ -154,9 +155,6 @@ size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
|
|||||||
size_t bytes_written;
|
size_t bytes_written;
|
||||||
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
|
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
|
||||||
|
|
||||||
if(data->bits.verbose)
|
|
||||||
fprintf(data->err, "> [binary output]\n");
|
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if (data->use_ssl) {
|
if (data->use_ssl) {
|
||||||
bytes_written = SSL_write(data->ssl, mem, len);
|
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;
|
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
lib/sendf.h
14
lib/sendf.h
@ -46,4 +46,18 @@ size_t ssend(int fd, struct connectdata *, void *fmt, size_t len);
|
|||||||
void infof(struct UrlData *, char *fmt, ...);
|
void infof(struct UrlData *, char *fmt, ...);
|
||||||
void failf(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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user