summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2015-05-08 10:43:36 +0200
committerDaniel Stenberg <daniel@haxx.se>2015-05-08 10:43:36 +0200
commit33874b1107550729d7e4c3d4f6c1f4eccd4b9cd8 (patch)
tree6fa32ae33696f89d4a0bdf70aafe620aa3e80a4f
parenta683f5590cad888d3f5769ef9bd5f72c3da6b0cd (diff)
downloadcurl-33874b1107550729d7e4c3d4f6c1f4eccd4b9cd8.tar.gz
CURLMOPT_PIPELINE: bit 1 is for multiplexing
-rw-r--r--docs/libcurl/opts/CURLMOPT_PIPELINING.327
-rw-r--r--include/curl/multi.h7
-rw-r--r--lib/multi.c15
-rw-r--r--lib/multihandle.h6
-rw-r--r--lib/multiif.h5
-rw-r--r--lib/sendf.c3
-rw-r--r--lib/transfer.c6
-rw-r--r--lib/url.c15
8 files changed, 48 insertions, 36 deletions
diff --git a/docs/libcurl/opts/CURLMOPT_PIPELINING.3 b/docs/libcurl/opts/CURLMOPT_PIPELINING.3
index c1df1d560..c795c48ec 100644
--- a/docs/libcurl/opts/CURLMOPT_PIPELINING.3
+++ b/docs/libcurl/opts/CURLMOPT_PIPELINING.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -26,17 +26,28 @@ CURLMOPT_PIPELINING \- enable/disable HTTP pipelining
.SH SYNOPSIS
#include <curl/curl.h>
-CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PIPELINING, bool onoff);
+CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PIPELINING, long bits);
.SH DESCRIPTION
-Set the \fBonoff\fP parameter to 1 to make libcurl use HTTP pipelining for
-HTTP transfers done using this multi handle, as far as possible. This means
-that if you add a second request that can use an already existing connection,
-the second request will be \&"piped" on the same connection rather than being
-executed in parallel.
+Set the \fBbits\fP parameter to 1 to make libcurl use HTTP pipelining for
+HTTP/1.1 transfers done using this multi handle, as far as possible. This
+means that if you add a second request that can use an already existing
+connection, the second request will be \&"piped" on the same connection rather
+than being executed in parallel.
When using pipelining, there are also several other related options that are
interesting to tweak and adjust to alter how libcurl spreads out requests on
different connections or not etc.
+
+Starting in 7.43.0, the \fBbits\fP parameter's bit 1 also has a meaning and
+libcurl is now offering symbol names for the bits:
+.IP CURLPIPE_NOTHING (0)
+Default, which means doing no attempts at pipelining or multiplexing.
+.IP CURLPIPE_HTTP1 (1)
+If this bit is set, libcurl will try to pipeline HTTP/1.1 requests on
+connections that are already established and in use to hosts.
+.IP CURLPIPE_MULTIPLEX (2)
+If this bit is set, libcurl will try to multiplex the new transfer over an
+existing connection if possible. This requires HTTP/2.
.SH DEFAULT
0 (off)
.SH PROTOCOLS
@@ -44,7 +55,7 @@ HTTP(S)
.SH EXAMPLE
TODO
.SH AVAILABILITY
-Added in 7.16.0
+Added in 7.16.0. Multiplex support bit added in 7.43.0.
.SH RETURN VALUE
Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
diff --git a/include/curl/multi.h b/include/curl/multi.h
index 3c4acb0f6..0d859f8fd 100644
--- a/include/curl/multi.h
+++ b/include/curl/multi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -74,6 +74,11 @@ typedef enum {
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING 0L
+#define CURLPIPE_HTTP1 1L
+#define CURLPIPE_MULTIPLEX 2L
+
typedef enum {
CURLMSG_NONE, /* first, not used */
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
diff --git a/lib/multi.c b/lib/multi.c
index 1d86d1661..f3f5d0d86 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -620,9 +620,10 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
return CURLM_OK;
}
-bool Curl_multi_pipeline_enabled(const struct Curl_multi *multi)
+/* Return TRUE if the application asked for a certain set of pipelining */
+bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
{
- return (multi && multi->pipelining_enabled) ? TRUE : FALSE;
+ return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
}
void Curl_multi_handlePipeBreak(struct SessionHandle *data)
@@ -1089,7 +1090,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
rc = CURLM_CALL_MULTI_PERFORM;
if(protocol_connect)
- multistate(data, multi->pipelining_enabled?
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
CURLM_STATE_WAITDO:CURLM_STATE_DO);
else {
#ifndef CURL_DISABLE_HTTP
@@ -1146,7 +1147,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* call again please so that we get the next socket setup */
rc = CURLM_CALL_MULTI_PERFORM;
if(protocol_connect)
- multistate(data, multi->pipelining_enabled?
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
CURLM_STATE_WAITDO:CURLM_STATE_DO);
else {
#ifndef CURL_DISABLE_HTTP
@@ -1210,7 +1211,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, CURLM_STATE_PROTOCONNECT);
else if(!result) {
/* protocol connect has completed, go WAITDO or DO */
- multistate(data, multi->pipelining_enabled?
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
CURLM_STATE_WAITDO:CURLM_STATE_DO);
rc = CURLM_CALL_MULTI_PERFORM;
}
@@ -1227,7 +1228,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
if(!result && protocol_connect) {
/* after the connect has completed, go WAITDO or DO */
- multistate(data, multi->pipelining_enabled?
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
CURLM_STATE_WAITDO:CURLM_STATE_DO);
rc = CURLM_CALL_MULTI_PERFORM;
}
@@ -2347,7 +2348,7 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
multi->socket_userp = va_arg(param, void *);
break;
case CURLMOPT_PIPELINING:
- multi->pipelining_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ multi->pipelining = va_arg(param, long);
break;
case CURLMOPT_TIMERFUNCTION:
multi->timer_cb = va_arg(param, curl_multi_timer_callback);
diff --git a/lib/multihandle.h b/lib/multihandle.h
index d8b9d8892..f53d0f44c 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -60,6 +60,8 @@ typedef enum {
#define GETSOCK_READABLE (0x00ff)
#define GETSOCK_WRITABLE (0xff00)
+#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+
/* This is the struct known as CURLM on the outside */
struct Curl_multi {
/* First a simple identifier to easier detect if a user mix up
@@ -95,8 +97,8 @@ struct Curl_multi {
same actual socket) */
struct curl_hash *sockhash;
- /* Whether pipelining is enabled for this multi handle */
- bool pipelining_enabled;
+ /* pipelining wanted bits (CURLPIPE*) */
+ long pipelining;
/* Shared connection cache (bundles)*/
struct conncache *conn_cache;
diff --git a/lib/multiif.h b/lib/multiif.h
index d8acfcabe..152cb8be2 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -27,8 +27,7 @@
*/
void Curl_expire(struct SessionHandle *data, long milli);
void Curl_expire_latest(struct SessionHandle *data, long milli);
-
-bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi);
+bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
void Curl_multi_handlePipeBreak(struct SessionHandle *data);
/* Internal version of curl_multi_init() accepts size parameters for the
diff --git a/lib/sendf.c b/lib/sendf.c
index 71b2d6030..5f39d1f2d 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -551,8 +551,7 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
ssize_t nread = 0;
size_t bytesfromsocket = 0;
char *buffertofill = NULL;
- bool pipelining = Curl_multi_pipeline_enabled(conn->data->multi) &&
- !conn->bits.multiplex;
+ bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1);
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
If it is the second socket, we set num to 1. Otherwise to 0. This lets
diff --git a/lib/transfer.c b/lib/transfer.c
index 8ac91664c..59e6acb4d 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -494,7 +494,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
/* We've stopped dealing with input, get out of the do-while loop */
if(nread > 0) {
- if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
infof(data,
"Rewinding stream by : %zd"
" bytes on url %s (zero-length body)\n",
@@ -639,7 +639,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(dataleft != 0) {
infof(conn->data, "Leftovers after chunking: %zu bytes\n",
dataleft);
- if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
/* only attempt the rewind if we truly are pipelining */
infof(conn->data, "Rewinding %zu bytes\n",dataleft);
read_rewind(conn, dataleft);
@@ -662,7 +662,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
excess = (size_t)(k->bytecount + nread - k->maxdownload);
if(excess > 0 && !k->ignorebody) {
- if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
/* The 'excess' amount below can't be more than BUFSIZE which
always will fit in a size_t */
infof(data,
diff --git a/lib/url.c b/lib/url.c
index 2369d53a4..177ac5027 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2783,7 +2783,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
Curl_ssl_close(conn, FIRSTSOCKET);
/* Indicate to all handles on the pipe that we're dead */
- if(Curl_multi_pipeline_enabled(data->multi)) {
+ if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
signalPipeClose(conn->send_pipe, TRUE);
signalPipeClose(conn->recv_pipe, TRUE);
}
@@ -2816,7 +2816,7 @@ static bool IsPipeliningPossible(const struct SessionHandle *handle,
{
/* If a HTTP protocol and pipelining is enabled */
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
- Curl_multi_pipeline_enabled(handle->multi)) {
+ Curl_pipeline_wanted(handle->multi, CURLPIPE_ANY)) {
if((handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
(handle->set.httpreq == HTTPREQ_GET ||
@@ -2831,11 +2831,6 @@ static bool IsPipeliningPossible(const struct SessionHandle *handle,
return FALSE;
}
-bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
-{
- return Curl_multi_pipeline_enabled(handle->multi);
-}
-
int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
struct curl_llist *pipeline)
{
@@ -3801,9 +3796,9 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
conn->response_header = NULL;
#endif
- if(Curl_multi_pipeline_enabled(data->multi) &&
- !conn->master_buffer) {
- /* Allocate master_buffer to be used for pipelining */
+ if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+ !conn->master_buffer) {
+ /* Allocate master_buffer to be used for HTTP/1 pipelining */
conn->master_buffer = calloc(BUFSIZE, sizeof (char));
if(!conn->master_buffer)
goto error;