io->id = id;
io->pool = pool;
io->bucket_alloc = bucket_alloc;
- io->request = h2_request_clone(pool, request);
+ io->request = request;
}
return io;
}
const char *s;
if (req->eoh) {
- return APR_EINVAL;
+ /* already done */
+ return APR_SUCCESS;
}
/* rfc7540, ch. 8.1.2.3:
return add_h1_trailer(req, pool, name, nlen, value, vlen);
}
-#define OPT_COPY(p, s) ((s)? apr_pstrdup(p, s) : NULL)
-
-void h2_request_copy(apr_pool_t *p, h2_request *dst, const h2_request *src)
+h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src)
{
- /* keep the dst id */
- dst->initiated_on = src->initiated_on;
- dst->method = OPT_COPY(p, src->method);
- dst->scheme = OPT_COPY(p, src->scheme);
- dst->authority = OPT_COPY(p, src->authority);
- dst->path = OPT_COPY(p, src->path);
- dst->headers = apr_table_clone(p, src->headers);
+ h2_request *dst = apr_pmemdup(p, src, sizeof(*dst));
+ dst->method = apr_pstrdup(p, src->method);
+ dst->scheme = apr_pstrdup(p, src->scheme);
+ dst->authority = apr_pstrdup(p, src->authority);
+ dst->path = apr_pstrdup(p, src->path);
+ dst->headers = apr_table_clone(p, src->headers);
if (src->trailers) {
- dst->trailers = apr_table_clone(p, src->trailers);
- }
- else {
- dst->trailers = NULL;
+ dst->trailers = apr_table_clone(p, src->trailers);
}
- dst->content_length = src->content_length;
- dst->chunked = src->chunked;
- dst->eoh = src->eoh;
- dst->body = src->body;
- dst->serialize = src->serialize;
- dst->push_policy = src->push_policy;
-}
-
-h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src)
-{
- h2_request *nreq = apr_pcalloc(p, sizeof(*nreq));
- memcpy(nreq, src, sizeof(*nreq));
- h2_request_copy(p, nreq, src);
- return nreq;
+ return dst;
}
request_rec *h2_request_create_rec(const h2_request *req, conn_rec *c)
apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool,
int eos, int push);
-void h2_request_copy(apr_pool_t *p, h2_request *dst, const h2_request *src);
-
h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src);
/**
}
}
-h2_stream *h2_session_open_stream(h2_session *session, int stream_id)
+h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
+ int initiated_on, const h2_request *req)
{
h2_stream * stream;
apr_pool_t *stream_pool;
apr_pool_tag(stream_pool, "h2_stream");
}
- stream = h2_stream_open(stream_id, stream_pool, session);
+ stream = h2_stream_open(stream_id, stream_pool, session,
+ initiated_on, req);
h2_ihash_add(session->streams, stream);
if (H2_STREAM_CLIENT_INITIATED(stream_id)) {
/* nop */
}
else {
- s = h2_session_open_stream((h2_session *)userp, frame->hd.stream_id);
+ s = h2_session_open_stream(userp, frame->hd.stream_id, 0, NULL);
}
return s? 0 : NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
}
}
/* Now we need to auto-open stream 1 for the request we got. */
- stream = h2_session_open_stream(session, 1);
+ stream = h2_session_open_stream(session, 1, 0, NULL);
if (!stream) {
status = APR_EGENERAL;
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, session->r,
session->id, is->id, nid,
push->req->method, push->req->path, is->id);
- stream = h2_session_open_stream(session, nid);
+ stream = h2_session_open_stream(session, nid, is->id, push->req);
if (stream) {
- h2_stream_set_h2_request(stream, is->id, push->req);
status = stream_schedule(session, stream, 1);
if (status != APR_SUCCESS) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c,
*
* @param session the session to register in
* @param stream_id the new stream identifier
+ * @param initiated_on the stream id this one is initiated on or 0
+ * @param req the request for this stream or NULL if not known yet
* @return the new stream
*/
-struct h2_stream *h2_session_open_stream(h2_session *session, int stream_id);
+struct h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
+ int initiated_on,
+ const h2_request *req);
+
/**
* Returns if client settings have push enabled.
static h2_sos *h2_sos_mplx_create(h2_stream *stream, h2_response *response);
-h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session)
+h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session,
+ int initiated_on, const h2_request *creq)
{
+ h2_request *req;
h2_stream *stream = apr_pcalloc(pool, sizeof(h2_stream));
+
stream->id = id;
stream->state = H2_STREAM_ST_IDLE;
stream->pool = pool;
stream->session = session;
set_state(stream, H2_STREAM_ST_OPEN);
- stream->request = h2_request_create(id, pool,
- h2_config_geti(session->config, H2_CONF_SER_HEADERS));
+
+ if (creq) {
+ /* take it into out pool and assure correct id's */
+ req = h2_request_clone(pool, creq);
+ req->id = id;
+ req->initiated_on = initiated_on;
+ }
+ else {
+ req = h2_request_create(id, pool,
+ h2_config_geti(session->config, H2_CONF_SER_HEADERS));
+ }
+ stream->request = req;
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03082)
"h2_stream(%ld-%d): opened", session->id, stream->id);
return status;
}
-void h2_stream_set_h2_request(h2_stream *stream, int initiated_on,
- const h2_request *req)
-{
- h2_request_copy(stream->pool, stream->request, req);
- stream->request->initiated_on = initiated_on;
- stream->request->eoh = 0;
-}
-
apr_status_t h2_stream_add_header(h2_stream *stream,
const char *name, size_t nlen,
const char *value, size_t vlen)
}
else {
h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
"h2_stream(%ld-%d): RST=2 (internal err) %s %s://%s%s",
stream->session->id, stream->id,
stream->request->method, stream->request->scheme,
* @param session the session this stream belongs to
* @return the newly opened stream
*/
-h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session);
+h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session,
+ int initiated_on, const struct h2_request *req);
/**
* Destroy any resources held by this stream. Will destroy memory pool
*/
apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r);
-/**
- * Initialize stream->request with the given h2_request.
- *
- * @param stream the stream to init the request for
- * @param req the request for initializing, will be copied
- */
-void h2_stream_set_h2_request(h2_stream *stream, int initiated_on,
- const struct h2_request *req);
-
/*
* Add a HTTP/2 header (including pseudo headers) or trailer
* to the given stream, depending on stream state.