Skip to content

Commit 2171e90

Browse files
committed
all tests passing again
1 parent 4ac13c3 commit 2171e90

File tree

14 files changed

+760
-728
lines changed

14 files changed

+760
-728
lines changed

include/aws/http/http.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ enum aws_http_log_subject {
6868
AWS_LS_HTTP_CONNECTION_MANAGER,
6969
AWS_LS_HTTP_WEBSOCKET,
7070
AWS_LS_HTTP_WEBSOCKET_SETUP,
71-
72-
AWS_LS_HTTP_FRAMES,
7371
};
7472

7573
enum aws_http_version {

include/aws/http/private/h2_frames.h

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
* permissions and limitations under the License.
1717
*/
1818

19-
#include <aws/http/private/hpack.h>
2019
#include <aws/http/request_response.h>
2120

2221
#include <aws/common/byte_buf.h>
@@ -81,6 +80,12 @@ enum aws_h2_settings {
8180
#define AWS_H2_WINDOW_UPDATE_MAX (0x7FFFFFFF)
8281
#define AWS_H2_STREAM_ID_MAX (0x7FFFFFFF)
8382

83+
/* Legal min(inclusive) and max(inclusive) for each setting */
84+
extern const uint32_t aws_h2_settings_bounds[AWS_H2_SETTINGS_END_RANGE][2];
85+
86+
/* Initial values for settings RFC-7540 6.5.2 */
87+
extern const uint32_t aws_h2_settings_initial[AWS_H2_SETTINGS_END_RANGE];
88+
8489
/* This magic string must be the very first thing a client sends to the server.
8590
* See RFC-7540 3.5 - HTTP/2 Connection Preface */
8691
extern const struct aws_byte_cursor aws_h2_connection_preface_client_string;
@@ -101,23 +106,6 @@ struct aws_h2_frame_priority_settings {
101106
uint8_t weight;
102107
};
103108

104-
struct aws_h2_frame_header_block {
105-
const struct aws_http_headers *headers;
106-
107-
/* state */
108-
109-
enum {
110-
AWS_H2_HEADER_BLOCK_STATE_INIT,
111-
AWS_H2_HEADER_BLOCK_STATE_FIRST_FRAME,
112-
AWS_H2_HEADER_BLOCK_STATE_CONTINUATION,
113-
AWS_H2_HEADER_BLOCK_STATE_COMPLETE,
114-
AWS_H2_HEADER_BLOCK_STATE_ERROR,
115-
} state;
116-
117-
struct aws_byte_buf whole_encoded_block; /* entire header block is encoded here */
118-
struct aws_byte_cursor encoded_block_cursor; /* tracks progress sending encoded header-block in fragments */
119-
};
120-
121109
/**
122110
* A frame to be encoded.
123111
* (in the case of HEADERS and PUSH_PROMISE, it might turn into multiple frames due to CONTINUATION)
@@ -130,19 +118,33 @@ struct aws_h2_frame {
130118
struct aws_linked_list_node node;
131119
};
132120

133-
/* Represents a HEADERS header-block.
134-
* (HEADERS frame followed 0 or more CONTINUATION frames) */
121+
/* Represents a HEADERS or PUSH_PROMISE frame (followed by zero or more CONTINUATION frames) */
135122
struct aws_h2_frame_headers {
136123
struct aws_h2_frame base;
137124

138-
/* Flags */
125+
/* Common data */
126+
const struct aws_http_headers *headers;
127+
uint8_t pad_length; /* Set to 0 to disable AWS_H2_FRAME_F_PADDED */
128+
129+
/* HEADERS-only data */
139130
bool end_stream; /* AWS_H2_FRAME_F_END_STREAM */
140131
bool has_priority; /* AWS_H2_FRAME_F_PRIORITY */
141-
142-
/* Payload */
143-
uint8_t pad_length; /* Set to 0 to disable AWS_H2_FRAME_F_PADDED */
144132
struct aws_h2_frame_priority_settings priority;
145-
struct aws_h2_frame_header_block header_block;
133+
134+
/* PUSH_PROMISE-only data */
135+
uint32_t promised_stream_id;
136+
137+
/* State */
138+
enum {
139+
AWS_H2_HEADERS_STATE_INIT,
140+
AWS_H2_HEADERS_STATE_FIRST_FRAME,
141+
AWS_H2_HEADERS_STATE_CONTINUATION,
142+
AWS_H2_HEADERS_STATE_COMPLETE,
143+
AWS_H2_HEADERS_STATE_ERROR,
144+
} state;
145+
146+
struct aws_byte_buf whole_encoded_header_block;
147+
struct aws_byte_cursor header_block_cursor; /* tracks progress sending encoded header-block in fragments */
146148
};
147149

148150
/* Represents a PRIORITY frame */
@@ -179,17 +181,6 @@ struct aws_h2_frame_settings {
179181
size_t settings_count;
180182
};
181183

182-
/* Represents a PUSH_PROMISE header-block.
183-
* (PUSH_PROMISE frame followed by 0 or more CONTINUATION frames) */
184-
struct aws_h2_frame_push_promise {
185-
struct aws_h2_frame base;
186-
187-
/* Payload */
188-
uint8_t pad_length; /* Set to 0 to disable AWS_H2_FRAME_F_PADDED */
189-
uint32_t promised_stream_id;
190-
struct aws_h2_frame_header_block header_block;
191-
};
192-
193184
#define AWS_H2_PING_DATA_SIZE (8)
194185

195186
/* Represents a PING frame */
@@ -223,12 +214,11 @@ struct aws_h2_frame_window_update {
223214

224215
/* Used to encode a frame */
225216
struct aws_h2_frame_encoder {
226-
/* Larger state */
227217
struct aws_allocator *allocator;
218+
const void *logging_id;
228219
struct aws_hpack_context *hpack;
229220
struct aws_h2_frame *current_frame;
230221
bool has_errored;
231-
enum aws_hpack_huffman_mode huffman_mode;
232222
};
233223

234224
typedef void aws_h2_frame_destroy_fn(struct aws_h2_frame *frame_base);
@@ -258,7 +248,8 @@ int aws_h2_validate_stream_id(uint32_t stream_id);
258248
* 2. Encode the frame using aws_h2_frame_*_encode
259249
*/
260250
AWS_HTTP_API
261-
int aws_h2_frame_encoder_init(struct aws_h2_frame_encoder *encoder, struct aws_allocator *allocator);
251+
int aws_h2_frame_encoder_init(struct aws_h2_frame_encoder *encoder, struct aws_allocator *allocator, void *logging_id);
252+
262253
AWS_HTTP_API
263254
void aws_h2_frame_encoder_clean_up(struct aws_h2_frame_encoder *encoder);
264255

include/aws/http/private/hpack.h

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ struct aws_hpack_decode_result {
5252
* This only controls how string values are encoded when they're not already in a table.
5353
*/
5454
enum aws_hpack_huffman_mode {
55+
AWS_HPACK_HUFFMAN_SMALLEST,
5556
AWS_HPACK_HUFFMAN_NEVER,
5657
AWS_HPACK_HUFFMAN_ALWAYS,
57-
AWS_HPACK_HUFFMAN_SMALLEST,
5858
};
5959

6060
AWS_EXTERN_C_BEGIN
@@ -90,24 +90,13 @@ int aws_hpack_decode(
9090
struct aws_hpack_decode_result *result);
9191

9292
/**
93-
* Must be called at start of header-block.
94-
* If the table has been resized, then a Dynamic Table Size Update (RFC-7541 6.3) is encoded.
95-
* This behavior is described in RFC-7541 4.2.
93+
* Encode header-block into the output.
94+
* This function will mutate the hpack context, so an error means the context can no longer be used.
9695
* Note that output will be dynamically resized if it's too short.
9796
*/
98-
AWS_HTTP_API
99-
int aws_hpack_encode_header_block_start(struct aws_hpack_context *context, struct aws_byte_buf *output);
100-
101-
/**
102-
* Encode a header-field into the output.
103-
* This function will mutate the hpack context, so any error is unrecoverable.
104-
* Note that output will be dynamically resized if it's too short.
105-
*/
106-
AWS_HTTP_API
107-
int aws_hpack_encode_header(
97+
int aws_hpack_encode_header_block(
10898
struct aws_hpack_context *context,
109-
const struct aws_http_header *header,
110-
enum aws_hpack_huffman_mode huffman_mode,
99+
const struct aws_http_headers *headers,
111100
struct aws_byte_buf *output);
112101

113102
/* Returns the hpack size of a header (name.len + value.len + 32) [4.1] */
@@ -132,6 +121,9 @@ int aws_hpack_insert_header(struct aws_hpack_context *context, const struct aws_
132121
AWS_HTTP_API
133122
int aws_hpack_resize_dynamic_table(struct aws_hpack_context *context, size_t new_max_size);
134123

124+
AWS_HTTP_API
125+
void aws_hpack_set_huffman_mode(struct aws_hpack_context *context, enum aws_hpack_huffman_mode mode);
126+
135127
/* Public for testing purposes.
136128
* Output will be dynamically resized if it's too short */
137129
AWS_HTTP_API
@@ -152,7 +144,6 @@ AWS_HTTP_API
152144
int aws_hpack_encode_string(
153145
struct aws_hpack_context *context,
154146
struct aws_byte_cursor to_encode,
155-
enum aws_hpack_huffman_mode huffman_mode,
156147
struct aws_byte_buf *output);
157148

158149
/* Public for testing purposes */

include/aws/http/request_response.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,13 @@ void aws_http_headers_release(struct aws_http_headers *headers);
362362
* The underlying strings are copied.
363363
*/
364364
AWS_HTTP_API
365+
int aws_http_headers_add_v2(struct aws_http_headers *headers, const struct aws_http_header *header);
366+
367+
/**
368+
* Add a header with default compression settings.
369+
* The underlying strings are copied.
370+
*/
371+
AWS_HTTP_API
365372
int aws_http_headers_add(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value);
366373

367374
/**

source/h2_connection.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static struct aws_h2_connection *s_connection_new(
219219
goto error;
220220
}
221221

222-
if (aws_h2_frame_encoder_init(&connection->thread_data.encoder, alloc)) {
222+
if (aws_h2_frame_encoder_init(&connection->thread_data.encoder, alloc, &connection->base)) {
223223
CONNECTION_LOGF(
224224
ERROR, connection, "Encoder init error %d (%s)", aws_last_error(), aws_error_name(aws_last_error()));
225225
goto error;

source/h2_decoder.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ int aws_h2_decode(struct aws_h2_decoder *decoder, struct aws_byte_cursor *data)
244244
/* Run decoder state machine until we're no longer changing states.
245245
* We don't simply loop `while(data->len)` because some states consume no data,
246246
* and these states should run even when there is no data left. */
247-
for (decoder->state_changed = false; decoder->state_changed; decoder->state_changed = false) {
247+
do {
248+
decoder->state_changed = false;
248249

249250
const uint32_t bytes_required = decoder->state->bytes_required;
250251
AWS_ASSERT(bytes_required <= decoder->scratch.capacity);
@@ -302,7 +303,7 @@ int aws_h2_decode(struct aws_h2_decoder *decoder, struct aws_byte_cursor *data)
302303
decoder->scratch.len);
303304
}
304305
}
305-
}
306+
} while (decoder->state_changed);
306307

307308
return AWS_OP_SUCCESS;
308309

0 commit comments

Comments
 (0)