diff --git a/proxy/hdrs/XPACK.cc b/proxy/hdrs/XPACK.cc index e987479b933..d6e69606298 100644 --- a/proxy/hdrs/XPACK.cc +++ b/proxy/hdrs/XPACK.cc @@ -21,11 +21,13 @@ limitations under the License. */ -#include "tscore/Arena.h" -#include "tscore/ink_memory.h" #include "XPACK.h" #include "HuffmanCodec.h" +#include "tscore/Arena.h" +#include "tscore/ink_memory.h" +#include "tscpp/util/LocalBuffer.h" + // // [RFC 7541] 5.1. Integer representation // @@ -150,26 +152,20 @@ xpack_encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *valu { uint8_t *p = buf_start; bool use_huffman = true; - char *data = nullptr; + + ts::LocalBuffer local_buffer(value_len * 4); + uint8_t *data = local_buffer.data(); int64_t data_len = 0; // TODO Choose whether to use Huffman encoding wisely // cppcheck-suppress knownConditionTrueFalse; leaving "use_huffman" for wise huffman usage in the future if (use_huffman && value_len) { - data = static_cast(ats_malloc(value_len * 4)); - if (data == nullptr) { - return -1; - } - data_len = huffman_encode(reinterpret_cast(data), reinterpret_cast(value), value_len); + data_len = huffman_encode(data, reinterpret_cast(value), value_len); } // Length const int64_t len = xpack_encode_integer(p, buf_end, data_len, n); if (len == -1) { - if (use_huffman) { - ats_free(data); - } - return -1; } @@ -181,10 +177,6 @@ xpack_encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *valu p += len; if (buf_end < p || buf_end - p < data_len) { - if (use_huffman) { - ats_free(data); - } - return -1; } @@ -194,9 +186,5 @@ xpack_encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *valu p += data_len; } - if (use_huffman) { - ats_free(data); - } - return p - buf_start; } diff --git a/proxy/http2/HPACK.cc b/proxy/http2/HPACK.cc index 4dcf72942d8..90c7718638f 100644 --- a/proxy/http2/HPACK.cc +++ b/proxy/http2/HPACK.cc @@ -22,7 +22,8 @@ */ #include "HPACK.h" -#include "HuffmanCodec.h" + +#include "tscpp/util/LocalBuffer.h" // [RFC 7541] 4.1. Calculating Table Size // The size of an entry is the sum of its name's length in octets (as defined in Section 5.2), @@ -581,12 +582,14 @@ encode_literal_header_field_with_new_name(uint8_t *buf_start, const uint8_t *buf // Convert field name to lower case to follow HTTP2 spec. // This conversion is needed because WKSs in MIMEFields is old fashioned - Arena arena; int name_len; - const char *name = header.name_get(&name_len); - char *lower_name = arena.str_store(name, name_len); + const char *original_name = header.name_get(&name_len); + + ts::LocalBuffer local_buffer(name_len); + char *lower_name = local_buffer.data(); + for (int i = 0; i < name_len; i++) { - lower_name[i] = ParseRules::ink_tolower(lower_name[i]); + lower_name[i] = ParseRules::ink_tolower(original_name[i]); } // Name String @@ -606,7 +609,7 @@ encode_literal_header_field_with_new_name(uint8_t *buf_start, const uint8_t *buf p += len; - Debug("hpack_encode", "Encoded field: %.*s: %.*s", name_len, name, value_len, value); + Debug("hpack_encode", "Encoded field: %.*s: %.*s", name_len, lower_name, value_len, value); return p - buf_start; } diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc index 94248060312..3160b31d87b 100644 --- a/proxy/http2/HTTP2.cc +++ b/proxy/http2/HTTP2.cc @@ -23,7 +23,10 @@ #include "HTTP2.h" #include "HPACK.h" + #include "tscore/ink_assert.h" +#include "tscpp/util/LocalBuffer.h" + #include "records/P_RecCore.h" #include "records/P_RecProcess.h" @@ -584,12 +587,12 @@ http2_convert_header_from_1_1_to_2(HTTPHdr *headers) const char *value = headers->host_get(&value_len); if (headers->is_port_in_header()) { - int port = headers->port_get(); - char *host_and_port = static_cast(ats_malloc(value_len + 8)); + int port = headers->port_get(); + ts::LocalBuffer buf(value_len + 8); + char *host_and_port = buf.data(); value_len = snprintf(host_and_port, value_len + 8, "%.*s:%d", value_len, value, port); field->value_set(headers->m_heap, headers->m_mime, host_and_port, value_len); - ats_free(host_and_port); } else { field->value_set(headers->m_heap, headers->m_mime, value, value_len); } @@ -602,12 +605,13 @@ http2_convert_header_from_1_1_to_2(HTTPHdr *headers) if (MIMEField *field = headers->field_find(HTTP2_VALUE_PATH, HTTP2_LEN_PATH); field != nullptr) { int value_len; const char *value = headers->path_get(&value_len); - char *path = static_cast(ats_malloc(value_len + 1)); - path[0] = '/'; + + ts::LocalBuffer buf(value_len + 1); + char *path = buf.data(); + path[0] = '/'; memcpy(path + 1, value, value_len); field->value_set(headers->m_heap, headers->m_mime, path, value_len + 1); - ats_free(path); } else { ink_abort("initialize HTTP/2 pseudo-headers"); return PARSE_RESULT_ERROR; diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc index ab1b5c6a255..8cea3818e4c 100644 --- a/proxy/http2/Http2ConnectionState.cc +++ b/proxy/http2/Http2ConnectionState.cc @@ -30,6 +30,7 @@ #include "HttpDebugNames.h" #include "tscpp/util/PostScript.h" +#include "tscpp/util/LocalBuffer.h" #include #include @@ -1587,8 +1588,6 @@ Http2ConnectionState::send_data_frames(Http2Stream *stream) void Http2ConnectionState::send_headers_frame(Http2Stream *stream) { - uint8_t *buf = nullptr; - uint32_t buf_len = 0; uint32_t header_blocks_size = 0; int payload_length = 0; uint8_t flags = 0x00; @@ -1598,17 +1597,14 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream) HTTPHdr *resp_hdr = &stream->response_header; http2_convert_header_from_1_1_to_2(resp_hdr); - buf_len = resp_hdr->length_get() * 2; // Make it double just in case - buf = static_cast(ats_malloc(buf_len)); - if (buf == nullptr) { - return; - } + uint32_t buf_len = resp_hdr->length_get() * 2; // Make it double just in case + ts::LocalBuffer local_buffer(buf_len); + uint8_t *buf = local_buffer.data(); stream->mark_milestone(Http2StreamMilestone::START_ENCODE_HEADERS); Http2ErrorCode result = http2_encode_header_blocks(resp_hdr, buf, buf_len, &header_blocks_size, *(this->remote_hpack_handle), client_settings.get(HTTP2_SETTINGS_HEADER_TABLE_SIZE)); if (result != Http2ErrorCode::HTTP2_ERROR_NO_ERROR) { - ats_free(buf); return; } @@ -1635,7 +1631,6 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream) fini_event = this_ethread()->schedule_imm_local((Continuation *)this, HTTP2_SESSION_EVENT_FINI); } - ats_free(buf); return; } @@ -1658,15 +1653,11 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream) this->ua_session->xmit(continuation_frame); sent += payload_length; } - - ats_free(buf); } bool Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url, const MIMEField *accept_encoding) { - uint8_t *buf = nullptr; - uint32_t buf_len = 0; uint32_t header_blocks_size = 0; int payload_length = 0; uint8_t flags = 0x00; @@ -1698,15 +1689,13 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url, con http2_convert_header_from_1_1_to_2(&hdr); - buf_len = hdr.length_get() * 2; // Make it double just in case - buf = static_cast(ats_malloc(buf_len)); - if (buf == nullptr) { - return false; - } + uint32_t buf_len = hdr.length_get() * 2; // Make it double just in case + ts::LocalBuffer local_buffer(buf_len); + uint8_t *buf = local_buffer.data(); + Http2ErrorCode result = http2_encode_header_blocks(&hdr, buf, buf_len, &header_blocks_size, *(this->remote_hpack_handle), client_settings.get(HTTP2_SETTINGS_HEADER_TABLE_SIZE)); if (result != Http2ErrorCode::HTTP2_ERROR_NO_ERROR) { - ats_free(buf); return false; } @@ -1742,7 +1731,6 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url, con this->ua_session->xmit(continuation); sent += payload_length; } - ats_free(buf); Http2Error error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE); stream = this->create_stream(id, error);