X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=php_http_curl_client.c;h=bf04651d00ccec16dbe0530ce724e46f433de357;hb=5df3bfd0128ebd48de13c95fc459110eb0463c30;hp=a285397fb124613cee728fea306b8343dcb8c790;hpb=eebe0f3e8947ecb407451d20aef0611cfcedfdac;p=m6w6%2Fext-http diff --git a/php_http_curl_client.c b/php_http_curl_client.c index a285397..bf04651 100644 --- a/php_http_curl_client.c +++ b/php_http_curl_client.c @@ -175,15 +175,22 @@ static int php_http_curl_client_raw_callback(CURL *ch, curl_infotype type, char switch (type) { case CURLINFO_HEADER_IN: case CURLINFO_DATA_IN: - case CURLINFO_HEADER_OUT: - case CURLINFO_DATA_OUT: - php_http_buffer_append(h->buffer, data, length); + php_http_buffer_append(h->response.buffer, data, length); if (curl->options.redirects) { flags |= PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS; } - if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->parser, h->buffer, flags, &h->message)) { + if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->response.parser, h->response.buffer, flags, &h->response.message)) { + return -1; + } + break; + + case CURLINFO_HEADER_OUT: + case CURLINFO_DATA_OUT: + php_http_buffer_append(h->request.buffer, data, length); + + if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->request.parser, h->request.buffer, flags, &h->request.message)) { return -1; } break; @@ -510,11 +517,13 @@ static STATUS set_options(php_http_client_t *h, HashTable *options) zval **cookie_val; FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) { - if (cookie_key.type == HASH_KEY_IS_STRING) { - zval *val = php_http_ztyp(IS_STRING, *cookie_val); - php_http_buffer_appendf(&curl->options.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val)); - zval_ptr_dtor(&val); - } + zval *val = php_http_ztyp(IS_STRING, *cookie_val); + + php_http_array_hashkey_stringify(&cookie_key); + php_http_buffer_appendf(&curl->options.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val)); + php_http_array_hashkey_stringfree(&cookie_key); + + zval_ptr_dtor(&val); } php_http_buffer_fix(&curl->options.cookies); @@ -565,6 +574,19 @@ static STATUS set_options(php_http_client_t *h, HashTable *options) if ((zoption = get_option(&curl->options.cache, options, ZEND_STRS("connecttimeout"), IS_DOUBLE))) { curl_easy_setopt(ch, CURLOPT_CONNECTTIMEOUT_MS, (long)(Z_DVAL_P(zoption)*1000)); } + +#if PHP_HTTP_CURL_VERSION(7,25,0) + /* tcp */ + if ((zoption = get_option(&curl->options.cache, options, ZEND_STRS("tcp_keepalive"), IS_BOOL))) { + curl_easy_setopt(ch, CURLOPT_TCP_KEEPALIVE, (long)Z_BVAL_P(zoption)); + } + if ((zoption = get_option(&curl->options.cache, options, ZEND_STRS("tcp_keepidle"), IS_LONG))) { + curl_easy_setopt(ch, CURLOPT_TCP_KEEPIDLE, Z_LVAL_P(zoption)); + } + if ((zoption = get_option(&curl->options.cache, options, ZEND_STRS("tcp_keepintvl"), IS_LONG))) { + curl_easy_setopt(ch, CURLOPT_TCP_KEEPINTVL, Z_LVAL_P(zoption)); + } +#endif /* ssl */ if ((zoption = get_option(&curl->options.cache, options, ZEND_STRS("ssl"), IS_ARRAY))) { @@ -962,7 +984,12 @@ static STATUS php_http_curl_client_reset(php_http_client_t *h) curl_easy_setopt(ch, CURLOPT_TIMECONDITION, 0L); curl_easy_setopt(ch, CURLOPT_TIMEVALUE, 0L); curl_easy_setopt(ch, CURLOPT_TIMEOUT, 0L); - curl_easy_setopt(ch, CURLOPT_CONNECTTIMEOUT, 3); + curl_easy_setopt(ch, CURLOPT_CONNECTTIMEOUT, 3L); +#if PHP_HTTP_CURL_VERSION(7,25,0) + curl_easy_setopt(ch, CURLOPT_TCP_KEEPALIVE, 0L); + curl_easy_setopt(ch, CURLOPT_TCP_KEEPIDLE, 60L); + curl_easy_setopt(ch, CURLOPT_TCP_KEEPINTVL, 60L); +#endif curl_easy_setopt(ch, CURLOPT_SSLCERT, NULL); curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, NULL); curl_easy_setopt(ch, CURLOPT_SSLCERTPASSWD, NULL); @@ -1024,8 +1051,9 @@ static STATUS php_http_curl_client_reset(php_http_client_t *h) return SUCCESS; } -STATUS php_http_curl_client_prepare(php_http_client_t *h, php_http_message_t *msg) +PHP_HTTP_API STATUS php_http_curl_client_prepare(php_http_client_t *h, php_http_message_t *msg) { + size_t body_size; php_http_curl_client_t *curl = h->ctx; php_http_curl_client_storage_t *storage = get_storage(curl->handle); TSRMLS_FETCH_FROM_CTX(h->ts); @@ -1072,6 +1100,7 @@ STATUS php_http_curl_client_prepare(php_http_client_t *h, php_http_message_t *ms } /* request headers */ + php_http_message_update_headers(msg); if (zend_hash_num_elements(&msg->hdrs)) { php_http_array_hashkey_t header_key = php_http_array_hashkey_init(0); zval **header_val; @@ -1096,15 +1125,14 @@ STATUS php_http_curl_client_prepare(php_http_client_t *h, php_http_message_t *ms } /* attach request body */ - { + if ((body_size = php_http_message_body_size(&msg->body))) { /* RFC2616, section 4.3 (para. 4) states that »a message-body MUST NOT be included in a request if the * specification of the request method (section 5.1.1) does not allow sending an entity-body in request.« * Following the clause in section 5.1.1 (para. 2) that request methods »MUST be implemented with the * same semantics as those specified in section 9« reveal that not any single defined HTTP/1.1 method * does not allow a request body. */ - size_t body_size = php_http_message_body_size(&msg->body); - + php_stream_rewind(php_http_message_body_stream(&msg->body)); curl_easy_setopt(curl->handle, CURLOPT_IOCTLDATA, &msg->body); curl_easy_setopt(curl->handle, CURLOPT_READDATA, &msg->body); curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE, body_size); @@ -1245,11 +1273,6 @@ static php_http_resource_factory_ops_t php_http_curl_client_resource_factory_ops php_http_curl_dtor }; -static zend_class_entry *get_class_entry(void) -{ - return php_http_curl_client_class_entry; -} - static php_http_client_ops_t php_http_curl_client_ops = { &php_http_curl_client_resource_factory_ops, php_http_curl_client_init, @@ -1260,7 +1283,7 @@ static php_http_client_ops_t php_http_curl_client_ops = { php_http_curl_client_setopt, php_http_curl_client_getopt, (php_http_new_t) php_http_curl_client_object_new_ex, - get_class_entry + php_http_curl_client_get_class_entry }; PHP_HTTP_API php_http_client_ops_t *php_http_curl_client_get_ops(void) @@ -1274,12 +1297,18 @@ PHP_HTTP_API php_http_client_ops_t *php_http_curl_client_get_ops(void) #define PHP_HTTP_CURL_CLIENT_ME(method, visibility) PHP_ME(HttpClientCURL, method, PHP_HTTP_ARGS(HttpClientCURL, method), visibility) #define PHP_HTTP_CURL_CLIENT_CLIENT_MALIAS(me, vis) ZEND_FENTRY(me, ZEND_MN(HttpClient_##me), PHP_HTTP_ARGS(HttpClientCURL, me), vis) -PHP_HTTP_BEGIN_ARGS(send, 1) +PHP_HTTP_BEGIN_ARGS(send, 0) PHP_HTTP_ARG_VAL(request, 0) PHP_HTTP_END_ARGS; -zend_class_entry *php_http_curl_client_class_entry; -zend_function_entry php_http_curl_client_method_entry[] = { +static zend_class_entry *php_http_curl_client_class_entry; + +zend_class_entry *php_http_curl_client_get_class_entry(void) +{ + return php_http_curl_client_class_entry; +} + +static zend_function_entry php_http_curl_client_method_entry[] = { PHP_HTTP_CURL_CLIENT_CLIENT_MALIAS(send, ZEND_ACC_PUBLIC) EMPTY_FUNCTION_ENTRY };