Author: rhuijben Date: Mon Nov 16 13:02:06 2015 New Revision: 1714585 URL: http://svn.apache.org/viewvc?rev=1714585&view=rev Log: * protocols/http2_stream.c Switch file from subversion code layout to serf code layout. No functional changes... just whitespace.
Modified: serf/trunk/protocols/http2_stream.c Modified: serf/trunk/protocols/http2_stream.c URL: http://svn.apache.org/viewvc/serf/trunk/protocols/http2_stream.c?rev=1714585&r1=1714584&r2=1714585&view=diff ============================================================================== --- serf/trunk/protocols/http2_stream.c (original) +++ serf/trunk/protocols/http2_stream.c Mon Nov 16 13:02:06 2015 @@ -31,8 +31,8 @@ struct serf_http2_stream_data_t { - serf_request_t *request; /* May be NULL as streams may outlive requests */ - serf_bucket_t *response_agg; + serf_request_t *request; /* May be NULL as streams may outlive requests */ + serf_bucket_t *response_agg; }; serf_http2_stream_t * @@ -42,44 +42,44 @@ serf_http2__stream_create(serf_http2_pro apr_uint32_t rl_window, serf_bucket_alloc_t *alloc) { - serf_http2_stream_t *stream = serf_bucket_mem_alloc(alloc, sizeof(*stream)); + serf_http2_stream_t *stream = serf_bucket_mem_alloc(alloc, + sizeof(*stream)); - stream->h2 = h2; - stream->alloc = alloc; + stream->h2 = h2; + stream->alloc = alloc; - stream->next = stream->prev = NULL; + stream->next = stream->prev = NULL; - /* Delay creating this? */ - stream->data = serf_bucket_mem_alloc(alloc, sizeof(*stream->data)); - stream->data->request = NULL; - stream->data->response_agg = NULL; + /* Delay creating this? */ + stream->data = serf_bucket_mem_alloc(alloc, sizeof(*stream->data)); + stream->data->request = NULL; + stream->data->response_agg = NULL; - stream->lr_window = lr_window; - stream->rl_window = rl_window; + stream->lr_window = lr_window; + stream->rl_window = rl_window; - if (streamid >= 0) - stream->streamid = streamid; - else - stream->streamid = -1; /* Undetermined yet */ + if (streamid >= 0) + stream->streamid = streamid; + else + stream->streamid = -1; /* Undetermined yet */ - stream->status = (streamid >= 0) ? H2S_IDLE : H2S_INIT; - stream->new_reserved_stream = NULL; + stream->status = (streamid >= 0) ? H2S_IDLE : H2S_INIT; + stream->new_reserved_stream = NULL; - return stream; + return stream; } void serf_http2__stream_cleanup(serf_http2_stream_t *stream) { - if (stream->data) - { - if (stream->data->response_agg) - serf_bucket_destroy(stream->data->response_agg); + if (stream->data) { + if (stream->data->response_agg) + serf_bucket_destroy(stream->data->response_agg); - serf_bucket_mem_free(stream->alloc, stream->data); - stream->data = NULL; + serf_bucket_mem_free(stream->alloc, stream->data); + stream->data = NULL; } - serf_bucket_mem_free(stream->alloc, stream); + serf_bucket_mem_free(stream->alloc, stream); } apr_status_t @@ -88,119 +88,115 @@ serf_http2__stream_setup_next_request(se apr_size_t max_payload_size, serf_hpack_table_t *hpack_tbl) { - serf_request_t *request = conn->unwritten_reqs; - apr_status_t status; - serf_bucket_t *hpack; - serf_bucket_t *body; - bool first_frame; - bool end_stream; - - SERF_H2_assert(request != NULL); - if (!request) - return APR_EGENERAL; - - stream->data->request = request; - - if (!request->req_bkt) - { - status = serf__setup_request(request); - if (status) + serf_request_t *request = conn->unwritten_reqs; + apr_status_t status; + serf_bucket_t *hpack; + serf_bucket_t *body; + bool first_frame; + bool end_stream; + + SERF_H2_assert(request != NULL); + if (!request) + return APR_EGENERAL; + + stream->data->request = request; + + if (!request->req_bkt) { + status = serf__setup_request(request); + if (status) + return status; + } + + conn->unwritten_reqs = request->next; + if (conn->unwritten_reqs_tail == request) + conn->unwritten_reqs = conn->unwritten_reqs_tail = NULL; + + request->next = NULL; + + serf__link_requests(&conn->written_reqs, &conn->written_reqs_tail, + request); + conn->nr_of_written_reqs++; + conn->nr_of_written_reqs--; + + serf__bucket_request_read(request->req_bkt, &body, NULL, NULL); + status = serf__bucket_hpack_create_from_request( + &hpack, hpack_tbl, + request->req_bkt, + request->conn->host_info.scheme, + request->allocator); + if (status) return status; + + if (!body) { + serf_bucket_destroy(request->req_bkt); + request->req_bkt = NULL; + end_stream = true; } + else + end_stream = false; - conn->unwritten_reqs = request->next; - if (conn->unwritten_reqs_tail == request) - conn->unwritten_reqs = conn->unwritten_reqs_tail = NULL; - - request->next = NULL; - - serf__link_requests(&conn->written_reqs, &conn->written_reqs_tail, - request); - conn->nr_of_written_reqs++; - conn->nr_of_written_reqs--; - - serf__bucket_request_read(request->req_bkt, &body, NULL, NULL); - status = serf__bucket_hpack_create_from_request(&hpack, hpack_tbl, - request->req_bkt, - request->conn->host_info.scheme, - request->allocator); - if (status) - return status; + first_frame = true; - if (!body) - { - serf_bucket_destroy(request->req_bkt); - request->req_bkt = NULL; - end_stream = true; - } - else - end_stream = false; - - first_frame = true; - - /* And now schedule the packet for writing. Note that it is required - by the HTTP/2 spec to send HEADERS and CONTINUATION directly after - each other, without other frames inbetween. */ - while (hpack != NULL) + /* And now schedule the packet for writing. Note that it is required + by the HTTP/2 spec to send HEADERS and CONTINUATION directly after + each other, without other frames inbetween. */ + while (hpack != NULL) { - serf_bucket_t *next; - apr_uint64_t remaining; + serf_bucket_t *next; + apr_uint64_t remaining; - /* hpack buckets implement get_remaining. And if they didn't adding the - framing around them would apply some reads that fix the buckets. + /* hpack buckets implement get_remaining. And if they didn't adding the + framing around them would apply some reads that fix the buckets. - So we can ignore the theoretical endless loop here for two different - reasons - */ - remaining = serf_bucket_get_remaining(hpack); + So we can ignore the theoretical endless loop here for two different + reasons + */ + remaining = serf_bucket_get_remaining(hpack); - if (remaining > max_payload_size) - { - serf_bucket_split_create(&next, &hpack, hpack, - max_payload_size - (max_payload_size / 4), - max_payload_size); + if (remaining > max_payload_size) { + serf_bucket_split_create(&next, &hpack, hpack, + max_payload_size - (max_payload_size / 4), + max_payload_size); } - else + else { - next = hpack; - hpack = NULL; + next = hpack; + hpack = NULL; } - next = serf__bucket_http2_frame_create(next, - first_frame - ? HTTP2_FRAME_TYPE_HEADERS - : HTTP2_FRAME_TYPE_CONTINUATION, - (end_stream - ? HTTP2_FLAG_END_STREAM - : 0) - | ((hpack != NULL) + next = serf__bucket_http2_frame_create(next, + first_frame + ? HTTP2_FRAME_TYPE_HEADERS + : HTTP2_FRAME_TYPE_CONTINUATION, + (end_stream + ? HTTP2_FLAG_END_STREAM + : 0) + | ((hpack != NULL) ? 0 : HTTP2_FLAG_END_HEADERS), - &stream->streamid, - serf_http2__allocate_stream_id, - stream, - max_payload_size, - request->allocator); - status = serf_http2__enqueue_frame(stream->h2, next, TRUE); + &stream->streamid, + serf_http2__allocate_stream_id, + stream, + max_payload_size, + request->allocator); + status = serf_http2__enqueue_frame(stream->h2, next, TRUE); - if (SERF_BUCKET_READ_ERROR(status)) - return status; /* Connection dead */ + if (SERF_BUCKET_READ_ERROR(status)) + return status; /* Connection dead */ - first_frame = false; /* Continue with 'continuation' frames */ + first_frame = false; /* Continue with 'continuation' frames */ } - if (end_stream) - { - stream->status = H2S_HALFCLOSED_LOCAL; /* Headers sent; no body */ + if (end_stream) { + stream->status = H2S_HALFCLOSED_LOCAL; /* Headers sent; no body */ } - else - { - stream->status = H2S_OPEN; /* Headers sent. Body to go */ - /* ### TODO: Schedule body to be sent */ + else { + stream->status = H2S_OPEN; /* Headers sent. Body to go */ + /* ### TODO: Schedule body to be sent */ } - return APR_SUCCESS; + return APR_SUCCESS; } apr_status_t @@ -208,32 +204,32 @@ serf_http2__stream_reset(serf_http2_stre apr_status_t reason, int local_reset) { - stream->status = H2S_CLOSED; + stream->status = H2S_CLOSED; - if (stream->streamid < 0) - return APR_SUCCESS; + if (stream->streamid < 0) + return APR_SUCCESS; - if (local_reset) - return serf_http2__enqueue_stream_reset(stream->h2, - stream->streamid, - reason); + if (local_reset) + return serf_http2__enqueue_stream_reset(stream->h2, + stream->streamid, + reason); - return APR_SUCCESS; + return APR_SUCCESS; } static apr_status_t stream_response_eof(void *baton, serf_bucket_t *aggregate_bucket) { - serf_http2_stream_t *stream = baton; + serf_http2_stream_t *stream = baton; - switch (stream->status) + switch (stream->status) { - case H2S_CLOSED: - case H2S_HALFCLOSED_REMOTE: - return APR_EOF; - default: - return APR_EAGAIN; + case H2S_CLOSED: + case H2S_HALFCLOSED_REMOTE: + return APR_EOF; + default: + return APR_EAGAIN; } } @@ -241,28 +237,28 @@ static void stream_setup_response(serf_http2_stream_t *stream, serf_config_t *config) { - serf_request_t *request; - serf_bucket_t *agg; + serf_request_t *request; + serf_bucket_t *agg; - agg = serf_bucket_aggregate_create(stream->alloc); - serf_bucket_aggregate_hold_open(agg, stream_response_eof, stream); + agg = serf_bucket_aggregate_create(stream->alloc); + serf_bucket_aggregate_hold_open(agg, stream_response_eof, stream); - serf_bucket_set_config(agg, config); + serf_bucket_set_config(agg, config); - request = stream->data->request; + request = stream->data->request; - if (!request) - return; + if (!request) + return; - if (! request->resp_bkt) - { - apr_pool_t *scratch_pool = request->respool; /* ### Pass scratch pool */ + if (!request->resp_bkt) { + apr_pool_t *scratch_pool = request->respool; /* ### Pass scratch pool */ - request->resp_bkt = request->acceptor(request, agg, request->acceptor_baton, - scratch_pool); + request->resp_bkt = request->acceptor(request, agg, + request->acceptor_baton, + scratch_pool); } - stream->data->response_agg = agg; + stream->data->response_agg = agg; } static apr_status_t @@ -272,56 +268,56 @@ stream_promise_item(void *baton, const char *value, apr_size_t value_sz) { - serf_http2_stream_t *parent_stream = baton; - serf_http2_stream_t *stream = parent_stream->new_reserved_stream; + serf_http2_stream_t *parent_stream = baton; + serf_http2_stream_t *stream = parent_stream->new_reserved_stream; + + SERF_H2_assert(stream != NULL); - SERF_H2_assert(stream != NULL); + /* TODO: Store key+value somewhere to allow asking the application + if it is interested in the promised stream. - /* TODO: Store key+value somewhere to allow asking the application - if it is interested in the promised stream. + Most likely it is not interested *yet* as the HTTP/2 spec + recommends pushing promised items *before* the stream that + references them. - Most likely it is not interested *yet* as the HTTP/2 spec - recommends pushing promised items *before* the stream that - references them. - - So we probably want to store the request anyway, to allow - matching this against a later added outgoing request. - */ - return APR_SUCCESS; + So we probably want to store the request anyway, to allow + matching this against a later added outgoing request. + */ + return APR_SUCCESS; } static apr_status_t stream_promise_done(void *baton, serf_bucket_t *done_agg) { - serf_http2_stream_t *parent_stream = baton; - serf_http2_stream_t *stream = parent_stream->new_reserved_stream; + serf_http2_stream_t *parent_stream = baton; + serf_http2_stream_t *stream = parent_stream->new_reserved_stream; - SERF_H2_assert(stream != NULL); - SERF_H2_assert(stream->status == H2S_RESERVED_REMOTE); - parent_stream->new_reserved_stream = NULL; /* End of PUSH_PROMISE */ + SERF_H2_assert(stream != NULL); + SERF_H2_assert(stream->status == H2S_RESERVED_REMOTE); + parent_stream->new_reserved_stream = NULL; /* End of PUSH_PROMISE */ - /* Anything else? */ + /* Anything else? */ - /* ### Absolute minimal implementation. - Just sending that we are not interested in the initial SETTINGS - would be the easier approach. */ - serf_http2__stream_reset(stream, SERF_ERROR_HTTP2_REFUSED_STREAM, TRUE); + /* ### Absolute minimal implementation. + Just sending that we are not interested in the initial SETTINGS + would be the easier approach. */ + serf_http2__stream_reset(stream, SERF_ERROR_HTTP2_REFUSED_STREAM, TRUE); - /* Exit condition: - * Either we should accept the stream and are ready to receive - HEADERS and DATA on it. - * Or we aren't and reject the stream - */ - SERF_H2_assert(stream->status == H2S_CLOSED - || stream->data->request != NULL); + /* Exit condition: + * Either we should accept the stream and are ready to receive + HEADERS and DATA on it. + * Or we aren't and reject the stream + */ + SERF_H2_assert(stream->status == H2S_CLOSED + || stream->data->request != NULL); - /* We must return a proper error or EOF here! */ - return APR_EOF; + /* We must return a proper error or EOF here! */ + return APR_EOF; } serf_bucket_t * @@ -334,44 +330,45 @@ serf_http2__stream_handle_hpack(serf_htt serf_config_t *config, serf_bucket_alloc_t *allocator) { - if (frametype == HTTP2_FRAME_TYPE_HEADERS) - { - if (!stream->data->response_agg) - stream_setup_response(stream, config); + if (frametype == HTTP2_FRAME_TYPE_HEADERS) { - bucket = serf__bucket_hpack_decode_create(bucket, NULL, NULL, max_entry_size, - hpack_tbl, allocator); + if (!stream->data->response_agg) + stream_setup_response(stream, config); - serf_bucket_aggregate_append(stream->data->response_agg, bucket); + bucket = serf__bucket_hpack_decode_create(bucket, NULL, NULL, + max_entry_size, + hpack_tbl, allocator); - if (end_stream) - { - if (stream->status == H2S_HALFCLOSED_LOCAL) - stream->status = H2S_CLOSED; - else - stream->status = H2S_HALFCLOSED_REMOTE; + serf_bucket_aggregate_append(stream->data->response_agg, bucket); + + if (end_stream) { + + if (stream->status == H2S_HALFCLOSED_LOCAL) + stream->status = H2S_CLOSED; + else + stream->status = H2S_HALFCLOSED_REMOTE; } - return NULL; /* We want to drain the bucket ourselves */ + return NULL; /* We want to drain the bucket ourselves */ } - else + else { - serf_bucket_t *agg; - SERF_H2_assert(frametype == HTTP2_FRAME_TYPE_PUSH_PROMISE); + serf_bucket_t *agg; + SERF_H2_assert(frametype == HTTP2_FRAME_TYPE_PUSH_PROMISE); + + /* First create the HPACK decoder as requested */ + bucket = serf__bucket_hpack_decode_create(bucket, + stream_promise_item, stream, + max_entry_size, + hpack_tbl, allocator); - /* First create the HPACK decoder as requested */ - bucket = serf__bucket_hpack_decode_create(bucket, - stream_promise_item, stream, - max_entry_size, - hpack_tbl, allocator); - - /* And now wrap around it the easiest way to get an EOF callback */ - agg = serf_bucket_aggregate_create(allocator); - serf_bucket_aggregate_append(agg, bucket); + /* And now wrap around it the easiest way to get an EOF callback */ + agg = serf_bucket_aggregate_create(allocator); + serf_bucket_aggregate_append(agg, bucket); - serf_bucket_aggregate_hold_open(agg, stream_promise_done, stream); + serf_bucket_aggregate_hold_open(agg, stream_promise_done, stream); - /* And return the aggregate, so the bucket will be drained for us */ - return agg; + /* And return the aggregate, so the bucket will be drained for us */ + return agg; } } @@ -383,20 +380,20 @@ serf_http2__stream_handle_data(serf_http serf_config_t *config, serf_bucket_alloc_t *allocator) { - if (!stream->data->response_agg) - stream_setup_response(stream, config); + if (!stream->data->response_agg) + stream_setup_response(stream, config); - serf_bucket_aggregate_append(stream->data->response_agg, bucket); + serf_bucket_aggregate_append(stream->data->response_agg, bucket); - if (end_stream) - { - if (stream->status == H2S_HALFCLOSED_LOCAL) - stream->status = H2S_CLOSED; - else - stream->status = H2S_HALFCLOSED_REMOTE; + if (end_stream) { + + if (stream->status == H2S_HALFCLOSED_LOCAL) + stream->status = H2S_CLOSED; + else + stream->status = H2S_HALFCLOSED_REMOTE; } - return NULL; + return NULL; } apr_status_t @@ -404,105 +401,102 @@ serf_http2__stream_processor(void *baton serf_http2_protocol_t *h2, serf_bucket_t *bucket) { - serf_http2_stream_t *stream = baton; - apr_status_t status = APR_SUCCESS; - serf_request_t *request = stream->data->request; + serf_http2_stream_t *stream = baton; + apr_status_t status = APR_SUCCESS; + serf_request_t *request = stream->data->request; - SERF_H2_assert(stream->data->response_agg != NULL); + SERF_H2_assert(stream->data->response_agg != NULL); - if (request) - { - SERF_H2_assert(request->resp_bkt != NULL); + if (request) { - status = stream->data->request->handler(request, request->resp_bkt, - request->handler_baton, - request->respool); + SERF_H2_assert(request->resp_bkt != NULL); - if (! APR_STATUS_IS_EOF(status) - && !SERF_BUCKET_READ_ERROR(status)) - return status; + status = stream->data->request->handler(request, request->resp_bkt, + request->handler_baton, + request->respool); - /* Ok, the request thinks is done, let's handle the bookkeeping, - to remove it from the outstanding requests */ - { - serf_connection_t *conn = serf_request_get_conn(request); - serf_request_t **rq = &conn->written_reqs; - serf_request_t *last = NULL; - - while (*rq && (*rq != request)) - { - last = *rq; - rq = &last->next; - } - - if (*rq) - { - (*rq) = request->next; - - if (conn->written_reqs_tail == request) - conn->written_reqs_tail = last; - - conn->nr_of_written_reqs--; - } - - serf__destroy_request(request); - stream->data->request = NULL; - } + if (!APR_STATUS_IS_EOF(status) + && !SERF_BUCKET_READ_ERROR(status)) + return status; - if (SERF_BUCKET_READ_ERROR(status)) + /* Ok, the request thinks is done, let's handle the bookkeeping, + to remove it from the outstanding requests */ { - if (stream->status != H2S_CLOSED) + serf_connection_t *conn = serf_request_get_conn(request); + serf_request_t **rq = &conn->written_reqs; + serf_request_t *last = NULL; + + while (*rq && (*rq != request)) { + last = *rq; + rq = &last->next; + } + + if (*rq) { + (*rq) = request->next; + + if (conn->written_reqs_tail == request) + conn->written_reqs_tail = last; + + conn->nr_of_written_reqs--; + } + + serf__destroy_request(request); + stream->data->request = NULL; + } + + if (SERF_BUCKET_READ_ERROR(status)) { + + if (stream->status != H2S_CLOSED) { /* Tell the other side that we are no longer interested to receive more data */ - serf_http2__stream_reset(stream, status, TRUE); + serf_http2__stream_reset(stream, status, TRUE); } - return status; + return status; } - SERF_H2_assert(APR_STATUS_IS_EOF(status)); + SERF_H2_assert(APR_STATUS_IS_EOF(status)); - /* Even though the request reported that it is done, we might not - have read all the data that we should (*cough* padding *cough*), - or perhaps an invalid 'Content-Length' value; maybe both. + /* Even though the request reported that it is done, we might not + have read all the data that we should (*cough* padding *cough*), + or perhaps an invalid 'Content-Length' value; maybe both. - This may even handle not-interested - return EOF cases, but that - would have broken the pipeline for HTTP/1.1. - */ + This may even handle not-interested - return EOF cases, but that + would have broken the pipeline for HTTP/1.1. + */ - /* ### For now, fall through and eat whatever is left. - Usually this is 0 bytes */ + /* ### For now, fall through and eat whatever is left. + Usually this is 0 bytes */ - status = APR_SUCCESS; + status = APR_SUCCESS; } - while (!status) + while (!status) { - struct iovec vecs[IOV_MAX]; - int vecs_used; + struct iovec vecs[IOV_MAX]; + int vecs_used; - /* Drain the bucket as efficiently as possible */ - status = serf_bucket_read_iovec(stream->data->response_agg, - SERF_READ_ALL_AVAIL, - IOV_MAX, vecs, &vecs_used); + /* Drain the bucket as efficiently as possible */ + status = serf_bucket_read_iovec(stream->data->response_agg, + SERF_READ_ALL_AVAIL, + IOV_MAX, vecs, &vecs_used); - if (vecs_used) - { + if (vecs_used) { /* We have data... What should we do with it? */ } } - if (APR_STATUS_IS_EOF(status) - && (stream->status == H2S_CLOSED - || stream->status == H2S_HALFCLOSED_REMOTE)) + if (APR_STATUS_IS_EOF(status) + && (stream->status == H2S_CLOSED + || stream->status == H2S_HALFCLOSED_REMOTE)) { /* If there was a request, it is already gone, so we can now safely destroy our aggregate which may include everything upto the http2 frames */ - serf_bucket_destroy(stream->data->response_agg); - stream->data->response_agg = NULL; + serf_bucket_destroy(stream->data->response_agg); + stream->data->response_agg = NULL; } - return status; + return status; }