diff --git a/ext-src/php_swoole_http.h b/ext-src/php_swoole_http.h index 71a7613fcf0..1c8107e63d4 100644 --- a/ext-src/php_swoole_http.h +++ b/ext-src/php_swoole_http.h @@ -114,6 +114,115 @@ struct Response { zval _ztrailer; }; +struct ByteBuffer { + const char *protocol = nullptr; + const char *status = nullptr; + const char *reason = nullptr; + + size_t http_status_length = 0; + size_t http_headers_length = 0; + + int index = 0; + size_t *lengths; + const char **headers; + + int free_num = 0; + zend_string **free_list; + + ByteBuffer(size_t *_lengths, const char **_headers, zend_string **_free_list) { + lengths = _lengths; + headers = _headers; + free_list = _free_list; + } + + ~ByteBuffer() { + int i = 0; + while (i < free_num) { + zend_string_release(free_list[i++]); + } + } + + inline void add_status(const char *_status, const char *_reason) { + protocol = "HTTP/1.1 "; + status = _status; + reason = _reason; + // calculate http status line length + if (!reason) { + http_status_length = strlen(protocol) + strlen(status) + SW_CRLF_LEN; + } else { + http_status_length = strlen(protocol) + strlen(status) + strlen(reason) + SW_CRLF_LEN + 1; + } + } + + inline void add_header(zend_string *key, zend_string *value) { + zend_string_addref(key); + zend_string_addref(value); + free_list[free_num++] = key; + free_list[free_num++] = value; + add_header(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(value), ZSTR_LEN(value)); + } + + inline void add_header(const char *key, size_t key_length, const char *value, size_t value_length) { + headers[index] = key; + lengths[index] = key_length; + index++; + + headers[index] = value; + lengths[index] = value_length; + index++; + + if (value) { + http_headers_length += key_length + value_length + SW_CRLF_LEN + 2; + } else { + // When the value is a nullptr, it means that this response header has a fixed value. + http_headers_length += key_length; + } + } + + inline size_t get_protocol_length(size_t length = 0) { + // calculate http protocol length + return http_status_length + http_headers_length + length + SW_CRLF_LEN; + } + + void write_protocol(String *http_buffer, const char *data, size_t length) { + http_buffer->append(protocol, strlen(protocol)); + http_buffer->append(status, strlen(status)); + if (reason) { + http_buffer->append(" ", 1); + http_buffer->append(reason, strlen(reason)); + } + http_buffer->append(SW_CRLF, SW_CRLF_LEN); + + size_t key_length = 0; + size_t value_length = 0; + const char *key = nullptr; + const char *value = nullptr; + int i = 0; + + while (i < index) { + key_length = lengths[i]; + value_length = lengths[i + 1]; + key = headers[i++]; + value = headers[i++]; + + if (value == nullptr) { + http_buffer->append(key, key_length); + continue; + } + + http_buffer->append(key, key_length); + http_buffer->append(ZEND_STRL(": ")); + http_buffer->append(value, value_length); + http_buffer->append(SW_CRLF, SW_CRLF_LEN); + } + + http_buffer->append(SW_CRLF, SW_CRLF_LEN); + if (data) { + http_buffer->append(data, length); + } + } +}; + struct Context { SessionId fd; uchar completed : 1; @@ -192,8 +301,8 @@ struct Context { void end(zval *zdata, zval *return_value); bool send_file(const char *file, uint32_t l_file, off_t offset, size_t length); void send_trailer(zval *return_value); - String *get_write_buffer(); - void build_header(String *http_buffer, const char *body, size_t length); + String *get_write_buffer(size_t capacity = SW_BUFFER_SIZE_STD); + void build_header(const char *body, size_t length); ssize_t build_trailer(String *http_buffer); size_t get_content_length() { @@ -212,7 +321,6 @@ struct Context { bool is_available(); void free(); }; - } // namespace http namespace http2 { diff --git a/ext-src/php_swoole_private.h b/ext-src/php_swoole_private.h index 2b05b58b885..3d5652f5100 100644 --- a/ext-src/php_swoole_private.h +++ b/ext-src/php_swoole_private.h @@ -709,11 +709,12 @@ static sw_inline void sw_zend_update_property_null_ex(zend_class_entry *scope, z zend_update_property_ex(scope, SW_Z8_OBJ_P(object), s, &tmp); } -static sw_inline zval *sw_zend_read_property_ex(zend_class_entry *ce, zval *obj, zend_string *s, int silent) { - zval rv, *property = zend_read_property_ex(ce, SW_Z8_OBJ_P(obj), s, silent, &rv); +static sw_inline zval *sw_zend_read_property_ex(zend_class_entry *ce, zval *zobject, zend_string *name, int silent) { + zval *zv = zend_hash_find(&ce->properties_info, name); + zend_property_info *property_info = (zend_property_info *) Z_PTR_P(zv); + zval *property = OBJ_PROP(SW_Z8_OBJ_P(zobject), property_info->offset); if (UNEXPECTED(property == &EG(uninitialized_zval))) { - sw_zend_update_property_null_ex(ce, obj, s); - return zend_read_property_ex(ce, SW_Z8_OBJ_P(obj), s, silent, &rv); + ZVAL_NULL(property); } return property; } @@ -946,11 +947,8 @@ static sw_inline int php_swoole_check_reactor() { } } -static sw_inline char *php_swoole_format_date(char *format, size_t format_len, time_t ts, int localtime) { - zend_string *time = php_format_date(format, format_len, ts, localtime); - char *return_str = estrndup(ZSTR_VAL(time), ZSTR_LEN(time)); - zend_string_release(time); - return return_str; +static sw_inline zend_string *php_swoole_format_date(char *format, size_t format_len, time_t ts, int localtime) { + return php_format_date(format, format_len, ts, localtime); } static sw_inline char *php_swoole_url_encode(const char *value, size_t value_len, size_t *exten) { diff --git a/ext-src/swoole_http2_server.cc b/ext-src/swoole_http2_server.cc index 37acbbecdf3..3288677ca6e 100644 --- a/ext-src/swoole_http2_server.cc +++ b/ext-src/swoole_http2_server.cc @@ -306,11 +306,11 @@ static void http2_server_set_date_header(Http2::HeaderSet *headers) { time_t now = time(nullptr); if (now != cache.time) { - char *date_str = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0); - cache.len = strlen(date_str); - memcpy(cache.buf, date_str, cache.len); + zend_string *date = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0); + memcpy(cache.buf, ZSTR_VAL(date), ZSTR_LEN(date)); + cache.len = ZSTR_LEN(date); cache.time = now; - efree(date_str); + zend_string_release(date); } headers->add(ZEND_STRL("date"), cache.buf, cache.len); } diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 9eb633d5e22..6fbb200b206 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -38,6 +38,7 @@ using swoole::coroutine::Socket; using HttpResponse = swoole::http::Response; using HttpContext = swoole::http::Context; +using HttpByteBuffer = swoole::http::ByteBuffer; namespace WebSocket = swoole::websocket; namespace HttpServer = swoole::http_server; @@ -63,12 +64,12 @@ static inline void http_header_key_format(char *key, int length) { } } -String *HttpContext::get_write_buffer() { +String *HttpContext::get_write_buffer(size_t capacity) { if (co_socket) { return ((Socket *) private_data)->get_write_buffer(); } else { if (!write_buffer) { - write_buffer = new String(SW_BUFFER_SIZE_STD, sw_php_allocator()); + write_buffer = new String(capacity, sw_php_allocator()); } return write_buffer; } @@ -223,13 +224,10 @@ static PHP_METHOD(swoole_http_response, write) { #ifdef SW_HAVE_COMPRESSION ctx->accept_compression = 0; #endif - String *http_buffer = ctx->get_write_buffer(); - if (!ctx->send_header_) { ctx->send_chunked = 1; - http_buffer->clear(); - ctx->build_header(http_buffer, nullptr, 0); + ctx->build_header(nullptr, 0); if (!ctx->send(ctx, http_buffer->str, http_buffer->length)) { ctx->send_chunked = 0; ctx->send_header_ = 0; @@ -288,7 +286,7 @@ static int parse_header_name(const char *key, size_t keylen) { return 0; } -static void http_set_date_header(String *response) { +static void http_set_date_header(HttpByteBuffer *http_byte_buffer) { static struct { time_t time; size_t len; @@ -297,18 +295,16 @@ static void http_set_date_header(String *response) { time_t now = time(nullptr); if (now != cache.time) { - char *date_str = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0); - cache.len = strlen(date_str); - memcpy(cache.buf, date_str, cache.len); - efree(date_str); + zend_string *date = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0); + memcpy(cache.buf, ZSTR_VAL(date), ZSTR_LEN(date)); + cache.len = ZSTR_LEN(date); cache.time = now; + zend_string_release(date); } - response->append(ZEND_STRL("Date: ")); - response->append(cache.buf, cache.len); - response->append(ZEND_STRL("\r\n")); + http_byte_buffer->add_header(ZEND_STRL("Date"), cache.buf, cache.len); } -static void add_custom_header(String *response, const char *key, size_t l_key, zval *value) { +static void add_custom_header(HttpByteBuffer *http_byte_buffer, zend_string *key, zval *value) { if (ZVAL_IS_NULL(value)) { return; } @@ -317,38 +313,57 @@ static void add_custom_header(String *response, const char *key, size_t l_key, z if (swoole_http_has_crlf(str_value.val(), str_value.len())) { return; } - response->append(key, l_key); - response->append(SW_STRL(": ")); - response->append(str_value.val(), str_value.len()); - response->append(SW_STRL("\r\n")); + + http_byte_buffer->add_header(key, str_value.get()); } -void HttpContext::build_header(String *http_buffer, const char *body, size_t length) { +void HttpContext::build_header(const char *body, size_t length) { assert(send_header_ == 0); + String *http_buffer = nullptr; + + int count = 6; + zval *zheader = + sw_zend_read_property_ex(swoole_http_response_ce, response.zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_HEADER), 0); + if (ZVAL_IS_ARRAY(zheader)) { + count += zend_hash_num_elements(Z_ARRVAL_P(zheader)); + zval *zvalue = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zheader), zvalue) { + if (ZVAL_IS_ARRAY(zvalue)) { + count += zend_hash_num_elements(Z_ARRVAL_P(zvalue)) - 1; + } + } + ZEND_HASH_FOREACH_END(); + } + + zval *zcookie = + sw_zend_read_property_ex(swoole_http_response_ce, response.zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_COOKIE), 0); + if (ZVAL_IS_ARRAY(zcookie)) { + count += zend_hash_num_elements(Z_ARRVAL_P(zcookie)); + } + int total = count * 2; + size_t lengths[total]; + const char *headers[total]; /** - * http status line + * We need to convert the key and value of numeric types into strings so that we can write them into a buffer. + * However, after the conversion, we need to manually release the resulting strings to avoid automatic release + * before writing them into the buffer. */ + zend_string *free_list[total]; + ByteBuffer http_byte_buffer(lengths, headers, free_list); + + // http status line + char status_to_string[16]; if (!response.reason) { - const char *status = HttpServer::get_status_message(response.status); - http_buffer->append(ZEND_STRL("HTTP/1.1 ")); - http_buffer->append((char *) status, strlen(status)); - http_buffer->append(ZEND_STRL("\r\n")); + http_byte_buffer.add_status(HttpServer::get_status_message(response.status), nullptr); } else { - http_buffer->append(ZEND_STRL("HTTP/1.1 ")); - http_buffer->append(response.status); - http_buffer->append(ZEND_STRL(" ")); - http_buffer->append(response.reason, strlen(response.reason)); - http_buffer->append(ZEND_STRL("\r\n")); + int length = swoole_itoa(status_to_string, response.status); + status_to_string[length] = '\0'; + http_byte_buffer.add_status(status_to_string, response.reason); } + // http header uint32_t header_flags = 0x0; - - /** - * http header - */ - zval *zheader = - sw_zend_read_property_ex(swoole_http_response_ce, response.zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_HEADER), 0); if (ZVAL_IS_ARRAY(zheader)) { zval *zvalue; zend_string *string_key; @@ -360,10 +375,9 @@ void HttpContext::build_header(String *http_buffer, const char *body, size_t len ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zheader), num_key, string_key, zvalue) { if (!string_key) { string_key = zend_long_to_str(num_key); - } else { - zend_string_addref(string_key); + zend_string_delref(string_key); } - zend::String key(string_key, false); + int key_header = parse_header_name(ZSTR_VAL(string_key), ZSTR_LEN(string_key)); if (key_header > 0) { #ifdef SW_HAVE_COMPRESSION @@ -398,11 +412,11 @@ void HttpContext::build_header(String *http_buffer, const char *body, size_t len if (ZVAL_IS_ARRAY(zvalue)) { zval *zvalue_2; SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(zvalue), zvalue_2) { - add_custom_header(http_buffer, ZSTR_VAL(string_key), ZSTR_LEN(string_key), zvalue_2); + add_custom_header(&http_byte_buffer, string_key, zvalue_2); } SW_HASHTABLE_FOREACH_END(); } else { - add_custom_header(http_buffer, ZSTR_VAL(string_key), ZSTR_LEN(string_key), zvalue); + add_custom_header(&http_byte_buffer, string_key, zvalue); } } ZEND_HASH_FOREACH_END(); @@ -419,75 +433,77 @@ void HttpContext::build_header(String *http_buffer, const char *body, size_t len #endif } - /** - * http cookies - */ - zval *zcookie = - sw_zend_read_property_ex(swoole_http_response_ce, response.zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_COOKIE), 0); + // http cookies if (ZVAL_IS_ARRAY(zcookie)) { zval *zvalue; SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(zcookie), zvalue) { if (Z_TYPE_P(zvalue) != IS_STRING) { continue; } - http_buffer->append(ZEND_STRL("Set-Cookie: ")); - http_buffer->append(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); - http_buffer->append(ZEND_STRL("\r\n")); + + http_byte_buffer.add_header(ZEND_STRL("Set-Cookie"), Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); } SW_HASHTABLE_FOREACH_END(); } + // http Server Name if (!(header_flags & HTTP_HEADER_SERVER)) { - http_buffer->append(ZEND_STRL("Server: " SW_HTTP_SERVER_SOFTWARE "\r\n")); + http_byte_buffer.add_header(ZEND_STRL("Server: " SW_HTTP_SERVER_SOFTWARE "\r\n"), nullptr, 0); } + + // http Date if (!(header_flags & HTTP_HEADER_DATE)) { - http_set_date_header(http_buffer); + http_set_date_header(&http_byte_buffer); } // websocket protocol (subsequent header info is unnecessary) if (upgrade == 1) { - http_buffer->append(ZEND_STRL("\r\n")); + http_buffer = get_write_buffer(http_byte_buffer.get_protocol_length()); + http_buffer->clear(); + http_byte_buffer.write_protocol(http_buffer, nullptr, 0); send_header_ = 1; return; } + + // http Connection if (!(header_flags & HTTP_HEADER_CONNECTION)) { - if (keepalive) { - http_buffer->append(ZEND_STRL("Connection: keep-alive\r\n")); - } else { - http_buffer->append(ZEND_STRL("Connection: close\r\n")); - } + keepalive ? http_byte_buffer.add_header(ZEND_STRL("Connection: keep-alive\r\n"), nullptr, 0) + : http_byte_buffer.add_header(ZEND_STRL("Connection: close\r\n"), nullptr, 0); } + + // http Content-Type if (!(header_flags & HTTP_HEADER_CONTENT_TYPE)) { - http_buffer->append(ZEND_STRL("Content-Type: " SW_HTTP_DEFAULT_CONTENT_TYPE "\r\n")); + http_byte_buffer.add_header(ZEND_STRL("Content-Type: " SW_HTTP_DEFAULT_CONTENT_TYPE "\r\n"), nullptr, 0); } + + // http Chunk if (send_chunked) { SW_ASSERT(length == 0); if (!(header_flags & HTTP_HEADER_TRANSFER_ENCODING)) { - http_buffer->append(ZEND_STRL("Transfer-Encoding: chunked\r\n")); + http_byte_buffer.add_header(ZEND_STRL("Transfer-Encoding: chunked\r\n"), nullptr, 0); } } + // Content-Length else if (length > 0 || parser.method != PHP_HTTP_HEAD) { #ifdef SW_HAVE_COMPRESSION if (compress(body, length)) { length = zlib_buffer->length; const char *content_encoding = get_content_encoding(); - http_buffer->append(ZEND_STRL("Content-Encoding: ")); - http_buffer->append((char *) content_encoding, strlen(content_encoding)); - http_buffer->append(ZEND_STRL("\r\n")); + http_byte_buffer.add_header(ZEND_STRL("Content-Encoding"), content_encoding, strlen(content_encoding)); } #endif + char content_length[25]; if (!(header_flags & HTTP_HEADER_CONTENT_LENGTH)) { - http_buffer->append(ZEND_STRL("Content-Length: ")); - - char content_length2[128]; - int convert_result = swoole_itoa(content_length2, length); - http_buffer->append(content_length2, convert_result); - http_buffer->append(ZEND_STRL("\r\n")); + int convert_result = swoole_itoa(content_length, length); + content_length[convert_result] = '\0'; + http_byte_buffer.add_header(ZEND_STRL("Content-Length"), content_length, convert_result); } } - http_buffer->append(ZEND_STRL("\r\n")); + http_buffer = get_write_buffer(http_byte_buffer.get_protocol_length(body ? length : 0)); + http_buffer->clear(); + http_byte_buffer.write_protocol(http_buffer, (content_compressed ? zlib_buffer->str : body), length); send_header_ = 1; } @@ -727,11 +743,8 @@ bool HttpContext::send_file(const char *file, uint32_t l_file, off_t offset, siz #ifdef SW_HAVE_COMPRESSION accept_compression = 0; #endif + build_header(nullptr, length); String *http_buffer = get_write_buffer(); - http_buffer->clear(); - - build_header(http_buffer, nullptr, length); - if (!send(this, http_buffer->str, http_buffer->length)) { send_header_ = 0; return false; @@ -777,9 +790,6 @@ void HttpContext::end(zval *zdata, zval *return_value) { } send_chunked = 0; } else { - String *http_buffer = get_write_buffer(); - http_buffer->clear(); - #ifdef SW_HAVE_ZLIB if (upgrade) { Server *serv = nullptr; @@ -807,42 +817,8 @@ void HttpContext::end(zval *zdata, zval *return_value) { } #endif - build_header(http_buffer, http_body.str, http_body.length); - - char *send_body_str; - size_t send_body_len; - - if (http_body.length > 0) { -#ifdef SW_HAVE_COMPRESSION - if (content_compressed) { - send_body_str = zlib_buffer->str; - send_body_len = zlib_buffer->length; - } else -#endif - { - send_body_str = http_body.str; - send_body_len = http_body.length; - } - // send twice to reduce memory copy - if (send_body_len < swoole_pagesize()) { - if (http_buffer->append(send_body_str, send_body_len) < 0) { - send_header_ = 0; - RETURN_FALSE; - } - } else { - if (!send(this, http_buffer->str, http_buffer->length)) { - send_header_ = 0; - RETURN_FALSE; - } - if (!send(this, send_body_str, send_body_len)) { - end_ = 1; - close(this); - RETURN_FALSE; - } - goto _skip_copy; - } - } - + build_header(http_body.str, http_body.length); + String *http_buffer = get_write_buffer(); if (!send(this, http_buffer->str, http_buffer->length)) { end_ = 1; close(this); @@ -850,7 +826,6 @@ void HttpContext::end(zval *zdata, zval *return_value) { } } -_skip_copy: if (upgrade && !co_socket) { Server *serv = (Server *) private_data; Connection *conn = serv->get_connection_verify(fd); @@ -996,11 +971,12 @@ static void php_swoole_http_response_cookie(INTERNAL_FUNCTION_PARAMETERS, const RETURN_FALSE; } - char *cookie = nullptr, *date = nullptr; - size_t cookie_size = name_len + 1; // add 1 for null char - cookie_size += 50; // strlen("; expires=Fri, 31-Dec-9999 23:59:59 GMT; Max-Age=0") + char *cookie = nullptr; + zend_string *date = nullptr; + size_t cookie_size = name_len + 1; // add 1 for null char + cookie_size += 50; // strlen("; expires=Fri, 31-Dec-9999 23:59:59 GMT; Max-Age=0") if (value_len == 0) { - cookie_size += 8; // strlen("=deleted") + cookie_size += 8; // strlen("=deleted") } if (expires > 0) { // Max-Age will be no longer than 12 digits since the @@ -1008,29 +984,29 @@ static void php_swoole_http_response_cookie(INTERNAL_FUNCTION_PARAMETERS, const cookie_size += 11; } if (path_len > 0) { - cookie_size += path_len + 7; // strlen("; path=") + cookie_size += path_len + 7; // strlen("; path=") } if (domain_len > 0) { - cookie_size += domain_len + 9; // strlen("; domain=") + cookie_size += domain_len + 9; // strlen("; domain=") } if (secure) { - cookie_size += 8; // strlen("; secure") + cookie_size += 8; // strlen("; secure") } if (httponly) { - cookie_size += 10; // strlen("; httponly") + cookie_size += 10; // strlen("; httponly") } if (samesite_len > 0) { - cookie_size += samesite_len + 11; // strlen("; samesite=") + cookie_size += samesite_len + 11; // strlen("; samesite=") } if (priority_len > 0) { - cookie_size += priority_len + 11; // strlen("; priority=") + cookie_size += priority_len + 11; // strlen("; priority=") } if (value_len == 0) { cookie = (char *) emalloc(cookie_size); date = php_swoole_format_date((char *) ZEND_STRL("D, d-M-Y H:i:s T"), 1, 0); - snprintf(cookie, cookie_size, "%s=deleted; expires=%s", name, date); - efree(date); + sw_snprintf(cookie, cookie_size, "%s=deleted; expires=%s", name, ZSTR_VAL(date)); + zend_string_release(date); strlcat(cookie, "; Max-Age=0", cookie_size); } else { if (url_encode) { @@ -1049,15 +1025,15 @@ static void php_swoole_http_response_cookie(INTERNAL_FUNCTION_PARAMETERS, const if (expires > 0) { strlcat(cookie, "; expires=", cookie_size); date = php_swoole_format_date((char *) ZEND_STRL("D, d-M-Y H:i:s T"), expires, 0); - const char *p = (const char *) zend_memrchr(date, '-', strlen(date)); + const char *p = (const char *) zend_memrchr(ZSTR_VAL(date), '-', ZSTR_LEN(date)); if (!p || *(p + 5) != ' ') { php_swoole_error(E_WARNING, "Expiry date can't be a year greater than 9999"); - efree(date); + zend_string_release(date); efree(cookie); RETURN_FALSE; } - strlcat(cookie, date, cookie_size); - efree(date); + strlcat(cookie, ZSTR_VAL(date), cookie_size); + zend_string_release(date); strlcat(cookie, "; Max-Age=", cookie_size); diff --git a/include/swoole_config.h b/include/swoole_config.h index cd0936ab5d2..6a1819832f8 100644 --- a/include/swoole_config.h +++ b/include/swoole_config.h @@ -183,7 +183,7 @@ #define SW_HTTP_ASCTIME_DATE "%a %b %e %T %Y" #define SW_HTTP_UPLOAD_FILE "Swoole-Upload-File" #define SW_HTTP_CHUNK_EOF "0\r\n\r\n" -#define SW_HTTP_DEFAULT_CONTENT_TYPE "text/html" +#define SW_HTTP_DEFAULT_CONTENT_TYPE "text/html; charset=utf-8" // #define SW_HTTP_100_CONTINUE #define SW_HTTP_100_CONTINUE_PACKET "HTTP/1.1 100 Continue\r\n\r\n" diff --git a/tests/swoole_http_client_coro/connection_close.phpt b/tests/swoole_http_client_coro/connection_close.phpt index 917ae15b296..48a84378ac3 100644 --- a/tests/swoole_http_client_coro/connection_close.phpt +++ b/tests/swoole_http_client_coro/connection_close.phpt @@ -56,7 +56,7 @@ array(5) { ["date"]=> string(%d) "%s" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["content-length"]=> string(1) "0" } @@ -69,7 +69,7 @@ array(5) { ["connection"]=> string(10) "keep-alive" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["content-length"]=> string(1) "0" } diff --git a/tests/swoole_http_server/bug_4857.phpt b/tests/swoole_http_server/bug_4857.phpt index 6abded5af23..010ffca35b9 100644 --- a/tests/swoole_http_server/bug_4857.phpt +++ b/tests/swoole_http_server/bug_4857.phpt @@ -67,7 +67,7 @@ array(6) { ["connection"]=> string(10) "keep-alive" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["content-encoding"]=> string(%d) %s ["content-length"]=> @@ -82,7 +82,7 @@ array(5) { ["connection"]=> string(10) "keep-alive" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["transfer-encoding"]=> string(7) "chunked" } @@ -95,7 +95,7 @@ array(6) { ["connection"]=> string(10) "keep-alive" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["content-encoding"]=> string(%d) %s ["content-length"]=> diff --git a/tests/swoole_http_server/bug_5107.phpt b/tests/swoole_http_server/bug_5107.phpt index 5e071f96071..a3672cb85a2 100644 --- a/tests/swoole_http_server/bug_5107.phpt +++ b/tests/swoole_http_server/bug_5107.phpt @@ -41,7 +41,7 @@ array(5) { ["connection"]=> string(10) "keep-alive" ["content-type"]=> - string(9) "text/html" + string(24) "text/html; charset=utf-8" ["content-length"]=> string(2) "11" } diff --git a/tests/swoole_http_server/duplicate_header.phpt b/tests/swoole_http_server/duplicate_header.phpt index 37743d67154..6297761904c 100644 --- a/tests/swoole_http_server/duplicate_header.phpt +++ b/tests/swoole_http_server/duplicate_header.phpt @@ -60,6 +60,6 @@ Test-Value: 3.1415926 Server: swoole-http-server Date: %s Connection: keep-alive -Content-Type: text/html +Content-Type: text/html; charset=utf-8 hello world