Skip to content

Commit

Permalink
fixed http2 cookie bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Feb 1, 2018
1 parent aa4e9d3 commit a91d9c1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 35 deletions.
61 changes: 47 additions & 14 deletions swoole_http_v2_client.c
Expand Up @@ -26,6 +26,8 @@ static zend_class_entry *swoole_http2_client_class_entry_ptr;
static zend_class_entry swoole_http2_response_ce;
zend_class_entry *swoole_http2_response_class_entry_ptr;

swString *cookie_buffer = NULL;

enum
{
HTTP2_CLIENT_PROPERTY_INDEX = 3,
Expand Down Expand Up @@ -98,9 +100,15 @@ void swoole_http2_client_init(int module_number TSRMLS_DC)
swoole_http2_response_class_entry_ptr = zend_register_internal_class(&swoole_http2_response_ce TSRMLS_CC);
SWOOLE_CLASS_ALIAS(swoole_http2_response, "Swoole\\Http2\\Response");

zend_declare_property_long(swoole_http2_response_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_long(swoole_http2_response_class_entry_ptr, SW_STRL("statusCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_null(swoole_http2_response_class_entry_ptr, SW_STRL("body")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_null(swoole_http2_response_class_entry_ptr, SW_STRL("streamId")-1, ZEND_ACC_PUBLIC TSRMLS_CC);

if (cookie_buffer == NULL)
{
cookie_buffer = swString_new(8192);
}
}

static PHP_METHOD(swoole_http2_client, __construct)
Expand Down Expand Up @@ -226,7 +234,7 @@ static int http2_client_build_header(zval *zobject, http2_client_request *req, c
}
if (strncasecmp("Host", key, keylen) == 0)
{
http2_add_header(&nv[3], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value));
http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value));
find_host = 1;
}
else
Expand All @@ -239,25 +247,14 @@ static int http2_client_build_header(zval *zobject, http2_client_request *req, c
}
if (!find_host)
{
http2_add_header(&nv[3], ZEND_STRL(":authority"), hcc->host, hcc->host_len);
http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), hcc->host, hcc->host_len);
}

zval *zcookie = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), 1 TSRMLS_CC);
//http cookies
if (zcookie && !ZVAL_IS_NULL(zcookie))
{
zend_size_t len;
smart_str formstr_s = { 0 };
char *formstr = sw_http_build_query(zcookie, &len, &formstr_s TSRMLS_CC);
if (formstr == NULL)
{
swoole_php_error(E_WARNING, "http_build_query failed.");
}
else
{
http2_add_header(&nv[3], ZEND_STRL("cookie"), formstr, len);
smart_str_free(&formstr_s);
}
http2_add_cookie(&nv, &index, zcookie TSRMLS_CC);
}

ssize_t rv;
Expand Down Expand Up @@ -308,6 +305,42 @@ static int http2_client_build_header(zval *zobject, http2_client_request *req, c
return rv;
}

void http2_add_cookie(nghttp2_nv *nv, int *index, zval *cookies TSRMLS_DC)
{
char *key;
uint32_t keylen;
int keytype;
zval *value = NULL;
char *encoded_value;
uint32_t offest = 0;
swString_clear(cookie_buffer);

SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(cookies), key, keylen, keytype, value)
if (HASH_KEY_IS_STRING != keytype)
{
continue;
}
convert_to_string(value);
if (Z_STRLEN_P(value) == 0)
{
continue;
}

swString_append_ptr(cookie_buffer, key, keylen);
swString_append_ptr(cookie_buffer, "=", 1);

int encoded_value_len;
encoded_value = sw_php_url_encode(Z_STRVAL_P(value), Z_STRLEN_P(value), &encoded_value_len);
if (encoded_value)
{
swString_append_ptr(cookie_buffer, encoded_value, encoded_value_len);
efree(encoded_value);
http2_add_header(&nv[(*index)++], ZEND_STRL("cookie"), cookie_buffer->str + offest, keylen + 1 + encoded_value_len);
offest += keylen + 1 + encoded_value_len;
}
SW_HASHTABLE_FOREACH_END();
}

int http2_client_parse_header(http2_client_property *hcc, http2_client_stream *stream , int flags, char *in, size_t inlen)
{
#if PHP_MAJOR_VERSION < 7
Expand Down
9 changes: 7 additions & 2 deletions swoole_http_v2_client.h
Expand Up @@ -23,6 +23,8 @@
#include "http.h"
#include "http2.h"

#define HTTP2_CLIENT_HOST_HEADER_INDEX 3

#ifdef SW_HAVE_ZLIB
#include <zlib.h>
extern voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size);
Expand Down Expand Up @@ -98,8 +100,6 @@ static sw_inline void http2_client_init_gzip_stream(http2_client_stream *stream)

int http2_client_parse_header(http2_client_property *hcc, http2_client_stream *stream , int flags, char *in, size_t inlen);

extern zend_class_entry *swoole_client_class_entry_ptr;

static sw_inline void http2_client_send_setting(swClient *cli)
{
uint16_t id = 0;
Expand Down Expand Up @@ -152,4 +152,9 @@ static sw_inline void http2_add_header(nghttp2_nv *headers, char *k, int kl, cha
swTrace("k=%s, len=%d, v=%s, len=%d", k, kl, v, vl);
}

void http2_add_cookie(nghttp2_nv *nv, int *index, zval *cookies TSRMLS_DC);

extern swString *cookie_buffer;
extern zend_class_entry *swoole_client_class_entry_ptr;

#endif
27 changes: 8 additions & 19 deletions swoole_http_v2_client_coro.c
Expand Up @@ -216,7 +216,7 @@ static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int
}
if (strncasecmp("Host", key, keylen) == 0)
{
http2_add_header(&nv[3], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value));
http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value));
find_host = 1;
}
else
Expand All @@ -229,24 +229,13 @@ static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int
}
if (!find_host)
{
http2_add_header(&nv[3], ZEND_STRL(":authority"), hcc->host, hcc->host_len);
http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), hcc->host, hcc->host_len);
}

//http cookies
if (cookies && !ZVAL_IS_NULL(cookies))
{
zend_size_t len;
smart_str formstr_s = { 0 };
char *formstr = sw_http_build_query(cookies, &len, &formstr_s TSRMLS_CC);
if (formstr == NULL)
{
swoole_php_error(E_WARNING, "http_build_query failed.");
}
else
{
http2_add_header(&nv[3], ZEND_STRL("cookie"), formstr, len);
smart_str_free(&formstr_s);
}
http2_add_cookie(&nv, &index, cookies TSRMLS_CC);
}

ssize_t rv;
Expand Down Expand Up @@ -301,6 +290,7 @@ static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length)
{
int type = buf[3];
int flags = buf[4];
int error_code;
int stream_id = ntohl((*(int *) (buf + 5))) & 0x7fffffff;
uint32_t length = swHttp2_get_length(buf);
buf += SW_HTTP2_FRAME_HEADER_SIZE;
Expand Down Expand Up @@ -375,7 +365,7 @@ static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length)
{
int last_stream_id = htonl(*(int *) (buf));
buf += 4;
int error_code = htonl(*(int *) (buf));
error_code = htonl(*(int *) (buf));
swWarn("["SW_ECHO_RED"] last_stream_id=%d, error_code=%d.", "GOAWAY", last_stream_id, error_code);

zval* retval;
Expand All @@ -391,10 +381,8 @@ static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length)
}
else if (type == SW_HTTP2_TYPE_RST_STREAM)
{
int last_stream_id = htonl(*(int *) (buf));
buf += 4;
int error_code = htonl(*(int *) (buf));
swWarn("["SW_ECHO_RED"] last_stream_id=%d, error_code=%d.", "RST_STREAM", last_stream_id, error_code);
error_code = htonl(*(int *) (buf));
swWarn("["SW_ECHO_RED"] stream_id=%d, error_code=%d.", "RST_STREAM", stream_id, error_code);

if (hcc->iowait == 0)
{
Expand Down Expand Up @@ -444,6 +432,7 @@ static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length)
if (type == SW_HTTP2_TYPE_RST_STREAM)
{
zend_update_property_long(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("statusCode"), -3 TSRMLS_CC);
zend_update_property_long(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("errCode"), error_code TSRMLS_CC);
}

if (stream->buffer)
Expand Down

0 comments on commit a91d9c1

Please sign in to comment.