]> granicus.if.org Git - apache/blob - modules/http2/h2_stream.h
reduced h2_request initialization/copy after review by CJ
[apache] / modules / http2 / h2_stream.h
1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
2  *
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
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  
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.
14  */
15
16 #ifndef __mod_h2__h2_stream__
17 #define __mod_h2__h2_stream__
18
19 #include "h2.h"
20
21 /**
22  * A HTTP/2 stream, e.g. a client request+response in HTTP/1.1 terms.
23  * 
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
28  * a h2_response.
29  * 
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.
32  */
33 #include "h2_io.h"
34
35 struct h2_mplx;
36 struct h2_priority;
37 struct h2_request;
38 struct h2_response;
39 struct h2_session;
40 struct h2_sos;
41
42 typedef struct h2_stream h2_stream;
43
44 struct 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 */
48     
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 */
52     
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 */
57     
58     apr_off_t input_remaining;  /* remaining bytes on input as advertised via content-length */
59
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 */
62 };
63
64
65 #define H2_STREAM_RST(s, def)    (s->rst_error? s->rst_error : (def))
66
67 /**
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
73  */
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);
76
77 /**
78  * Destroy any resources held by this stream. Will destroy memory pool
79  * if still owned by the stream.
80  *
81  * @param stream the stream to destroy
82  */
83 apr_status_t h2_stream_destroy(h2_stream *stream);
84
85 /**
86  * Removes stream from h2_session and destroys it.
87  *
88  * @param stream the stream to cleanup
89  */
90 void h2_stream_cleanup(h2_stream *stream);
91
92 /**
93  * Detach the memory pool from the stream. Will prevent stream
94  * destruction to take the pool with it.
95  *
96  * @param stream the stream to detach the pool from
97  * @param the detached memmory pool or NULL if stream no longer has one
98  */
99 apr_pool_t *h2_stream_detach_pool(h2_stream *stream);
100
101
102 /**
103  * Initialize stream->request with the given request_rec.
104  * 
105  * @param stream stream to write request to
106  * @param r the request with all the meta data
107  */
108 apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r);
109
110 /*
111  * Add a HTTP/2 header (including pseudo headers) or trailer 
112  * to the given stream, depending on stream state.
113  *
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
119  */
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);
123
124 /**
125  * Closes the stream's input.
126  *
127  * @param stream stream to close intput of
128  */
129 apr_status_t h2_stream_close_input(h2_stream *stream);
130
131 /*
132  * Write a chunk of DATA to the stream.
133  *
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
137  */
138 apr_status_t h2_stream_write_data(h2_stream *stream,
139                                   const char *data, size_t len, int eos);
140
141 /**
142  * Reset the stream. Stream write/reads will return errors afterwards.
143  *
144  * @param stream the stream to reset
145  * @param error_code the HTTP/2 error code
146  */
147 void h2_stream_rst(h2_stream *streamm, int error_code);
148
149 /**
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.
153  * 
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
158  */
159 apr_status_t h2_stream_schedule(h2_stream *stream, int eos, int push_enabled,
160                                 h2_stream_pri_cmp *cmp, void *ctx);
161
162 /**
163  * Determine if stream has been scheduled already.
164  * @param stream the stream to check on
165  * @return != 0 iff stream has been scheduled
166  */
167 int h2_stream_is_scheduled(const h2_stream *stream);
168
169 struct h2_response *h2_stream_get_response(h2_stream *stream);
170
171 /**
172  * Set the response for this stream. Invoked when all meta data for
173  * the stream response has been collected.
174  * 
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,
178  *        may be incomplete.
179  */
180 apr_status_t h2_stream_set_response(h2_stream *stream, 
181                                     struct h2_response *response,
182                                     apr_bucket_brigade *bb);
183
184 /**
185  * Do a speculative read on the stream output to determine the 
186  * amount of data that can be read.
187  * 
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
192  *        bytes (out value).
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
195  *         reached yet.
196  */
197 apr_status_t h2_stream_out_prepare(h2_stream *stream, 
198                                    apr_off_t *plen, int *peos);
199
200 /**
201  * Read data from the stream output.
202  * 
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
212  *         reached yet.
213  */
214 apr_status_t h2_stream_readx(h2_stream *stream, h2_io_data_cb *cb, 
215                              void *ctx, apr_off_t *plen, int *peos);
216
217 /**
218  * Read a maximum number of bytes into the bucket brigade.
219  * 
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
227  *         reached yet.
228  */
229 apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, 
230                                apr_off_t *plen, int *peos);
231
232 /**
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
235  * been reached.
236  *
237  * @param stream to ask for trailers
238  * @return trailers for NULL
239  */
240 apr_table_t *h2_stream_get_trailers(h2_stream *stream);
241
242 /**
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
246  */
247 void h2_stream_set_suspended(h2_stream *stream, int suspended);
248
249 /**
250  * Check if the stream has been suspended.
251  * @param stream the stream to check
252  * @return != 0 iff stream is suspended.
253  */
254 int h2_stream_is_suspended(const h2_stream *stream);
255
256 /**
257  * Check if the stream has open input.
258  * @param stream the stream to check
259  * @return != 0 iff stream has open input.
260  */
261 int h2_stream_input_is_open(const h2_stream *stream);
262
263 /**
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.
267  */
268 int h2_stream_needs_submit(const h2_stream *stream);
269
270 /**
271  * Submit any server push promises on this stream and schedule
272  * the tasks connection with these.
273  *
274  * @param stream the stream for which to submit
275  */
276 apr_status_t h2_stream_submit_pushes(h2_stream *stream);
277
278 /**
279  * Get priority information set for this stream.
280  */
281 const struct h2_priority *h2_stream_get_priority(h2_stream *stream);
282
283 #endif /* defined(__mod_h2__h2_stream__) */