1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #ifndef __mod_h2__h2_stream__
17 #define __mod_h2__h2_stream__
22 * A HTTP/2 stream, e.g. a client request+response in HTTP/1.1 terms.
24 * A stream always belongs to a h2_session, the one managing the
25 * connection to the client. The h2_session writes to the h2_stream,
26 * adding HEADERS and DATA and finally an EOS. When headers are done,
27 * h2_stream is scheduled for handling, which is expected to produce
30 * The h2_response gives the HEADER frames to sent to the client, followed
31 * by DATA frames read from the h2_stream until EOS is reached.
42 typedef struct h2_stream h2_stream;
45 int id; /* http2 stream id */
46 h2_stream_state_t state; /* http/2 state of this stream */
47 struct h2_session *session; /* the session this stream belongs to */
49 apr_pool_t *pool; /* the memory pool for this stream */
50 struct h2_request *request; /* the request made in this stream */
51 int rst_error; /* stream error for RST_STREAM */
53 unsigned int aborted : 1; /* was aborted */
54 unsigned int suspended : 1; /* DATA sending has been suspended */
55 unsigned int scheduled : 1; /* stream has been scheduled */
56 unsigned int submitted : 1; /* response HEADER has been sent */
58 apr_off_t input_remaining; /* remaining bytes on input as advertised via content-length */
60 struct h2_sos *sos; /* stream output source, e.g. to read output from */
61 apr_off_t data_frames_sent; /* # of DATA frames sent out for this stream */
65 #define H2_STREAM_RST(s, def) (s->rst_error? s->rst_error : (def))
68 * Create a stream in OPEN state.
69 * @param id the stream identifier
70 * @param pool the memory pool to use for this stream
71 * @param session the session this stream belongs to
72 * @return the newly opened stream
74 h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session,
75 int initiated_on, const struct h2_request *req);
78 * Destroy any resources held by this stream. Will destroy memory pool
79 * if still owned by the stream.
81 * @param stream the stream to destroy
83 apr_status_t h2_stream_destroy(h2_stream *stream);
86 * Removes stream from h2_session and destroys it.
88 * @param stream the stream to cleanup
90 void h2_stream_cleanup(h2_stream *stream);
93 * Detach the memory pool from the stream. Will prevent stream
94 * destruction to take the pool with it.
96 * @param stream the stream to detach the pool from
97 * @param the detached memmory pool or NULL if stream no longer has one
99 apr_pool_t *h2_stream_detach_pool(h2_stream *stream);
103 * Initialize stream->request with the given request_rec.
105 * @param stream stream to write request to
106 * @param r the request with all the meta data
108 apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r);
111 * Add a HTTP/2 header (including pseudo headers) or trailer
112 * to the given stream, depending on stream state.
114 * @param stream stream to write the header to
115 * @param name the name of the HTTP/2 header
116 * @param nlen the number of characters in name
117 * @param value the header value
118 * @param vlen the number of characters in value
120 apr_status_t h2_stream_add_header(h2_stream *stream,
121 const char *name, size_t nlen,
122 const char *value, size_t vlen);
125 * Closes the stream's input.
127 * @param stream stream to close intput of
129 apr_status_t h2_stream_close_input(h2_stream *stream);
132 * Write a chunk of DATA to the stream.
134 * @param stream stream to write the data to
135 * @param data the beginning of the bytes to write
136 * @param len the number of bytes to write
138 apr_status_t h2_stream_write_data(h2_stream *stream,
139 const char *data, size_t len, int eos);
142 * Reset the stream. Stream write/reads will return errors afterwards.
144 * @param stream the stream to reset
145 * @param error_code the HTTP/2 error code
147 void h2_stream_rst(h2_stream *streamm, int error_code);
150 * Schedule the stream for execution. All header information must be
151 * present. Use the given priority comparision callback to determine
152 * order in queued streams.
154 * @param stream the stream to schedule
155 * @param eos != 0 iff no more input will arrive
156 * @param cmp priority comparision
157 * @param ctx context for comparision
159 apr_status_t h2_stream_schedule(h2_stream *stream, int eos, int push_enabled,
160 h2_stream_pri_cmp *cmp, void *ctx);
163 * Determine if stream has been scheduled already.
164 * @param stream the stream to check on
165 * @return != 0 iff stream has been scheduled
167 int h2_stream_is_scheduled(const h2_stream *stream);
169 struct h2_response *h2_stream_get_response(h2_stream *stream);
172 * Set the response for this stream. Invoked when all meta data for
173 * the stream response has been collected.
175 * @param stream the stream to set the response for
176 * @param resonse the response data for the stream
177 * @param bb bucket brigade with output data for the stream. Optional,
180 apr_status_t h2_stream_set_response(h2_stream *stream,
181 struct h2_response *response,
182 apr_bucket_brigade *bb);
185 * Do a speculative read on the stream output to determine the
186 * amount of data that can be read.
188 * @param stream the stream to speculatively read from
189 * @param plen (in-/out) number of bytes requested and on return amount of bytes that
190 * may be read without blocking
191 * @param peos (out) != 0 iff end of stream will be reached when reading plen
193 * @return APR_SUCCESS if out information was computed successfully.
194 * APR_EAGAIN if not data is available and end of stream has not been
197 apr_status_t h2_stream_out_prepare(h2_stream *stream,
198 apr_off_t *plen, int *peos);
201 * Read data from the stream output.
203 * @param stream the stream to read from
204 * @param cb callback to invoke for byte chunks read. Might be invoked
205 * multiple times (with different values) for one read operation.
206 * @param ctx context data for callback
207 * @param plen (in-/out) max. number of bytes to read and on return actual
208 * number of bytes read
209 * @param peos (out) != 0 iff end of stream has been reached while reading
210 * @return APR_SUCCESS if out information was computed successfully.
211 * APR_EAGAIN if not data is available and end of stream has not been
214 apr_status_t h2_stream_readx(h2_stream *stream, h2_io_data_cb *cb,
215 void *ctx, apr_off_t *plen, int *peos);
218 * Read a maximum number of bytes into the bucket brigade.
220 * @param stream the stream to read from
221 * @param bb the brigade to append output to
222 * @param plen (in-/out) max. number of bytes to append and on return actual
223 * number of bytes appended to brigade
224 * @param peos (out) != 0 iff end of stream has been reached while reading
225 * @return APR_SUCCESS if out information was computed successfully.
226 * APR_EAGAIN if not data is available and end of stream has not been
229 apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb,
230 apr_off_t *plen, int *peos);
233 * Get optional trailers for this stream, may be NULL. Meaningful
234 * results can only be expected when the end of the response body has
237 * @param stream to ask for trailers
238 * @return trailers for NULL
240 apr_table_t *h2_stream_get_trailers(h2_stream *stream);
243 * Set the suspended state of the stream.
244 * @param stream the stream to change state on
245 * @param suspended boolean value if stream is suspended
247 void h2_stream_set_suspended(h2_stream *stream, int suspended);
250 * Check if the stream has been suspended.
251 * @param stream the stream to check
252 * @return != 0 iff stream is suspended.
254 int h2_stream_is_suspended(const h2_stream *stream);
257 * Check if the stream has open input.
258 * @param stream the stream to check
259 * @return != 0 iff stream has open input.
261 int h2_stream_input_is_open(const h2_stream *stream);
264 * Check if the stream has not submitted a response or RST yet.
265 * @param stream the stream to check
266 * @return != 0 iff stream has not submitted a response or RST.
268 int h2_stream_needs_submit(const h2_stream *stream);
271 * Submit any server push promises on this stream and schedule
272 * the tasks connection with these.
274 * @param stream the stream for which to submit
276 apr_status_t h2_stream_submit_pushes(h2_stream *stream);
279 * Get priority information set for this stream.
281 const struct h2_priority *h2_stream_get_priority(h2_stream *stream);
283 #endif /* defined(__mod_h2__h2_stream__) */