}
}
+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;
/* 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;
}
#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 */
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);
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)
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;
}
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)
===DONE===
--EXPECTF--
Test
-HTTP/2.0 200
+HTTP/2 200
%a
<!doctype html>
$this->client = $client;
}
- function init(callable $run) {
+ function init($run) {
$this->run = $run;
}