1
0
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:
Daniel Stenberg 2000-10-03 11:01:32 +00:00
parent 398d21696f
commit d3f9b2a490
3 changed files with 174 additions and 70 deletions

View File

@ -340,35 +340,41 @@ 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,
"%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;
@ -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,16 +422,16 @@ CURLcode http(struct connectdata *conn)
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;
}
}
@ -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,
"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,
@ -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,
"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 */
}

View File

@ -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;
}

View File

@ -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