int flags, void *user_data)
{
struct http_ctx *ctx = (struct http_ctx *)user_data;
- return ctx->send_cb(data, length, ctx->user_ctx);
+ return ctx->send_cb(data, length, ctx->session);
}
/*
/*
* Setup and initialize connection with new HTTP/2 context.
*/
-struct http_ctx* http_new(http_send_callback cb, void *user_ctx)
+struct http_ctx* http_new(struct session *session, http_send_callback send_cb)
{
- assert(cb != NULL);
+ if (!session || !send_cb)
+ return NULL;
nghttp2_session_callbacks *callbacks;
- struct http_ctx *ctx;
+ struct http_ctx *ctx = NULL;
static const nghttp2_settings_entry iv[] = {
{ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, HTTP_MAX_CONCURRENT_STREAMS }
};
callbacks, on_frame_recv_callback);
ctx = calloc(1UL, sizeof(struct http_ctx));
- ctx->send_cb = cb;
- ctx->user_ctx = user_ctx;
+ if (!ctx)
+ goto finish;
+
+ ctx->send_cb = send_cb;
+ ctx->session = session;
queue_init(ctx->streams);
ctx->incomplete_stream = false;
ctx->submitted = 0;
nghttp2_session_server_new(&ctx->h2, callbacks, ctx);
- nghttp2_session_callbacks_del(callbacks);
-
nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE,
iv, sizeof(iv)/sizeof(*iv));
-
+finish:
+ nghttp2_session_callbacks_del(callbacks);
return ctx;
}
*
* This function may trigger outgoing HTTP/2 data, such as stream resets, window updates etc.
*/
-ssize_t http_process_input_data(struct session *s, const uint8_t *in_buf, ssize_t in_buf_len)
+ssize_t http_process_input_data(struct session *session, const uint8_t *in_buf,
+ ssize_t in_buf_len)
{
- struct http_ctx *ctx = session_http_get_server_ctx(s);
+ struct http_ctx *ctx = session_http_get_server_ctx(session);
ssize_t ret = 0;
- if (!ctx->h2) // TODO session vs h2; assert session equals
+ if (!ctx->h2)
return kr_error(ENOSYS);
+ assert(ctx->session == session);
ctx->submitted = 0;
- ctx->buf = session_wirebuf_get_free_start(s);
+ ctx->buf = session_wirebuf_get_free_start(session);
ctx->buf_pos = 0;
- ctx->buf_size = session_wirebuf_get_free_size(s);
+ ctx->buf_size = session_wirebuf_get_free_size(session);
ret = nghttp2_session_mem_recv(ctx->h2, in_buf, in_buf_len);
if (ret < 0) {
return kr_error(EINVAL);
}
- struct session *s = handle->data;
- struct http_ctx *http_ctx = session_http_get_server_ctx(s);
+ struct session *session = handle->data;
+ struct http_ctx *http_ctx = session_http_get_server_ctx(session);
assert (http_ctx);
- assert (!session_flags(s)->outgoing);
+ assert (!session_flags(session)->outgoing);
char size[MAX_DECIMAL_LENGTH(pkt->size)] = { 0 };
int size_len = snprintf(size, MAX_DECIMAL_LENGTH(pkt->size), "%ld", pkt->size);
/** Transport session (opaque). */
struct session;
-typedef ssize_t(*http_send_callback)(const uint8_t *buffer, const size_t buffer_len, void *user_ctx);
+typedef ssize_t(*http_send_callback)(const uint8_t *buffer,
+ const size_t buffer_len,
+ struct session *session);
typedef queue_t(int32_t) queue_int32_t;
struct http_ctx {
struct nghttp2_session *h2;
http_send_callback send_cb;
- void *user_ctx;
- queue_int32_t streams; /* List of stream IDs of read HTTP/2 frames. */
+ struct session *session;
+ queue_int32_t streams; /* IDs of streams present in the buffer. */
bool incomplete_stream;
ssize_t submitted;
- uint8_t *buf; /* Part of the session->wire_buf that belongs to current HTTP/2 stream. */
+ uint8_t *buf; /* Part of the wire_buf that belongs to current HTTP/2 stream. */
ssize_t buf_pos;
ssize_t buf_size;
};
-struct http_ctx* http_new(http_send_callback cb, void *user_ctx);
-ssize_t http_process_input_data(struct session *s, const uint8_t *buf, ssize_t nread);
-int http_write(uv_write_t *req, uv_handle_t *handle, int32_t stream_id, knot_pkt_t *pkt, uv_write_cb cb);
+struct http_ctx* http_new(struct session *session, http_send_callback send_cb);
+ssize_t http_process_input_data(struct session *session, const uint8_t *buf, ssize_t nread);
+int http_write(uv_write_t *req, uv_handle_t *handle, int32_t stream_id, knot_pkt_t *pkt,
+ uv_write_cb cb);
void http_free(struct http_ctx *ctx);
mp_flush(the_worker->pkt_pool.ctx);
}
-static ssize_t tls_send(const uint8_t *buffer, const size_t buffer_len, void *user_ctx)
+static ssize_t tls_send(const uint8_t *buf, const size_t len, struct session *session)
{
- struct tls_ctx *ctx = user_ctx;
- ssize_t len = 0;
- if ((len = gnutls_record_send(ctx->c.tls_session, buffer, buffer_len)) < 0) {
+ struct tls_ctx *ctx = session_tls_get_server_ctx(session);
+ ssize_t sent = 0;
+ assert(ctx);
+
+ sent = gnutls_record_send(ctx->c.tls_session, buf, len);
+ if (sent < 0) {
return kr_error(EIO);
}
- return len;
+ return sent;
}
static void _tcp_accept(uv_stream_t *master, int status, bool tls, bool http)
session_close(s);
return;
}
- ctx = http_new(tls_send, (void*)session_tls_get_server_ctx(s));
+ ctx = http_new(s, tls_send);
if (!ctx) {
session_close(s);
return;