From 76b679d046ac10c00eb13da217f2adaaad580251 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 7 Sep 2016 14:55:24 +0200 Subject: [PATCH] attempt to fix that HTTP/2 nonsense --- src/php_http_info.c | 42 +++++++++++++++++++++++++++++++++++++++++- src/php_http_info.h | 16 +--------------- src/php_http_message.c | 37 ++++++++----------------------------- src/php_http_version.c | 7 ++++++- tests/client022.phpt | 2 +- tests/client029.phpt | 2 +- 6 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/php_http_info.c b/src/php_http_info.c index 13bf124..81bf727 100644 --- a/src/php_http_info.c +++ b/src/php_http_info.c @@ -49,6 +49,46 @@ void php_http_info_free(php_http_info_t **i) } } +void php_http_info_to_string(php_http_info_t *info, char **str, size_t *len, const char *eol TSRMLS_DC) +{ + char *tmp = NULL; + + if (info->http.version.major == 2) { + if (info->type == PHP_HTTP_REQUEST) { + *len = spprintf(str, 0, "%s %s HTTP/2%s", + info->http.info.request.method?info->http.info.request.method:"UNKNOWN", + info->http.info.request.method&&!strcasecmp(info->http.info.request.method,"CONNECT")?( + info->http.info.request.url?php_http_url_authority_to_string(info->http.info.request.url, &(tmp), NULL):"0"):( + info->http.info.request.url?php_http_url_to_string(info->http.info.request.url, &(tmp), NULL, 0):"/"), + eol); + } else if (info->type == PHP_HTTP_RESPONSE) { + *len = spprintf(str, 0, "HTTP/2 %d%s%s%s", + info->http.info.response.code?info->http.info.response.code:200, + info->http.info.response.status&&*info->http.info.response.status ? " ":"", + STR_PTR(info->http.info.response.status), + eol); + } + } else if (info->type == PHP_HTTP_REQUEST) { + *len = spprintf(str, 0, "%s %s HTTP/%u.%u%s", + info->http.info.request.method?info->http.info.request.method:"UNKNOWN", + info->http.info.request.method&&!strcasecmp(info->http.info.request.method,"CONNECT")?( + info->http.info.request.url?php_http_url_authority_to_string(info->http.info.request.url, &(tmp), NULL):"0"):( + info->http.info.request.url?php_http_url_to_string(info->http.info.request.url, &(tmp), NULL, 0):"/"), + info->http.version.major||info->http.version.major?info->http.version.major:1, + info->http.version.major||info->http.version.minor?info->http.version.minor:1, + eol); + } else if (info->type == PHP_HTTP_RESPONSE){ + *len = spprintf(str, 0, "HTTP/%u.%u %d%s%s%s", info->http.version.major||info->http.version.major?info->http.version.major:1, + info->http.version.major||info->http.version.minor?info->http.version.minor:1, + info->http.info.response.code?info->http.info.response.code:200, + info->http.info.response.status&&*info->http.info.response.status ? " ":"", + STR_PTR(info->http.info.response.status), + eol); + } + + STR_FREE(tmp); +} + php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_header TSRMLS_DC) { const char *end, *http, *off; @@ -80,7 +120,7 @@ php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_head /* clumsy fix for changed libcurl behaviour in 7.49.1, see https://github.com/curl/curl/issues/888 */ off = &http[lenof("HTTP/X")]; - if (info->http.version.major < 2) { + if (info->http.version.major < 2 || (info->http.version.major == 2 && *off == '.')) { off += 2; } diff --git a/src/php_http_info.h b/src/php_http_info.h index 4f02908..e1cce6f 100644 --- a/src/php_http_info.h +++ b/src/php_http_info.h @@ -16,21 +16,6 @@ #include "php_http_version.h" #include "php_http_url.h" -#define PHP_HTTP_INFO_REQUEST_FMT_ARGS(_http_ptr, tmp, eol) "%s %s HTTP/%u.%u" eol, \ - (_http_ptr)->info.request.method?(_http_ptr)->info.request.method:"UNKNOWN", \ - (_http_ptr)->info.request.method&&!strcasecmp((_http_ptr)->info.request.method,"CONNECT")?( \ - (_http_ptr)->info.request.url?php_http_url_authority_to_string((_http_ptr)->info.request.url, &(tmp), NULL):"0"):( \ - (_http_ptr)->info.request.url?php_http_url_to_string((_http_ptr)->info.request.url, &(tmp), NULL, 0):"/"), \ - (_http_ptr)->version.major||(_http_ptr)->version.major?(_http_ptr)->version.major:1, \ - (_http_ptr)->version.major||(_http_ptr)->version.minor?(_http_ptr)->version.minor:1 - -#define PHP_HTTP_INFO_RESPONSE_FMT_ARGS(_http_ptr, tmp, eol) "HTTP/%u.%u %d%s%s" eol, \ - (_http_ptr)->version.major||(_http_ptr)->version.major?(_http_ptr)->version.major:1, \ - (_http_ptr)->version.major||(_http_ptr)->version.minor?(_http_ptr)->version.minor:1, \ - (_http_ptr)->info.response.code?(_http_ptr)->info.response.code:200, \ - (_http_ptr)->info.response.status&&*(_http_ptr)->info.response.status ? " ":"", \ - STR_PTR((_http_ptr)->info.response.status) - typedef struct php_http_info_data { union { /* GET /foo/bar */ @@ -60,6 +45,7 @@ typedef zend_bool (*php_http_info_callback_t)(void **callback_data, HashTable ** PHP_HTTP_API php_http_info_t *php_http_info_init(php_http_info_t *info TSRMLS_DC); PHP_HTTP_API php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_header TSRMLS_DC); +PHP_HTTP_API void php_http_info_to_string(php_http_info_t *info, char **str, size_t *len, const char *eol TSRMLS_DC); PHP_HTTP_API void php_http_info_dtor(php_http_info_t *info); PHP_HTTP_API void php_http_info_free(php_http_info_t **info); diff --git a/src/php_http_message.c b/src/php_http_message.c index 0701af0..60569b8 100644 --- a/src/php_http_message.c +++ b/src/php_http_message.c @@ -358,25 +358,15 @@ void php_http_message_update_headers(php_http_message_t *msg) static void message_headers(php_http_message_t *msg, php_http_buffer_t *str) { char *tmp = NULL; + size_t len = 0; TSRMLS_FETCH_FROM_CTX(msg->ts); - switch (msg->type) { - case PHP_HTTP_REQUEST: - php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF)); - PTR_FREE(tmp); - break; - - case PHP_HTTP_RESPONSE: - php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF)); - PTR_FREE(tmp); - break; - - default: - break; - } - + php_http_info_to_string((php_http_info_t *) msg, &tmp, &len, PHP_HTTP_CRLF TSRMLS_CC); php_http_message_update_headers(msg); + + php_http_buffer_append(str, tmp, len); php_http_header_to_string(str, &msg->hdrs TSRMLS_CC); + STR_FREE(tmp); } void php_http_message_to_callback(php_http_message_t *msg, php_http_pass_callback_t cb, void *cb_arg) @@ -1391,24 +1381,13 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, getInfo) { if (SUCCESS == zend_parse_parameters_none()) { - char *tmp = NULL; + size_t len = 0; php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - switch (obj->message->type) { - case PHP_HTTP_REQUEST: - Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&obj->message->http, tmp, "")); - PTR_FREE(tmp); - break; - case PHP_HTTP_RESPONSE: - Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&obj->message->http, tmp, "")); - PTR_FREE(tmp); - break; - default: - RETURN_NULL(); - break; - } + php_http_info_to_string((php_http_info_t *) obj->message, &Z_STRVAL_P(return_value), &len, "" TSRMLS_CC); + Z_STRLEN_P(return_value) = len; Z_TYPE_P(return_value) = IS_STRING; return; } diff --git a/src/php_http_version.c b/src/php_http_version.c index c861a64..2cba01e 100644 --- a/src/php_http_version.c +++ b/src/php_http_version.c @@ -73,7 +73,12 @@ php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *st void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post TSRMLS_DC) { - *len = spprintf(str, 0, "%s%u.%u%s", pre ? pre : "", v->major, v->minor, post ? post : ""); + /* different semantics for different versions */ + if (v->major == 2) { + *len = spprintf(str, 0, "%s2%s", STR_PTR(pre), STR_PTR(post)); + } else { + *len = spprintf(str, 0, "%s%u.%u%s", STR_PTR(pre), v->major, v->minor, STR_PTR(post)); + } } void php_http_version_dtor(php_http_version_t *v) diff --git a/tests/client022.phpt b/tests/client022.phpt index a59971c..e813cdc 100644 --- a/tests/client022.phpt +++ b/tests/client022.phpt @@ -31,7 +31,7 @@ nghttpd(function($port) { ===DONE=== --EXPECTF-- Test -HTTP/2.0 200 +HTTP/2 200 %a diff --git a/tests/client029.phpt b/tests/client029.phpt index 2ed6d79..fc42500 100644 --- a/tests/client029.phpt +++ b/tests/client029.phpt @@ -23,7 +23,7 @@ class UserHandler implements http\Client\Curl\User $this->client = $client; } - function init(callable $run) { + function init($run) { $this->run = $run; } -- 2.30.2