From 666dfb2af40856f96f031c0fc2d516183d143819 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Wed, 28 Feb 2024 22:52:50 +0800 Subject: [PATCH 01/21] Optimize memory usage --- ext-src/php_swoole.cc | 2 +- ext-src/php_swoole_http.h | 122 ++++++- ext-src/php_swoole_library.h | 9 +- ext-src/php_swoole_private.h | 16 +- ext-src/swoole_http2_server.cc | 8 +- ext-src/swoole_http_response.cc | 301 +++++++++--------- include/swoole_config.h | 4 +- tests/swoole_http_server/bug_4857.phpt | 6 +- tests/swoole_http_server/bug_5107.phpt | 2 +- .../swoole_http_server/duplicate_header.phpt | 2 +- 10 files changed, 290 insertions(+), 182 deletions(-) diff --git a/ext-src/php_swoole.cc b/ext-src/php_swoole.cc index 17046b423cf..334713be0b7 100644 --- a/ext-src/php_swoole.cc +++ b/ext-src/php_swoole.cc @@ -695,7 +695,7 @@ PHP_MINIT_FUNCTION(swoole) { // init bug report message bug_report_message_init(); if (strcmp("cli", sapi_module.name) == 0 || strcmp("phpdbg", sapi_module.name) == 0 || - strcmp("embed", sapi_module.name) == 0) { + strcmp("embed", sapi_module.name) == 0 || strcmp("micro", sapi_module.name) == 0) { SWOOLE_G(cli) = 1; } diff --git a/ext-src/php_swoole_http.h b/ext-src/php_swoole_http.h index 71a7613fcf0..4646561af2d 100644 --- a/ext-src/php_swoole_http.h +++ b/ext-src/php_swoole_http.h @@ -64,6 +64,126 @@ class Session; namespace http { +struct ByteBuffer { + const char *version = "HTTP/1.1 "; + size_t version_length = 9; + const char *status = nullptr; + size_t status_length = 0; + const char *reason = nullptr; + size_t reason_length = 0; + + size_t position = 0; + 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) { + status = _status; + status_length = strlen(status); + reason = _reason; + reason_length = reason ? strlen(reason) : 0; + + // calculate http status line length + http_status_length = version_length + status_length + SW_CRLF_LEN; + if (reason) { + http_status_length += reason_length + 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; + } + + inline void append(char *protocol, const char *data, size_t length) { + memcpy(protocol + position, data, length); + position += length; + } + + void write_protocol(char *protocol, const char *data, size_t length) { + append(protocol, version, version_length); + append(protocol, status, status_length); + if (reason) { + append(protocol, " ", 1); + append(protocol, reason, reason_length); + } + + append(protocol, 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) { + append(protocol, key, key_length); + continue; + } + + append(protocol, key, key_length); + append(protocol, ": ", 2); + append(protocol, value, value_length); + append(protocol, SW_CRLF, SW_CRLF_LEN); + } + + append(protocol, SW_CRLF, SW_CRLF_LEN); + if (data) { + append(protocol, data, length); + } + } +}; + struct Request { int version; char *path; @@ -193,7 +313,7 @@ struct Context { 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); + bool start_send(const char *body, size_t length); ssize_t build_trailer(String *http_buffer); size_t get_content_length() { diff --git a/ext-src/php_swoole_library.h b/ext-src/php_swoole_library.h index 50175d4fc06..ae6c1606191 100644 --- a/ext-src/php_swoole_library.h +++ b/ext-src/php_swoole_library.h @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: d0ac03753a22ce34a521c7eb75b2e19f0d6ec961 */ +/* $Id: 286fa34095664574dbb1c9c00cfe3ca052e04a59 */ #ifndef SWOOLE_LIBRARY_H #define SWOOLE_LIBRARY_H @@ -1939,7 +1939,7 @@ static const char* swoole_library_source_core_coroutine_http_client_proxy = "\n" "class ClientProxy\n" "{\n" - " public function __construct(private string $body, private int $statusCode, private array $headers, private array $cookies)\n" + " public function __construct(private string $body, private int $statusCode, private ?array $headers, private ?array $cookies)\n" " {\n" " }\n" "\n" @@ -6609,6 +6609,7 @@ static const char* swoole_library_source_core_coroutine_fast_cgi_client = "\n" "namespace Swoole\\Coroutine\\FastCGI;\n" "\n" + "use Swoole\\Constant;\n" "use Swoole\\Coroutine\\FastCGI\\Client\\Exception;\n" "use Swoole\\Coroutine\\Socket;\n" "use Swoole\\FastCGI\\FrameParser;\n" @@ -6655,8 +6656,8 @@ static const char* swoole_library_source_core_coroutine_fast_cgi_client = " if (!isset($this->socket)) {\n" " $this->socket = $socket = new Socket($this->af, SOCK_STREAM, IPPROTO_IP);\n" " $socket->setProtocol([\n" - " 'open_ssl' => $this->ssl,\n" - " 'open_fastcgi_protocol' => true,\n" + " Constant::OPTION_OPEN_SSL => $this->ssl,\n" + " Constant::OPTION_OPEN_FASTCGI_PROTOCOL => true,\n" " ]);\n" " if (!$socket->connect($this->host, $this->port, $timeout)) {\n" " $this->ioException();\n" 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..2c70b735f4c 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; @@ -223,31 +224,20 @@ 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); - if (!ctx->send(ctx, http_buffer->str, http_buffer->length)) { + if (!ctx->start_send(nullptr, 0)) { ctx->send_chunked = 0; ctx->send_header_ = 0; RETURN_FALSE; } } - struct { - char *str; - size_t length; - } http_body; - size_t length = php_swoole_get_send_data(zdata, &http_body.str); - - if (length == 0) { + char *http_body_str = nullptr; + size_t http_body_length = php_swoole_get_send_data(zdata, &http_body_str); + if (http_body_length == 0) { php_swoole_error(E_WARNING, "data to send is empty"); RETURN_FALSE; - } else { - http_body.length = length; } // Why not enable compression? @@ -256,13 +246,14 @@ static PHP_METHOD(swoole_http_response, write) { // so the chunk encoding itself is not compressed, // **and the data in each chunk is not compressed individually.** // The remote endpoint then decodes the stream by concatenating the chunks and decompressing the result. + String *http_buffer = ctx->get_write_buffer(); http_buffer->clear(); - char *hex_string = swoole_dec2hex(http_body.length, 16); + char *hex_string = swoole_dec2hex(http_body_length, 16); int hex_len = strlen(hex_string); //"%.*s\r\n%.*s\r\n", hex_len, hex_string, body.length, body.str http_buffer->append(hex_string, hex_len); http_buffer->append(ZEND_STRL("\r\n")); - http_buffer->append(http_body.str, http_body.length); + http_buffer->append(http_body_str, http_body_length); http_buffer->append(ZEND_STRL("\r\n")); sw_free(hex_string); @@ -288,7 +279,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,58 +288,93 @@ 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, int key_header) { if (ZVAL_IS_NULL(value)) { return; } + + if (key_header == HTTP_HEADER_CONTENT_TYPE && ZVAL_IS_STRING(value)) { + if (SW_STRCASEEQ(Z_STRVAL_P(value), Z_STRLEN_P(value), SW_HTTP_APPLICATION_JSON)) { + http_byte_buffer->add_header(ZEND_STRL("Content-Type: " SW_HTTP_APPLICATION_JSON "\r\n"), nullptr, 0); + return; + } + + if (SW_STRCASEEQ(Z_STRVAL_P(value), Z_STRLEN_P(value), SW_HTTP_DEFAULT_CONTENT_TYPE)) { + http_byte_buffer->add_header(ZEND_STRL("Content-Type: " SW_HTTP_DEFAULT_CONTENT_TYPE "\r\n"), nullptr, 0); + return; + } + + if (SW_STRCASEEQ(Z_STRVAL_P(value), Z_STRLEN_P(value), SW_HTTP_TEXT_PLAIN)) { + http_byte_buffer->add_header(ZEND_STRL("Content-Type: " SW_HTTP_TEXT_PLAIN "\r\n"), nullptr, 0); + return; + } + } + zend::String str_value(value); str_value.rtrim(); 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) { +bool HttpContext::start_send(const char *body, size_t length) { assert(send_header_ == 0); + const + 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 +386,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 +423,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, key_header); } 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, key_header); } } ZEND_HASH_FOREACH_END(); @@ -419,51 +444,58 @@ 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; + if (Z_TYPE_P(zvalue) == IS_STRING) { + http_byte_buffer.add_header(ZEND_STRL("Set-Cookie"), Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); } - 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")); } 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) + size_t protocol_length = 0; if (upgrade == 1) { - http_buffer->append(ZEND_STRL("\r\n")); - send_header_ = 1; - return; - } - if (!(header_flags & HTTP_HEADER_CONNECTION)) { - if (keepalive) { - http_buffer->append(ZEND_STRL("Connection: keep-alive\r\n")); + protocol_length = http_byte_buffer.get_protocol_length(); + char websocket_protocol[protocol_length]; + http_byte_buffer.write_protocol(websocket_protocol, nullptr, 0); + if (send(this, websocket_protocol, protocol_length)) { + send_header_ = 1; + return true; } else { - http_buffer->append(ZEND_STRL("Connection: close\r\n")); + send_header_ = 0; + return false; } } + + // http Connection + if (!(header_flags & HTTP_HEADER_CONNECTION)) { + 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 @@ -471,24 +503,29 @@ void HttpContext::build_header(String *http_buffer, const char *body, size_t len #ifdef SW_HAVE_COMPRESSION if (compress(body, length)) { length = zlib_buffer->length; + body = zlib_buffer->str; 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")); - send_header_ = 1; + protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); + char http_protocol[protocol_length]; + http_byte_buffer.write_protocol(http_protocol, body, length); + if (send(this, http_protocol, protocol_length)) { + send_header_ = 1; + return true; + } else { + send_header_ = 0; + return false; + } } ssize_t HttpContext::build_trailer(String *http_buffer) { @@ -727,12 +764,7 @@ bool HttpContext::send_file(const char *file, uint32_t l_file, off_t offset, siz #ifdef SW_HAVE_COMPRESSION accept_compression = 0; #endif - String *http_buffer = get_write_buffer(); - http_buffer->clear(); - - build_header(http_buffer, nullptr, length); - - if (!send(this, http_buffer->str, http_buffer->length)) { + if (!start_send(nullptr, length)) { send_header_ = 0; return false; } @@ -752,15 +784,10 @@ bool HttpContext::send_file(const char *file, uint32_t l_file, off_t offset, siz } void HttpContext::end(zval *zdata, zval *return_value) { - struct { - char *str; - size_t length; - } http_body; + char *http_body_str = nullptr; + size_t http_body_length = 0; if (zdata) { - http_body.length = php_swoole_get_send_data(zdata, &http_body.str); - } else { - http_body.length = 0; - http_body.str = nullptr; + http_body_length = php_swoole_get_send_data(zdata, &http_body_str); } if (send_chunked) { @@ -777,9 +804,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; @@ -806,51 +830,13 @@ 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; - } - } - - if (!send(this, http_buffer->str, http_buffer->length)) { + if (!start_send(http_body_str, http_body_length)) { end_ = 1; close(this); RETURN_FALSE; } } -_skip_copy: if (upgrade && !co_socket) { Server *serv = (Server *) private_data; Connection *conn = serv->get_connection_verify(fd); @@ -996,11 +982,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 +995,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 +1036,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..b266fb7bc19 100644 --- a/include/swoole_config.h +++ b/include/swoole_config.h @@ -183,7 +183,9 @@ #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_APPLICATION_JSON "application/json" +#define SW_HTTP_TEXT_PLAIN "text/plain; 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_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 From aa02263cfa0dd9f03c6875e05edaaaeeef86024a Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Wed, 28 Feb 2024 23:22:02 +0800 Subject: [PATCH 02/21] fix error --- ext-src/swoole_http_response.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 2c70b735f4c..bbec1872584 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -330,7 +330,6 @@ static void add_custom_header(HttpByteBuffer *http_byte_buffer, zend_string *key bool HttpContext::start_send(const char *body, size_t length) { assert(send_header_ == 0); - const int count = 6; zval *zheader = From 72a269b00ea4e34ee1f9e6863ed552490a61cc11 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 18:35:43 +0800 Subject: [PATCH 03/21] fix error --- ext-src/swoole_http_response.cc | 20 ++++++---- include/swoole.h | 1 + src/core/base.cc | 8 +++- .../connection_close.phpt | 4 +- tests/swoole_http_server/big_data.phpt | 37 +++++++++++++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 tests/swoole_http_server/big_data.phpt diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index bbec1872584..95423279549 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -516,15 +516,21 @@ bool HttpContext::start_send(const char *body, size_t length) { } protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); - char http_protocol[protocol_length]; - http_byte_buffer.write_protocol(http_protocol, body, length); - if (send(this, http_protocol, protocol_length)) { - send_header_ = 1; - return true; + bool overflow = protocol_length > (SwooleG.stack_size / 2); + bool result; + if (overflow) { + char *http_protocol = (char *) emalloc(protocol_length); + http_byte_buffer.write_protocol(http_protocol, body, length); + result = send(this, http_protocol, protocol_length); + efree(http_protocol); } else { - send_header_ = 0; - return false; + char _http_protocol[protocol_length]; + http_byte_buffer.write_protocol(_http_protocol, body, length); + result = send(this, _http_protocol, protocol_length); } + + send_header_ = result ? 1 : 0; + return result; } ssize_t HttpContext::build_trailer(String *http_buffer) { diff --git a/include/swoole.h b/include/swoole.h index ee12b283ab3..dee18669c92 100644 --- a/include/swoole.h +++ b/include/swoole.h @@ -732,6 +732,7 @@ struct Global { //-----------------------[System]-------------------------- uint16_t cpu_num; + uint32_t stack_size; uint32_t pagesize; struct utsname uname; uint32_t max_sockets; diff --git a/src/core/base.cc b/src/core/base.cc index 37b723a6dc6..0fbb084a443 100644 --- a/src/core/base.cc +++ b/src/core/base.cc @@ -191,12 +191,18 @@ void swoole_init(void) { SwooleG.max_sockets = SW_MAX_SOCKETS_DEFAULT; struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0) { - swoole_sys_warning("getrlimit() failed"); + swoole_sys_warning("getrlimit(RLIMIT_NOFILE) failed"); } else { SwooleG.max_sockets = SW_MAX((uint32_t) rlmt.rlim_cur, SW_MAX_SOCKETS_DEFAULT); SwooleG.max_sockets = SW_MIN((uint32_t) rlmt.rlim_cur, SW_SESSION_LIST_SIZE); } + if (getrlimit(RLIMIT_STACK, &rlmt) < 0) { + swoole_sys_warning("getrlimit(RLIMIT_STACK) failed"); + } else { + SwooleG.stack_size = rlmt.rlim_cur; + } + SwooleTG.buffer_stack = new swoole::String(SW_STACK_BUFFER_SIZE); if (!swoole_set_task_tmpdir(SW_TASK_TMP_DIR)) { 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/big_data.phpt b/tests/swoole_http_server/big_data.phpt new file mode 100644 index 00000000000..bc94d33f8de --- /dev/null +++ b/tests/swoole_http_server/big_data.phpt @@ -0,0 +1,37 @@ +--TEST-- +swoole_http_server: big data +--SKIPIF-- + +--FILE-- +parentFunc = function () use ($pm) { + Co\Run(function () use ($pm) { + $response = httpRequest("http://127.0.0.1:{$pm->getFreePort()}"); + var_dump($response['statusCode'] == 200); + var_dump($response['body'] == str_repeat('A', 10 * 1024 * 1024)); + }); + $pm->kill(); +}; +$pm->childFunc = function () use ($pm) { + $server = new Swoole\Http\Server('0.0.0.0', $pm->getFreePort(), SWOOLE_BASE); + $server->set(['log_file' => '/dev/null']); + $server->on('workerStart', function () use ($pm) { + $pm->wakeup(); + }); + $server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) use ($pm) { + $response->end(str_repeat('A', 10 * 1024 * 1024)); + }); + $server->start(); +}; +$pm->childFirst(); +$pm->run(); + +?> +--EXPECT-- +bool(true) +bool(true) From 5fec65c79788a4afa297dbc9a41234d314f21648 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 19:30:17 +0800 Subject: [PATCH 04/21] test --- ext-src/swoole_http_response.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 95423279549..aa84a2ab5b8 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -516,6 +516,7 @@ bool HttpContext::start_send(const char *body, size_t length) { } protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); + printf("test stack %d, %d\n", SwooleG.stack_size, SwooleG.stack_size / 2); bool overflow = protocol_length > (SwooleG.stack_size / 2); bool result; if (overflow) { From d514dd5d85060ef169798ba0d24c4f0e64f09158 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 19:46:17 +0800 Subject: [PATCH 05/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index aa84a2ab5b8..4a660ae6e1a 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -516,7 +516,7 @@ bool HttpContext::start_send(const char *body, size_t length) { } protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); - printf("test stack %d, %d\n", SwooleG.stack_size, SwooleG.stack_size / 2); + printf("test stack %d, %d, %d\n", SwooleG.stack_size, SwooleG.stack_size / 2, protocol_length); bool overflow = protocol_length > (SwooleG.stack_size / 2); bool result; if (overflow) { From 36253d9021db035906fc52ea7e23e12d1f3b959e Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 20:10:55 +0800 Subject: [PATCH 06/21] test --- ext-src/swoole_http_response.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 4a660ae6e1a..6d03d190d57 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -516,10 +516,9 @@ bool HttpContext::start_send(const char *body, size_t length) { } protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); - printf("test stack %d, %d, %d\n", SwooleG.stack_size, SwooleG.stack_size / 2, protocol_length); - bool overflow = protocol_length > (SwooleG.stack_size / 2); bool result; - if (overflow) { + if (protocol_length > (SwooleG.stack_size >> 1)) { + printf("test\n"); char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 55584ae839696866386c476120990aa1a4549a5e Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 20:19:56 +0800 Subject: [PATCH 07/21] test --- ext-src/swoole_http_response.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 6d03d190d57..d20de82eb90 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -524,6 +524,7 @@ bool HttpContext::start_send(const char *body, size_t length) { result = send(this, http_protocol, protocol_length); efree(http_protocol); } else { + printf("test123123123\n"); char _http_protocol[protocol_length]; http_byte_buffer.write_protocol(_http_protocol, body, length); result = send(this, _http_protocol, protocol_length); From fc445da87ba85c4b62d72127477dbbca356d7cf1 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 20:53:16 +0800 Subject: [PATCH 08/21] test --- ext-src/swoole_http_response.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index d20de82eb90..e9771735e06 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,18 +517,16 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > (SwooleG.stack_size >> 1)) { - printf("test\n"); +// if (protocol_length > (SwooleG.stack_size >> 1)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); efree(http_protocol); - } else { - printf("test123123123\n"); - char _http_protocol[protocol_length]; - http_byte_buffer.write_protocol(_http_protocol, body, length); - result = send(this, _http_protocol, protocol_length); - } +// } else { +// char _http_protocol[protocol_length]; +// http_byte_buffer.write_protocol(_http_protocol, body, length); +// result = send(this, _http_protocol, protocol_length); +// } send_header_ = result ? 1 : 0; return result; From ea434dea6b4290cc23f44a648a8c0bae56683aba Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 21:13:25 +0800 Subject: [PATCH 09/21] test --- ext-src/swoole_http_response.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index e9771735e06..aaaccc92275 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,16 +517,16 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; -// if (protocol_length > (SwooleG.stack_size >> 1)) { + if (protocol_length > (size_t) (SwooleG.stack_size >> 1)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); efree(http_protocol); -// } else { -// char _http_protocol[protocol_length]; -// http_byte_buffer.write_protocol(_http_protocol, body, length); -// result = send(this, _http_protocol, protocol_length); -// } + } else { + char _http_protocol[protocol_length]; + http_byte_buffer.write_protocol(_http_protocol, body, length); + result = send(this, _http_protocol, protocol_length); + } send_header_ = result ? 1 : 0; return result; From 01d39212405cdda28506a23eb341a0aafae3b297 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 21:35:54 +0800 Subject: [PATCH 10/21] test --- ext-src/swoole_http_response.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index aaaccc92275..641ebcdb14b 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,8 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > (size_t) (SwooleG.stack_size >> 1)) { + printf("%d, %d\n", protocol_length, SwooleG.stack_size); + if (protocol_length > SwooleG.stack_size)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From b0f433fdc35f4a23e2ca965b151978060e8671f5 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 21:40:55 +0800 Subject: [PATCH 11/21] test --- ext-src/swoole_http_response.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 641ebcdb14b..a24f4f1d0c5 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,8 +517,8 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - printf("%d, %d\n", protocol_length, SwooleG.stack_size); - if (protocol_length > SwooleG.stack_size)) { + printf("%ld, %d, %d\n", protocol_length, SwooleG.stack_size, protocol_length > (SwooleG.stack_size / 2)); + if (protocol_length > SwooleG.stack_size) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 1d9e270d77c939977c3c2f5f3203f887b60c9e17 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 21:51:58 +0800 Subject: [PATCH 12/21] test --- ext-src/swoole_http_response.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index a24f4f1d0c5..49375d82d54 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,8 +517,8 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - printf("%ld, %d, %d\n", protocol_length, SwooleG.stack_size, protocol_length > (SwooleG.stack_size / 2)); - if (protocol_length > SwooleG.stack_size) { + + if (protocol_length > 16777216 >> 1) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 038dbb24ac4045cb585c5c567699216694a51897 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 21:52:08 +0800 Subject: [PATCH 13/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 49375d82d54..66a43fc2558 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -518,7 +518,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > 16777216 >> 1) { + if (protocol_length > (16777216 >> 1)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 42cc551fe3c68fada0d99a67c1a85f5154a09b98 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 22:16:10 +0800 Subject: [PATCH 14/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 66a43fc2558..f5fddaa51f8 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -518,7 +518,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > (16777216 >> 1)) { + if (protocol_length) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From ec7c22292a69ae49aac1c03197dbd5ba9d18553a Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 22:25:08 +0800 Subject: [PATCH 15/21] test --- ext-src/swoole_http_response.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index f5fddaa51f8..004512d4609 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,8 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - - if (protocol_length) { + if ((uint32_t) protocol_length > (SwooleG.stack_size >> 1)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From ce229b83efe94189be03726a8f837cd8d40e61c9 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 22:35:32 +0800 Subject: [PATCH 16/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 004512d4609..6d8f9281288 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if ((uint32_t) protocol_length > (SwooleG.stack_size >> 1)) { + if (protocol_length > 16777216) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From d671e03f7d8d5222a5ccb2ab532b0e4e9bcbc23c Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 22:49:36 +0800 Subject: [PATCH 17/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 6d8f9281288..12881b2de61 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > 16777216) { + if (protocol_length > 2048) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 9c8844df905208357ab7f1da3d5eede62633169c Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 23:02:31 +0800 Subject: [PATCH 18/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index 12881b2de61..a73b10055f6 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > 2048) { + if (UNEXPECTED((SwooleG.stack_size >> 1) < protocol_length)) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From fbda9cd4b7abe68363681b526a2cc5cf665a6671 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 23:14:28 +0800 Subject: [PATCH 19/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index a73b10055f6..d17740bf970 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (UNEXPECTED((SwooleG.stack_size >> 1) < protocol_length)) { + if (protocol_length > 1 * 1024 * 1024) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); From 4aa28d5f7f76b6ce79bca9c40cf9d37c6b7d8e5c Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 23:22:24 +0800 Subject: [PATCH 20/21] test --- ext-src/swoole_http_response.cc | 2 +- src/core/base.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index d17740bf970..c5e194a5d44 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (protocol_length > 1 * 1024 * 1024) { + if (UNEXPECTED(protocol_length > (SwooleG.stack_size >> 1))) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length); diff --git a/src/core/base.cc b/src/core/base.cc index 0fbb084a443..1daaca89eb2 100644 --- a/src/core/base.cc +++ b/src/core/base.cc @@ -200,7 +200,7 @@ void swoole_init(void) { if (getrlimit(RLIMIT_STACK, &rlmt) < 0) { swoole_sys_warning("getrlimit(RLIMIT_STACK) failed"); } else { - SwooleG.stack_size = rlmt.rlim_cur; + SwooleG.stack_size = (uint32_t) rlmt.rlim_cur; } SwooleTG.buffer_stack = new swoole::String(SW_STACK_BUFFER_SIZE); From f113fc719390845183901cd73018c84bd5292b50 Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Thu, 29 Feb 2024 23:37:38 +0800 Subject: [PATCH 21/21] test --- ext-src/swoole_http_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext-src/swoole_http_response.cc b/ext-src/swoole_http_response.cc index c5e194a5d44..2a386ac9f5a 100644 --- a/ext-src/swoole_http_response.cc +++ b/ext-src/swoole_http_response.cc @@ -517,7 +517,7 @@ bool HttpContext::start_send(const char *body, size_t length) { protocol_length = http_byte_buffer.get_protocol_length(body ? length : 0); bool result; - if (UNEXPECTED(protocol_length > (SwooleG.stack_size >> 1))) { + if (UNEXPECTED(protocol_length > static_cast(SwooleG.stack_size >> 1))) { char *http_protocol = (char *) emalloc(protocol_length); http_byte_buffer.write_protocol(http_protocol, body, length); result = send(this, http_protocol, protocol_length);