Newer
Older
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
switch(data->set.httpreq) {
case HTTPREQ_POST_FORM:
if(Curl_FormInit(&http->form, http->sendit)) {
failf(data, "Internal HTTP POST error!");
return CURLE_HTTP_POST_ERROR;
/* set the read function to read from the generated form data */
conn->fread = (curl_read_callback)Curl_FormReader;
conn->fread_in = &http->form;
Daniel Stenberg
committed
http->sending = HTTPSEND_BODY;
if(!conn->bits.upload_chunky)
/* only add Content-Length if not uploading chunked */
add_bufferf(req_buffer,
"Content-Length: %d\r\n", http->postsize);
if(!checkheaders(data, "Expect:")) {
/* if not disabled explicitly we add a Expect: 100-continue
to the headers which actually speeds up post operations (as
there is one packet coming back from the web server) */
add_bufferf(req_buffer,
"Expect: 100-continue\r\n");
Daniel Stenberg
committed
data->set.expect100header = TRUE;
if(!checkheaders(data, "Content-Type:")) {
/* Get Content-Type: line from Curl_FormReadOneLine, which happens
to always be the first line. We can know this for sure since
we always build the formpost linked list the same way!
The Content-Type header line also contains the MIME boundary
string etc why disabling this header is likely to not make things
work, but we support it anyway.
*/
char contentType[256];
int linelength=0;
linelength = Curl_FormReadOneLine (contentType,
sizeof(contentType),
1,
(FILE *)&http->form);
if(linelength == -1) {
failf(data, "Could not get Content-Type header line!");
return CURLE_HTTP_POST_ERROR;
}
add_buffer(req_buffer, contentType, linelength);
}
/* make the request end in a true CRLF */
add_buffer(req_buffer, "\r\n", 2);
Daniel Stenberg
committed
/* set upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
/* fire away the whole request to the server */
result = add_buffer_send(req_buffer, conn->firstsocket, conn,
Daniel Stenberg
committed
&data->info.request_size);
if(result)
failf(data, "Failed sending POST request");
else
/* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount,
conn->firstsocket,
&http->writebytecount);
Curl_formclean(http->sendit); /* free that whole lot */
break;
case HTTPREQ_PUT: /* Let's PUT the data to the server! */
if((data->set.infilesize>0) && !conn->bits.upload_chunky)
/* only add Content-Length if not uploading chunked */
Daniel Stenberg
committed
add_bufferf(req_buffer,
"Content-Length: %d\r\n", /* file size */
Daniel Stenberg
committed
data->set.infilesize );
add_bufferf(req_buffer, "\r\n");
Daniel Stenberg
committed
/* set the upload size to the progress meter */
Daniel Stenberg
committed
Curl_pgrsSetUploadSize(data, data->set.infilesize);
Daniel Stenberg
committed
/* this sends the buffer and frees all the buffer resources */
result = add_buffer_send(req_buffer, conn->firstsocket, conn,
Daniel Stenberg
committed
&data->info.request_size);
if(result)
failf(data, "Failed sending POST request");
Daniel Stenberg
committed
else
/* prepare for transfer */
result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount,
conn->firstsocket,
&http->writebytecount);
break;
case HTTPREQ_POST:
/* this is the simple POST, using x-www-form-urlencoded style */
if(!conn->bits.upload_chunky) {
/* We only set Content-Length and allow a custom Content-Length if
we don't upload data chunked, as RFC2616 forbids us to set both
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
if(!checkheaders(data, "Content-Length:"))
/* we allow replacing this header, although it isn't very wise to
actually set your own */
add_bufferf(req_buffer,
"Content-Length: %d\r\n",
data->set.postfieldsize?
data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0) );
}
if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n");
add_buffer(req_buffer, "\r\n", 2);
/* and here we setup the pointers to the actual data */
if(data->set.postfields) {
if(data->set.postfieldsize)
http->postsize = data->set.postfieldsize;
else
http->postsize = strlen(data->set.postfields);
http->postdata = data->set.postfields;
Daniel Stenberg
committed
http->sending = HTTPSEND_BODY;
conn->fread = (curl_read_callback)readmoredata;
conn->fread_in = (void *)conn;
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
Daniel Stenberg
committed
else
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* issue the request, headers-only */
result = add_buffer_send(req_buffer, conn->firstsocket, conn,
&data->info.request_size);
if(result)
failf(data, "Failed sending HTTP POST request");
result =
Daniel Stenberg
committed
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount,
conn->firstsocket,
&http->writebytecount);
break;
default:
add_buffer(req_buffer, "\r\n", 2);
result = add_buffer_send(req_buffer, conn->firstsocket, conn,
Daniel Stenberg
committed
&data->info.request_size);
Daniel Stenberg
committed
if(result)
failf(data, "Failed sending HTTP request");
else
/* HTTP GET/HEAD download: */
Daniel Stenberg
committed
result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
&http->readbytecount,
Daniel Stenberg
committed
http->postdata?conn->firstsocket:-1,
http->postdata?&http->writebytecount:NULL);
if(result)
return result;
} while (0); /* this is just a left-over from the multiple document download
attempts */