Skip to content

Commit fd05f03

Browse files
authored
Merge branch 'main' into unified-write-data-api
2 parents 944d1e5 + 8bf9e53 commit fd05f03

13 files changed

Lines changed: 612 additions & 29 deletions

.github/workflows/ci.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- 'main'
77

88
env:
9-
BUILDER_VERSION: v0.9.72
9+
BUILDER_VERSION: v0.9.90
1010
BUILDER_SOURCE: releases
1111
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
1212
PACKAGE_NAME: aws-c-http
@@ -135,6 +135,7 @@ jobs:
135135
136136
# Test downstream repos.
137137
# This should not be required because we can run into a chicken and egg problem if there is a change that needs some fix in a downstream repo.
138+
# bump to ubuntu-22 since ubuntu 18 failed to install the mock server deps with python3.6
138139
downstream:
139140
runs-on: ubuntu-24.04 # latest
140141
steps:
@@ -146,7 +147,7 @@ jobs:
146147
- name: Build ${{ env.PACKAGE_NAME }}
147148
run: |
148149
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
149-
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build downstream -p ${{ env.PACKAGE_NAME }}
150+
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-ubuntu-22-x64 build downstream -p ${{ env.PACKAGE_NAME }}
150151
151152
windows:
152153
runs-on: windows-2025 # latest
@@ -203,7 +204,7 @@ jobs:
203204
python .\aws-c-http\build\deps\aws-c-common\scripts\appverifier_ctest.py --build_directory .\aws-c-http\build\aws-c-http
204205
205206
macos:
206-
runs-on: macos-14
207+
runs-on: macos-15
207208
strategy:
208209
fail-fast: false
209210
matrix:
@@ -220,7 +221,7 @@ jobs:
220221
./builder build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DAWS_USE_APPLE_NETWORK_FRAMEWORK=${{ matrix.eventloop == 'dispatch_queue' && 'ON' || 'OFF' }}
221222
222223
macos-x64:
223-
runs-on: macos-14-large
224+
runs-on: macos-15-large
224225
steps:
225226
- uses: aws-actions/configure-aws-credentials@v4
226227
with:
@@ -247,7 +248,7 @@ jobs:
247248
python3 builder.pyz build -p aws-c-http --cmake-extra=-DENABLE_LOCALHOST_INTEGRATION_TESTS=ON --config Debug
248249
249250
localhost-test-macos:
250-
runs-on: macos-14
251+
runs-on: macos-15
251252
strategy:
252253
fail-fast: false
253254
matrix:

include/aws/http/http2_stream_manager.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,17 @@ struct aws_http2_stream_manager_options {
154154
size_t max_concurrent_streams_per_connection;
155155
/**
156156
* Required.
157-
* The max number of connections will be open at same time. If all the connections are full, manager will wait until
158-
* available to vender more streams */
157+
* The max number of connections that will be open at the same time. If all the connections are full, the manager
158+
* will wait until a connection is available to vend more streams.
159+
*/
159160
size_t max_connections;
161+
/**
162+
* Optional.
163+
* The max number of concurrent streams that can be active across all connections at the same time.
164+
* 0 means no limit (default). When this limit is reached, the stream manager will wait for
165+
* existing streams to complete before creating new ones, even if connections have available capacity.
166+
*/
167+
size_t max_concurrent_streams;
160168
};
161169

162170
struct aws_http2_stream_manager_acquire_stream_options {

include/aws/http/private/h2_stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct aws_h2_stream {
8080
* to keep flow continues.
8181
*/
8282
int32_t window_size_threshold_to_send_update;
83+
aws_http2_on_remote_end_stream_fn *on_h2_remote_end_stream;
8384

8485
/* Only the event-loop thread may touch this data */
8586
struct {

include/aws/http/private/http2_stream_manager_impl.h

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ struct aws_h2_sm_connection {
4343
} thread_data;
4444

4545
enum aws_h2_sm_connection_state_type state;
46+
47+
/**
48+
* Node for tracking in the all_held_connections list,
49+
* NOTE: lock required to alter the state of the list.
50+
*/
51+
struct aws_linked_list_node node;
4652
};
4753

4854
/* Live from the user request to acquire a stream to the stream completed. */
@@ -114,6 +120,14 @@ struct aws_http2_stream_manager {
114120
*/
115121
size_t max_concurrent_streams_per_connection;
116122

123+
/**
124+
* Optional. 0 means no limit (default).
125+
* The max number of concurrent streams that can be active across all connections at the same time.
126+
* When this limit is reached, the stream manager will wait for existing streams to complete
127+
* before creating new ones, even if connections have available capacity.
128+
*/
129+
size_t max_concurrent_streams;
130+
117131
/**
118132
* Task to invoke pending acquisition callbacks asynchronously if stream manager is shutting.
119133
*/
@@ -129,26 +143,36 @@ struct aws_http2_stream_manager {
129143
enum aws_h2_sm_state_type state;
130144

131145
/**
132-
* A set of all connections that meet all requirement to use. Note: there will be connections not in this set,
133-
* but hold by the stream manager, which can be tracked by the streams created on it. Set of `struct
134-
* aws_h2_sm_connection *`
146+
* A set of all connections that meet all requirement to use. Doesn't own the connection.
147+
*
148+
* Note: there will be connections not in this set, but hold by the stream manager, which can be tracked by the
149+
* all_held_connections. Set of `struct aws_h2_sm_connection *`
135150
*/
136151
struct aws_random_access_set ideal_available_set;
137152
/**
138-
* A set of all available connections that exceed the soft limits set by users. Note: there will be connections
139-
* not in this set, but hold by the stream manager, which can be tracked by the streams created. Set of `struct
140-
* aws_h2_sm_connection *`
153+
* A set of all available connections that exceed the soft limits set by users. Doesn't own the connection.
154+
*
155+
* Note: there will be connections not in this set, but hold by the stream manager, which can be tracked by the
156+
* all_held_connections. Set of `struct aws_h2_sm_connection *`
141157
*/
142158
struct aws_random_access_set nonideal_available_set;
143-
/* We don't mantain set for connections that is full or "dead" (Cannot make any new streams). We have streams
144-
* opening from the connection tracking them */
159+
/* We don't mantain set for connections that is full or "dead" (Cannot make any new streams). We have
160+
* all_held_connections tracking them */
145161

146162
/**
147163
* The set of all incomplete stream acquisition requests (haven't decide what connection to make the request
148164
* to), list of `struct aws_h2_sm_pending_stream_acquisition*`
149165
*/
150166
struct aws_linked_list pending_stream_acquisitions;
151167

168+
/**
169+
* List of all aws_h2_sm_connection that holding the HTTP connection from connection manager.
170+
* This list tracks all aws_h2_sm_connection from getting the connection from connection manager until release
171+
* it back.
172+
* list of `struct aws_h2_sm_connection*`
173+
*/
174+
struct aws_linked_list all_held_connections;
175+
152176
/**
153177
* The number of connections acquired from connection manager and not released yet.
154178
*/

include/aws/http/request_response.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,24 @@ typedef int(
189189
*/
190190
typedef int(aws_http_on_incoming_request_done_fn)(struct aws_http_stream *stream, void *user_data);
191191

192+
/**
193+
* Invoked when the remote peer sends END_STREAM on an HTTP/2 stream.
194+
* This is always invoked on the HTTP connection's event-loop thread.
195+
*
196+
* **HTTP/2 ONLY** - This callback is only supported for HTTP/2 request.
197+
*
198+
* This callback is invoked when the remote peer finishes sending by setting the END_STREAM
199+
* flag on the final HEADERS or DATA frame. This indicates that no more data will be received from the
200+
* remote peer for this stream.
201+
*
202+
* Note: If the server sends RST_STREAM instead of END_STREAM, `on_remote_end_stream` will NOT fire,
203+
* but `on_complete` will fire with an error code.
204+
*
205+
* @param stream The HTTP/2 stream
206+
* @param user_data User data provided in aws_http_make_request_options
207+
*/
208+
typedef void(aws_http2_on_remote_end_stream_fn)(struct aws_http_stream *stream, void *user_data);
209+
192210
/**
193211
* Invoked when a request/response stream is complete, whether successful or unsuccessful
194212
* This is always invoked on the HTTP connection's event-loop thread.
@@ -290,6 +308,16 @@ struct aws_http_make_request_options {
290308
*/
291309
aws_http_on_stream_metrics_fn *on_metrics;
292310

311+
/**
312+
* Invoked when the remote peer sends END_STREAM on an HTTP/2 stream (HTTP/2 ONLY).
313+
* Optional.
314+
* See `aws_http2_on_remote_end_stream_fn`.
315+
*
316+
* This callback fires when the remote peer sends END_STREAM, which happens BEFORE `on_complete`.
317+
* Ignored for HTTP/1.x connections.
318+
*/
319+
aws_http2_on_remote_end_stream_fn *on_h2_remote_end_stream;
320+
293321
/**
294322
* Invoked when request/response stream is complete, whether successful or unsuccessful
295323
* Optional.

source/h2_stream.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ struct aws_h2_stream *aws_h2_stream_new_request(
277277
AWS_PRECONDITION(options);
278278

279279
struct aws_h2_stream *stream = aws_mem_calloc(client_connection->alloc, 1, sizeof(struct aws_h2_stream));
280+
stream->on_h2_remote_end_stream = options->on_h2_remote_end_stream;
280281

281282
/* Initialize base stream */
282283
stream->base.vtable = &s_h2_stream_vtable;
@@ -1274,6 +1275,10 @@ struct aws_h2err aws_h2_stream_on_decoder_end_stream(struct aws_h2_stream *strea
12741275
}
12751276
}
12761277

1278+
if (stream->on_h2_remote_end_stream) {
1279+
stream->on_h2_remote_end_stream(&stream->base, stream->base.user_data);
1280+
}
1281+
12771282
if (stream->thread_data.state == AWS_H2_STREAM_STATE_HALF_CLOSED_LOCAL) {
12781283
/* Both sides have sent END_STREAM */
12791284
stream->thread_data.state = AWS_H2_STREAM_STATE_CLOSED;

0 commit comments

Comments
 (0)