# curl_multi_setopt

Definition: | include builtins\libcurl.e CURLMcode res = curl_multi_setopt(atom mcurl, CURLMoption option, object param)
Description: | Set options for a curl multi handle. mcurl: a return value from curl_multi_init(). option: one of the values listed below. param: can be a long, a function pointer, an object pointer or a curl_off_t type, depending on what the specific option expects. Read this manual carefully as bad input values may cause libcurl to behave badly! You can only set one option in each function call. Returns: The standard CURLMcode for multi interface error codes. Note that it returns a CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl does not know of.
pwa/p2js: | Not supported.
Comments: | curl_multi_setopt is used to tell a libcurl multi handle how to behave. By using the appropriate options to curl_multi_setopt, you can change libcurl’s behaviour when using that multi handle. All options are set with the option followed by the parameter param. Availability: This function was added in libcurl 7.15.4.
CURLMoption | CURLMoption is one of the following:
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE | Chunk length threshold for pipelining. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, integer nsize) Specify nsize in bytes. If a pipelined connection is currently processing a chunked (Transfer-encoding: chunked) request with a current chunk length larger than CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, that pipeline will not be considered for additional requests, even if it is shorter than CURLMOPT_MAX_PIPELINE_LENGTH. Default: The default value is 0, which means that the penalization is inactive. Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    curl_multi_setopt(m, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, 10000)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PIPELINING, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLMOPT_MAX_PIPELINE_LENGTH
CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE | Size threshold for pipelining penalty. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, integer nsize) Specify nsize in bytes. If a pipelined connection is currently processing a request with a Content-Length larger than this CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, that pipeline will then not be considered for additional requests, even if it is shorter than CURLMOPT_MAX_PIPELINE_LENGTH. Default: The default value is 0, which means that the size penalization is inactive. Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    curl_multi_setopt(m, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, 10000)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PIPELINING, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE
CURLMOPT_MAX_HOST_CONNECTIONS | Set max number of connections to a single host. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_MAX_HOST_CONNECTIONS, integer max) The specified number will be used as the maximum amount of simultaneously open connections to a single host (a host being the same as a host name + port number pair). For each new session to a host, libcurl will open a new connection up to the limit set by CURLMOPT_MAX_HOST_CONNECTIONS. When the limit is reached, the sessions will be pending until a connection becomes available. If CURLMOPT_PIPELINING is enabled, libcurl will try to pipeline if the host is capable of it. The default max value is 0, unlimited. However, for backwards compatibility, setting it to 0 when CURLMOPT_PIPELINING is 1 will not be treated as unlimited. Instead it will open only 1 connection and try to pipeline on it. This set limit is also used for proxy connections, and then the proxy is considered to be the host for which this limit counts. Default: 0 Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    /* do no more than 2 connections per host */
    curl_multi_setopt(m, CURLMOPT_MAX_HOST_CONNECTIONS, 2)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_MAXCONNECTS, CURLMOPT_MAX_TOTAL_CONNECTIONS
CURLMOPT_MAX_PIPELINE_LENGTH | Maximum number of requests in a pipeline. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_MAX_PIPELINE_LENGTH, integer max) The specified max number will be used as the maximum amount of outstanding requests in an HTTP/1.1 pipelined connection. This option is only used for HTTP/1.1 pipelining, not for HTTP/2 multiplexing. When this limit is reached, libcurl will use another connection to the same host (see CURLMOPT_MAX_HOST_CONNECTIONS), or queue the request until one of the pipelines to the host is ready to accept a request. Thus, the total number of requests in-flight is CURLMOPT_MAX_HOST_CONNECTIONS * CURLMOPT_MAX_PIPELINE_LENGTH. Default: 5 Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    /* set a more conservative pipe length */
    curl_multi_setopt(m, CURLMOPT_MAX_PIPELINE_LENGTH, 3)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PIPELINING, CURLMOPT_MAX_HOST_CONNECTIONS
CURLMOPT_MAX_TOTAL_CONNECTIONS | Max simultaneously open connections. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_MAX_TOTAL_CONNECTIONS, integer max) The set number will be used as the maximum number of simultaneously open connections in total using this multi handle. For each new session, libcurl will open a new connection up to the limit set by CURLMOPT_MAX_TOTAL_CONNECTIONS. When the limit is reached, the sessions will be pending until there are available connections. If CURLMOPT_PIPELINING is enabled, libcurl will try to pipeline or use multiplexing if the host is capable of it. Default: The default value is 0, which means that there is no limit. It is then simply controlled by the number of easy handles added. Protocols: All Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    /* never do more than 15 connections */
    curl_multi_setopt(m, CURLMOPT_MAX_TOTAL_CONNECTIONS, 15)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_MAXCONNECTS, CURLMOPT_MAX_HOST_CONNECTIONS
CURLMOPT_MAXCONNECTS | Set size of connection cache. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_MAXCONNECTS, integer max) Set the maximum number of simultaneously open connections that libcurl may keep in its connection cache after completed use. By default libcurl will enlarge the size for each added easy handle to make it fit 4 times the number of added easy handles. By setting this option, you can prevent the cache size from growing beyond the limit set by you. When the cache is full, curl closes the oldest one in the cache to prevent the number of open connections from increasing. This option is for the multi handle’s use only, when using the easy interface you should instead use the CURLOPT_MAXCONNECTS option. See CURLMOPT_MAX_TOTAL_CONNECTIONS for limiting the number of active connections. Protocols: All Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    /* only keep 10 connections in the cache */
    curl_multi_setopt(m, CURLMOPT_MAXCONNECTS, 10)
Availability: Added in 7.16.3 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPT_MAXCONNECTS
CURLMOPT_PIPELINING | Enable HTTP pipelining and multiplexing. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_PIPELINING, integer bitmask) Pass in the bitmask parameter to instruct libcurl to enable HTTP pipelining and/or HTTP/2 multiplexing for this multi handle. When enabled, libcurl will attempt to use those protocol features when doing parallel requests to the same hosts. For pipelining, 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. For multiplexing, this means that follow-up requests can re-use an existing connection and send the new request multiplexed over that at the same time as other transfers are already using that single connection. There are several other related options that are interesting to tweak and adjust to alter how libcurl spreads out requests on different connections or not etc. Before 7.43.0, this option was set to 1 and 0 to enable and disable HTTP/1.1 pipelining. Starting in 7.43.0, bitmask’s second bit also has a meaning, and you can ask for pipelining and multiplexing independently of each other by toggling the correct bits. CURLPIPE_NOTHING (0) Default, which means doing no attempts at pipelining or multiplexing. 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. 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. Default: 0 (both pipeline and multiplexing are off) Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    /* try HTTP/1 pipelining and HTTP/2 multiplexing */
    curl_multi_setopt(m, CURLMOPT_PIPELINING, or_bits(CURLPIPE_HTTP1,CURLPIPE_MULTIPLEX))
Availability: Added in 7.16.0. Multiplex support bit added in 7.43.0. Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_MAX_PIPELINE_LENGTH, CURLMOPT_PIPELINING_SITE_BL, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLMOPT_MAX_HOST_CONNECTIONS, CURLMOPT_MAXCONNECTS, CURLMOPT_MAX_HOST_CONNECTIONS
CURLMOPT_PIPELINING_SITE_BL | Pipelining host blacklist. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_PIPELINING_SITE_BL, sequence hosts) Pass a hosts array (/sequence) of strings. It is not necessary to "NULL_terminate" this (unlike C). This is a list of sites that are blacklisted from pipelining, i.e sites that are known to not support HTTP pipelining. The array is copied by libcurl. Pass a NULL pointer to clear the blacklist. Default: The default value is NULL, which means that there is no blacklist. Protocols: HTTP(S) Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    sequence site_blacklist = {"www.haxx.se",
                               "www.example.com:1234"}
    curl_multi_setopt(m, CURLMOPT_PIPELINING_SITE_BL, site_blacklist)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PIPELINING, CURLMOPT_PIPELINING_SERVER_BL
CURLMOPT_PIPELINING_SERVER_BL | Pipelining server blacklist. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, sequence servers) Pass a servers array (/sequence) of strings. It is not necessary to "NULL_terminate" this (unlike C). This is a list of server types prefixes (in the Server: HTTP header) that are blacklisted from pipelining, i.e server types that are known to not support HTTP pipelining. The array is copied by libcurl. Note that the comparison matches if the Server: header begins with the string in the blacklist, i.e "Server: Ninja 1.2.3" and "Server: Ninja 1.4.0" can both be blacklisted by having "Ninja" in the backlist. Pass a NULL pointer to clear the blacklist. Default: The default value is NULL, which means that there is no blacklist. Example Copy
    include builtins\libcurl.e
    atom m = curl_multi_init()
    constant server_blacklist = {"Microsoft-IIS/6.0",
                                 "nginx/0.8.54"}
    curl_multi_setopt(m, CURLMOPT_PIPELINING_SERVER_BL, server_blacklist)
Availability: Added in 7.30.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PIPELINING, CURLMOPT_PIPELINING_SITE_BL
CURLMOPT_PUSHFUNCTION | Callback that approves or denies server pushes Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_PUSHFUNCTION, atom curl_push_cb) This callback gets called when a new HTTP/2 stream is being pushed by the server (using the PUSH_PROMISE frame). If no push callback is set, all offered pushes will be denied automatically. The callback (see example below) gets its arguments like this: parent: the handle of the stream on which this push arrives. The new handle has been duphandle()d from the parent, meaning that it has gotten all its options inherited. It is then up to the application to alter any options if desired. easy: a newly created handle that represents this upcoming transfer. num_headers: the number of name+value pairs that was received and can be accessed p_curl_pushheaders: a handle used to access push headers using the accessor functions described below. This only accesses and provides the PUSH_PROMISE headers, the normal response headers will be provided in the header callback as usual. userp: the pointer set with CURLMOPT_PUSHDATA If the callback returns CURL_PUSH_OK, the 'easy' handle will be added to the multi handle, the callback must not do that by itself. The callback can access PUSH_PROMISE headers with two accessor functions. These functions can only be used from within this callback and they can only access the PUSH_PROMISE headers. The normal response headers will be passed to the header callback for pushed streams just as for normal streams. atom ptr = curl_pushheader_bynum(atom p_curl_pushheaders, integer num) Returns the header at index 'num' (or NULL). The returned pointer points to a "name:value" string that will be freed when this callback returns. atom ptr = curl_pushheader_byname(atom p_curl_pushheaders, string name) Returns the value for the given header name (or NULL). This is a shortcut so that the application doesn’t have to loop through all headers to find the one it is interested in. The data pointed will be freed when this callback returns. If more than one header field use the same name, this returns only the first one. Callback return value CURL_PUSH_OK (0): The application has accepted the stream and it can now start receiving data, the ownership of the CURL handle has been taken over by the application. CURL_PUSH_DENY (1): The callback denies the stream and no data for this will reach the application, the easy handle will be destroyed by libcurl. All other return codes are reserved for future use. Default: NULL, no callback Protocols: HTTP(S) (HTTP/2 only) Example Copy
    include builtins\libcurl.e
    atom multi = curl_multi_init()

    /* only allow pushes for file names starting with "push-" */
    function push_callback(atom parent, easy, integer num_headers, atom p_curl_pushheaders, p_counter)
    --  FILE *out;
        atom ppath = curl_pushheader_byname(headers, ":path");
        if headp!=NULL then
            string path = peek_string(ppath)
            if length(path)>=6 and path[1..6]="/push-" then
                printf(2,"The PATH is %s\n", {path})

                /* save the push here */
    --DEV       out = fopen("pushed-stream", "wb")

                /* write to this file */
                curl_easy_setopt(easy, CURLOPT_WRITEDATA, out)

                integer counter = peekNS(p_counter,machine_word(),true)
                pokeN(p_counter,counter+1,machine_word())   /* one more */

                return CURL_PUSH_OK
            end if
        end if
        return CURL_PUSH_DENY
    end function
    constant push_cb = call_back({'+',routine_id("push_callback")})

    curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_cb)
    atom p_counter = allocate(machine_word())
    pokeN(p_counter,0,machine_word())
    curl_multi_setopt(multi, CURLMOPT_PUSHDATA, p_counter)
Availability: Added in 7.44.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PUSHDATA, CURLMOPT_PIPELINING, CURLOPT_PIPEWAIT, RFC 7540
CURLMOPT_PUSHDATA | Pointer to pass to push callback. Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_PUSHDATA, atom pointer) Set pointer to pass as the last argument to the CURLMOPT_PUSHFUNCTION callback. The pointer will not be touched or used by libcurl itself, only passed on to the callback function. Default: NULL Protocols: HTTP(S) Availability: Added in 7.44.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_PUSHFUNCTION, CURLMOPT_PIPELINING, CURLOPT_PIPEWAIT, RFC 7540
CURLMOPT_SOCKETFUNCTION | Callback informed about what to wait for Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_SOCKETFUNCTION, atom socket_cb) Pass a pointer to your callback function, which should match the prototype shown in the example below. When the curl_multi_socket_action function runs, it informs the application about updates in the socket (file descriptor) status by doing none, one, or multiple calls to the socket_callback. The callback gets status updates with changes since the previous time the callback was called. If the given callback pointer is NULL, no callback will be called. Set the callback’s userp argument with CURLMOPT_SOCKETDATA. See curl_multi_socket_action for more details on how the callback is used and should work. The what parameter informs the callback on the status of the given socket. It can hold one of these values: CURL_POLL_IN: Wait for incoming data. For the socket to become readable. CURL_POLL_OUT: Wait for outgoing data. For the socket to become writable. CURL_POLL_INOUT: Wait for incoming and outgoing data. For the socket to become readable or writable. CURL_POLL_REMOVE: The specified socket/file descriptor is no longer used by libcurl. Default: NULL (no callback) Protocols: All Example Copy
    -- (This example has not been translated)

    --/*
    int socket_callback(CURL *easy,      /* easy handle */
                        curl_socket_t s, /* socket */
                        int what,        /* describes the socket */
                        void *userp,     /* private callback pointer */
                        void *socketp);  /* private socket pointer */

    //CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_SOCKETFUNCTION, socket_callback);

    include builtins\libcurl.e
    atom multi = curl_multi_init()

    static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
    {
      GlobalInfo *g = (GlobalInfo*) cbp;
      SockInfo *fdp = (SockInfo*) sockp;

      if(what == CURL_POLL_REMOVE) {
        remsock(fdp);
      }
      else {
        if(!fdp) {
          addsock(s, e, what, g);
        }
        else {
          setsock(fdp, s, e, what, g);
        }
      }
      return 0;
    }

    main()
    {
      GlobalInfo setup;
      /* ... use socket callback and custom pointer */
      curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
      curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, &setup);
    }
    --*/
Availability: Added in 7.15.4 Return value: Returns CURLM_OK. See also: CURLMOPT_SOCKETDATA, curl_multi_socket_action, CURLMOPT_TIMERFUNCTION
CURLMOPT_SOCKETDATA | Custom pointer passed to the socket callback Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_SOCKETDATA, atom pointer) A data pointer to pass to the socket callback set with the CURLMOPT_SOCKETFUNCTION option. This pointer will not be touched by libcurl but will only be passed in to the socket callbacks’s userp argument. Default: NULL Protocols: All Availability: Added in 7.15.4 Return value: Returns CURLM_OK. See also: CURLMOPT_SOCKETFUNCTION, curl_multi_socket_action, CURLMOPT_TIMERFUNCTION
CURLMOPT_TIMERFUNCTION | Set callback to receive timeout values Synopsis/Example: Copy
    include builtins\libcurl.e

    -- NB this example is incomplete and untested

    function timer_callback(atom curlm, integer timeout_ms, atom userp)
        if timeout_ms=-1 then
            -- delete your timer?? [curl_multi_setopt(curlm, CURLMOPT_TIMERDATA, NULL)?]
        end if
        return 0    -- success
    end function
    constant timer_cb = call_back({'+',routine_id("timer_callback")})

    curl_multi_setopt(curlm, CURLMOPT_TIMERFUNCTION, timer_cb)
Pass a pointer to your callback function, which should match the prototype shown above. Certain features, such as timeouts and retries, require you to call libcurl even when there is no activity on the file descriptors. Your callback function timer_callback should install a non-repeating timer with an interval of timeout_ms. Each time that timer fires, call either curl_multi_socket_action or curl_multi_perform, depending on which interface you use. A timeout_ms value of -1 means you should delete your timer. A timeout_ms value of 0 means you should call curl_multi_socket_action or curl_multi_perform (once) as soon as possible. timer_callback will only be called when the timeout_ms changes. The userp pointer is set with CURLMOPT_TIMERDATA. The timer callback should return 0 on success, and -1 on error. This callback can be used instead of, or in addition to, curl_multi_timeout. Default: NULL Protocols: All Availability: Added in 7.16.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_TIMERDATA, CURLMOPT_SOCKETFUNCTION
CURLMOPT_TIMERDATA | Custom pointer to pass to timer callback Synopsis: CURLMcode res = curl_multi_setopt(atom mcurl, CURLMOPT_TIMERDATA, atom pointer) A data pointer to pass to the timer callback set with the CURLMOPT_TIMERFUNCTION option. This pointer will not be touched by libcurl but will only be passed in to the timer callbacks’s userp argument. Default: NULL Protocols: All Availability: Added in 7.16.0 Return value: Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. See also: CURLMOPT_TIMERFUNCTION, CURLMOPT_SOCKETFUNCTION
See Also: | SEE ALSO , , curl_multi_socket, curl_multi_init, curl_multi_cleanup, curl_multi_info_read