File: h1_stream.h

package info (click to toggle)
aws-crt-python 0.20.4%2Bdfsg-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 72,656 kB
  • sloc: ansic: 381,805; python: 23,008; makefile: 6,251; sh: 4,536; cpp: 699; ruby: 208; java: 77; perl: 73; javascript: 46; xml: 11
file content (124 lines) | stat: -rw-r--r-- 4,772 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef AWS_HTTP_H1_STREAM_H
#define AWS_HTTP_H1_STREAM_H
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#include <aws/http/private/h1_encoder.h>
#include <aws/http/private/http_impl.h>
#include <aws/http/private/request_response_impl.h>
#include <aws/io/channel.h>

#ifdef _MSC_VER
#    pragma warning(disable : 4214) /* nonstandard extension used: bit field types other than int */
#endif

/* Simple view of stream's state.
 * Used to determine whether it's safe for a user to call functions that alter state. */
enum aws_h1_stream_api_state {
    AWS_H1_STREAM_API_STATE_INIT,
    AWS_H1_STREAM_API_STATE_ACTIVE,
    AWS_H1_STREAM_API_STATE_COMPLETE,
};

struct aws_h1_stream {
    struct aws_http_stream base;

    struct aws_linked_list_node node;

    /* Task that removes items from `synced_data` and does their on-thread work.
     * Runs once and wait until it's scheduled again.
     * Any function that wants to schedule this task MUST:
     * - acquire the synced_data.lock
     * - check whether `synced_data.is_cross_thread_work_scheduled` was true or false.
     * - set `synced_data.is_cross_thread_work_scheduled = true`
     * - release synced_data.lock
     * - ONLY IF `synced_data.is_cross_thread_work_scheduled` CHANGED from false to true:
     *   - increment the stream's refcount, to keep stream alive until task runs
     *   - schedule the task
     */
    struct aws_channel_task cross_thread_work_task;

    /* Message (derived from outgoing request or response) to be submitted to encoder */
    struct aws_h1_encoder_message encoder_message;

    bool is_outgoing_message_done;

    bool is_incoming_message_done;
    bool is_incoming_head_done;

    /* If true, this is the last stream the connection should process.
     * See RFC-7230 Section 6: Connection Management. */
    bool is_final_stream;

    /* Buffer for incoming data that needs to stick around. */
    struct aws_byte_buf incoming_storage_buf;

    struct {
        /* TODO: move most other members in here */

        /* List of `struct aws_h1_chunk`, used for chunked encoding.
         * Encoder completes/frees/pops front chunk when it's done sending. */
        struct aws_linked_list pending_chunk_list;

        struct aws_h1_encoder_message message;

        /* Size of stream's flow-control window.
         * Only body data (not headers, etc) counts against the stream's flow-control window. */
        uint64_t stream_window;

        /* Whether a "request handler" stream has a response to send.
         * Has mirror variable in synced_data */
        bool has_outgoing_response : 1;
    } thread_data;

    /* Any thread may touch this data, but the connection's lock must be held.
     * Sharing a lock is fine because it's rare for an HTTP/1 connection
     * to have more than one stream at a time. */
    struct {
        /* List of `struct aws_h1_chunk` which have been submitted by user,
         * but haven't yet moved to encoder_message.pending_chunk_list where the encoder will find them. */
        struct aws_linked_list pending_chunk_list;

        /* trailing headers which have been submitted by user,
         * but haven't yet moved to encoder_message where the encoder will find them. */
        struct aws_h1_trailer *pending_trailer;

        enum aws_h1_stream_api_state api_state;

        /* Sum of all aws_http_stream_update_window() calls that haven't yet moved to thread_data.stream_window */
        uint64_t pending_window_update;

        /* See `cross_thread_work_task` */
        bool is_cross_thread_work_task_scheduled : 1;

        /* Whether a "request handler" stream has a response to send.
         * Has mirror variable in thread_data */
        bool has_outgoing_response : 1;

        /* Whether the outgoing message is using chunked encoding */
        bool using_chunked_encoding : 1;

        /* Whether the final 0 length chunk has already been sent */
        bool has_final_chunk : 1;

        /* Whether the chunked trailer has already been sent */
        bool has_added_trailer : 1;
    } synced_data;
};

/* DO NOT export functions below. They're only used by other .c files in this library */

struct aws_h1_stream *aws_h1_stream_new_request(
    struct aws_http_connection *client_connection,
    const struct aws_http_make_request_options *options);

struct aws_h1_stream *aws_h1_stream_new_request_handler(const struct aws_http_request_handler_options *options);

int aws_h1_stream_activate(struct aws_http_stream *stream);
void aws_h1_stream_cancel(struct aws_http_stream *stream, int error_code);

int aws_h1_stream_send_response(struct aws_h1_stream *stream, struct aws_http_message *response);

#endif /* AWS_HTTP_H1_STREAM_H */