start refactoring isc_nm_httprequest() into read/send
the goal here is to have the interface to http sockets be the same as other types of netmgr socket, so that (for example) dig can open an http connection and then just work with no further code change, the same as it does with tcpdns or tlsdns. but the supporting code for https seems to be written with the assumption that there will be a tight connection between a request and a response, so the send and read functions have been compressed into a single 'httprequest' function call. in an effort to make the normal send and read semantics work correctly, we're trying to set it up so that read sets us up to listen for a response, send sets up the query we're sending, and whichever one comes second triggers the transaction. currently this is working in doh_test, but dig is failing due to a deadlock; isc_http_connect() needs to return so launch_next_query() can unlock the lookup before tcp_connected() runs.
This commit is contained in:
@@ -41,10 +41,12 @@ typedef struct isc_nm_http_response_status {
|
||||
typedef struct http_cstream {
|
||||
isc_nm_recv_cb_t read_cb;
|
||||
void *read_cbarg;
|
||||
|
||||
isc_nm_cb_t connect_cb;
|
||||
void *connect_cbarg;
|
||||
|
||||
bool sending;
|
||||
bool reading;
|
||||
|
||||
char *uri;
|
||||
isc_url_parser_t up;
|
||||
|
||||
@@ -118,10 +120,13 @@ failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
||||
static void
|
||||
failed_read_cb(isc_result_t result, isc_nm_http_session_t *session);
|
||||
|
||||
static int
|
||||
static isc_result_t
|
||||
server_send_error_response(const isc_http_error_responses_t error,
|
||||
nghttp2_session *ngsession, isc_nmsocket_t *socket);
|
||||
|
||||
static isc_result_t
|
||||
client_send(isc_nmhandle_t *handle, const isc_region_t *region);
|
||||
|
||||
static bool
|
||||
inactive(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
|
||||
@@ -146,17 +151,17 @@ find_http_cstream(int32_t stream_id, isc_nm_http_session_t *session) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
get_http_cstream(isc_mem_t *mctx, http_cstream_t **streamp, const char *uri) {
|
||||
new_http_cstream(isc_nmsocket_t *sock, http_cstream_t **streamp) {
|
||||
isc_mem_t *mctx = sock->mgr->mctx;
|
||||
const char *uri = sock->h2.connect.uri;
|
||||
http_cstream_t *stream = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(streamp != NULL && *streamp == NULL);
|
||||
REQUIRE(uri != NULL);
|
||||
|
||||
stream = isc_mem_get(mctx, sizeof(http_cstream_t));
|
||||
*stream = (http_cstream_t){ .stream_id = -1, .rbufsize = 0 };
|
||||
|
||||
stream->uri = isc_mem_strdup(mctx, uri);
|
||||
*stream = (http_cstream_t){ .stream_id = -1,
|
||||
.post = sock->h2.connect.post,
|
||||
.uri = isc_mem_strdup(mctx, uri) };
|
||||
ISC_LINK_INIT(stream, link);
|
||||
|
||||
result = isc_url_parse(stream->uri, strlen(stream->uri), 0,
|
||||
&stream->up);
|
||||
@@ -207,11 +212,6 @@ get_http_cstream(isc_mem_t *mctx, http_cstream_t **streamp, const char *uri) {
|
||||
stream->up.field_data[ISC_UF_QUERY].len);
|
||||
}
|
||||
|
||||
stream->GET_path = NULL;
|
||||
stream->GET_path_len = 0;
|
||||
stream->postdata = (isc_region_t){ .base = NULL, .length = 0 };
|
||||
memset(&stream->response_status, 0, sizeof(stream->response_status));
|
||||
|
||||
*streamp = stream;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -652,7 +652,7 @@ http_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
|
||||
return;
|
||||
}
|
||||
|
||||
if (readlen < region->length) {
|
||||
if (readlen < (ssize_t)region->length) {
|
||||
INSIST(session->bufsize == 0);
|
||||
INSIST(region->length - readlen < MAX_DNS_MESSAGE_SIZE);
|
||||
memmove(session->buf, region->base, region->length - readlen);
|
||||
@@ -755,6 +755,27 @@ http_do_bio(isc_nm_http_session_t *session) {
|
||||
return;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
get_http_cstream(isc_nmsocket_t *sock, http_cstream_t **streamp) {
|
||||
http_cstream_t *cstream = sock->h2.connect.cstream;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(streamp != NULL && *streamp == NULL);
|
||||
|
||||
sock->h2.connect.cstream = NULL;
|
||||
|
||||
if (cstream == NULL) {
|
||||
result = new_http_cstream(sock, &cstream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(cstream == NULL);
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
*streamp = cstream;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
typedef struct http_connect_data {
|
||||
char *uri;
|
||||
isc_nm_cb_t connect_cb;
|
||||
@@ -769,13 +790,19 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
http_connect_data_t *pconn_data = (http_connect_data_t *)cbarg;
|
||||
http_connect_data_t conn_data = *pconn_data;
|
||||
isc_nm_http_session_t *session = NULL;
|
||||
http_cstream_t *cstream = NULL;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_mem_t *mctx = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(cbarg != NULL);
|
||||
|
||||
handle->sock->h2.session = NULL;
|
||||
mctx = handle->sock->mgr->mctx;
|
||||
sock = handle->sock;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
sock->h2.session = NULL;
|
||||
mctx = sock->mgr->mctx;
|
||||
|
||||
isc_mem_put(mctx, pconn_data, sizeof(*pconn_data));
|
||||
|
||||
@@ -795,8 +822,15 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
.client = true };
|
||||
isc_mem_attach(mctx, &session->mctx);
|
||||
|
||||
handle->sock->h2.connect.uri = conn_data.uri;
|
||||
handle->sock->h2.connect.post = conn_data.post;
|
||||
sock->h2.connect.uri = conn_data.uri;
|
||||
sock->h2.connect.post = conn_data.post;
|
||||
|
||||
result = get_http_cstream(sock, &cstream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
sock->h2.connect.cstream = cstream;
|
||||
|
||||
session->tlsctx = conn_data.tlsctx;
|
||||
conn_data.tlsctx = NULL;
|
||||
@@ -807,12 +841,9 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
||||
INSIST(sock->type == isc_nm_tlssocket);
|
||||
|
||||
isc_tls_get_http2_alpn(handle->sock->tlsstream.tls, &alpn,
|
||||
&alpnlen);
|
||||
isc_tls_get_http2_alpn(sock->tlsstream.tls, &alpn, &alpnlen);
|
||||
if (alpn == NULL || alpnlen != 2 ||
|
||||
memcmp(NGHTTP2_PROTO_VERSION_ID, alpn,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN) != 0)
|
||||
@@ -823,18 +854,18 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
}
|
||||
|
||||
isc_nmhandle_attach(handle, &session->handle);
|
||||
handle->sock->h2.session = session;
|
||||
sock->h2.session = session;
|
||||
|
||||
initialize_nghttp2_client_session(session);
|
||||
if (!send_client_connection_header(session)) {
|
||||
handle->sock->h2.session = NULL;
|
||||
sock->h2.session = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
conn_data.connect_cb(handle, ISC_R_SUCCESS, conn_data.connect_cbarg);
|
||||
if (ISC_LIST_EMPTY(session->cstreams)) {
|
||||
delete_http_session(session);
|
||||
isc__nmsocket_prep_destroy(handle->sock);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
} else {
|
||||
http_do_bio(session);
|
||||
}
|
||||
@@ -900,35 +931,21 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_httprequest(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_nm_recv_cb_t reply_cb, void *cbarg) {
|
||||
http_cstream_t *cstream = NULL;
|
||||
static isc_result_t
|
||||
client_send(isc_nmhandle_t *handle, const isc_region_t *region) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nm_http_session_t *session = NULL;
|
||||
isc_mem_t *mctx;
|
||||
isc_nmsocket_t *sock = handle->sock;
|
||||
isc_mem_t *mctx = sock->mgr->mctx;
|
||||
isc_nm_http_session_t *session = sock->h2.session;
|
||||
http_cstream_t *cstream = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
REQUIRE(handle->sock->tid == isc_nm_tid());
|
||||
REQUIRE(VALID_HTTP2_SESSION(handle->sock->h2.session));
|
||||
REQUIRE(session->client);
|
||||
REQUIRE(region != NULL);
|
||||
REQUIRE(region->base != NULL);
|
||||
REQUIRE(region->length != 0);
|
||||
REQUIRE(region->length <= MAX_DNS_MESSAGE_SIZE);
|
||||
REQUIRE(reply_cb != NULL);
|
||||
|
||||
session = handle->sock->h2.session;
|
||||
mctx = handle->sock->mgr->mctx;
|
||||
|
||||
result = get_http_cstream(mctx, &cstream, handle->sock->h2.connect.uri);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
cstream->read_cb = reply_cb;
|
||||
cstream->read_cbarg = cbarg;
|
||||
cstream->post = handle->sock->h2.connect.post;
|
||||
cstream = sock->h2.connect.cstream;
|
||||
|
||||
if (cstream->post) {
|
||||
/* POST */
|
||||
@@ -950,8 +967,8 @@ isc_nm_httprequest(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
|
||||
isc_buffer_allocate(mctx, &buf, base64_len);
|
||||
|
||||
if ((result = isc_base64_totext(&data, -1, "", buf)) !=
|
||||
ISC_R_SUCCESS) {
|
||||
result = isc_base64_totext(&data, -1, "", buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_buffer_free(&buf);
|
||||
goto error;
|
||||
}
|
||||
@@ -978,24 +995,50 @@ isc_nm_httprequest(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_mem_free(mctx, base64url_data);
|
||||
}
|
||||
|
||||
ISC_LINK_INIT(cstream, link);
|
||||
ISC_LIST_APPEND(session->cstreams, cstream, link);
|
||||
cstream->sending = true;
|
||||
if (cstream->reading) {
|
||||
sock->h2.connect.cstream = NULL;
|
||||
ISC_LIST_APPEND(session->cstreams, cstream, link);
|
||||
result = client_submit_request(session, cstream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ISC_LIST_UNLINK(session->cstreams, cstream, link);
|
||||
goto error;
|
||||
}
|
||||
|
||||
INSIST(cstream != NULL);
|
||||
http_do_bio(session);
|
||||
}
|
||||
|
||||
result = client_submit_request(session, cstream);
|
||||
error:
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_httprequest(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
http_cstream_t *cstream = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
REQUIRE(handle->sock->tid == isc_nm_tid());
|
||||
|
||||
REQUIRE(cb != NULL);
|
||||
|
||||
sock = handle->sock;
|
||||
|
||||
isc__nm_http_read(handle, cb, cbarg);
|
||||
client_send(handle, region);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ISC_LIST_UNLINK(session->cstreams, cstream, link);
|
||||
goto error;
|
||||
}
|
||||
http_do_bio(session);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
error:
|
||||
reply_cb(handle, result, NULL, cbarg);
|
||||
if (cstream != NULL) {
|
||||
put_http_cstream(mctx, cstream);
|
||||
sock->h2.connect.cstream = cstream;
|
||||
if (cstream->read_cb != NULL) {
|
||||
cstream->read_cb(handle, result, NULL, cstream->read_cbarg);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
@@ -1209,6 +1252,7 @@ server_on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
const uint8_t *name, size_t namelen,
|
||||
const uint8_t *value, size_t valuelen, uint8_t flags,
|
||||
void *user_data) {
|
||||
isc_result_t result;
|
||||
isc_nmsocket_t *socket = NULL;
|
||||
isc_http_error_responses_t code = ISC_HTTP_ERROR_SUCCESS;
|
||||
const char path[] = ":path";
|
||||
@@ -1260,9 +1304,11 @@ server_on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
}
|
||||
|
||||
INSIST(socket != NULL);
|
||||
if (server_send_error_response(code, session, socket) != 0) {
|
||||
result = server_send_error_response(code, session, socket);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (NGHTTP2_ERR_CALLBACK_FAILURE);
|
||||
};
|
||||
}
|
||||
|
||||
failed_httpstream_read_cb(socket, ISC_R_CANCELED, socket->h2.session);
|
||||
return (0);
|
||||
}
|
||||
@@ -1294,7 +1340,7 @@ server_read_callback(nghttp2_session *ngsession, int32_t stream_id,
|
||||
return (buflen);
|
||||
}
|
||||
|
||||
static int
|
||||
static isc_result_t
|
||||
server_send_response(nghttp2_session *ngsession, int32_t stream_id,
|
||||
const nghttp2_nv *nva, size_t nvlen,
|
||||
isc_nmsocket_t *socket) {
|
||||
@@ -1307,9 +1353,9 @@ server_send_response(nghttp2_session *ngsession, int32_t stream_id,
|
||||
rv = nghttp2_submit_response(ngsession, stream_id, nva, nvlen,
|
||||
&data_prd);
|
||||
if (rv != 0) {
|
||||
return (-1);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
return (0);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
#define MAKE_ERROR_REPLY(tag, code) \
|
||||
@@ -1331,11 +1377,9 @@ static struct http_error_responses {
|
||||
MAKE_ERROR_REPLY(ISC_HTTP_ERROR_GENERIC, 500),
|
||||
};
|
||||
|
||||
static int
|
||||
static isc_result_t
|
||||
server_send_error_response(const isc_http_error_responses_t error,
|
||||
nghttp2_session *ngsession, isc_nmsocket_t *socket) {
|
||||
int rv;
|
||||
|
||||
socket->h2.bufsize = 0;
|
||||
socket->h2.bufpos = 0;
|
||||
|
||||
@@ -1343,22 +1387,21 @@ server_send_error_response(const isc_http_error_responses_t error,
|
||||
i < sizeof(error_responses) / sizeof(error_responses[0]); i++)
|
||||
{
|
||||
if (error_responses[i].type == error) {
|
||||
rv = server_send_response(
|
||||
return (server_send_response(
|
||||
ngsession, socket->h2.stream_id,
|
||||
&error_responses[i].header,
|
||||
sizeof(error_responses[i].header), socket);
|
||||
return (rv);
|
||||
sizeof(error_responses[i].header), socket));
|
||||
}
|
||||
}
|
||||
|
||||
rv = server_send_error_response(ISC_HTTP_ERROR_GENERIC, ngsession,
|
||||
socket);
|
||||
return (rv);
|
||||
return (server_send_error_response(ISC_HTTP_ERROR_GENERIC, ngsession,
|
||||
socket));
|
||||
}
|
||||
|
||||
static int
|
||||
server_on_request_recv(nghttp2_session *ngsession,
|
||||
isc_nm_http_session_t *session, isc_nmsocket_t *socket) {
|
||||
isc_result_t result;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
isc_sockaddr_t addr;
|
||||
isc_http_error_responses_t code = ISC_HTTP_ERROR_SUCCESS;
|
||||
@@ -1437,7 +1480,8 @@ server_on_request_recv(nghttp2_session *ngsession,
|
||||
return (0);
|
||||
|
||||
error:
|
||||
if (server_send_error_response(code, ngsession, socket) != 0) {
|
||||
result = server_send_error_response(code, ngsession, socket);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (NGHTTP2_ERR_CALLBACK_FAILURE);
|
||||
}
|
||||
return (0);
|
||||
@@ -1446,24 +1490,16 @@ error:
|
||||
void
|
||||
isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
||||
isc_nm_cb_t cb, void *cbarg) {
|
||||
isc_nmsocket_t *sock = handle->sock;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc__netievent_httpsend_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(handle->httpsession != NULL);
|
||||
|
||||
sock = handle->sock;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
/* TODO: should be called from within the context of an NM thread? */
|
||||
if (inactive(sock) || handle->httpsession->closed) {
|
||||
cb(handle, ISC_R_CANCELED, cbarg);
|
||||
return;
|
||||
}
|
||||
|
||||
INSIST(VALID_NMHANDLE(handle->httpsession->handle));
|
||||
INSIST(VALID_NMSOCK(handle->httpsession->handle->sock));
|
||||
INSIST(sock->tid == handle->httpsession->handle->sock->tid);
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
isc_nmhandle_attach(handle, &uvreq->handle);
|
||||
uvreq->cb.send = cb;
|
||||
@@ -1477,6 +1513,19 @@ isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_result_t eresult) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
if (req->cb.send != NULL) {
|
||||
isc__nm_sendcb(sock, req, eresult);
|
||||
} else {
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
@@ -1484,6 +1533,7 @@ isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc_nmsocket_t *sock = ievent->sock;
|
||||
isc__nm_uvreq_t *req = ievent->req;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
isc_nm_http_session_t *session = NULL;
|
||||
isc_nm_cb_t cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
size_t len;
|
||||
@@ -1499,10 +1549,34 @@ isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
cbarg = req->cbarg;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
/* Client send */
|
||||
session = sock->h2.session;
|
||||
if (session != NULL && session->client) {
|
||||
result = client_send(
|
||||
handle,
|
||||
&(isc_region_t){ (uint8_t *)req->uvbuf.base,
|
||||
req->uvbuf.len });
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
failed_send_cb(sock, req, result);
|
||||
return;
|
||||
}
|
||||
|
||||
cb(handle, result, cbarg);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Server send */
|
||||
REQUIRE(VALID_NMHANDLE(handle->httpsession->handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->httpsession->handle->sock));
|
||||
REQUIRE(handle->httpsession->handle->sock->tid == isc_nm_tid());
|
||||
|
||||
if (inactive(sock) || handle->httpsession->closed) {
|
||||
failed_send_cb(sock, req, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(sock->h2.buf, req->uvbuf.base, req->uvbuf.len);
|
||||
sock->h2.bufsize = req->uvbuf.len;
|
||||
|
||||
@@ -1514,12 +1588,9 @@ isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
MAKE_NV("Content-Length", sock->h2.clenbuf, len)
|
||||
};
|
||||
|
||||
if (server_send_response(handle->httpsession->ngsession,
|
||||
sock->h2.stream_id, hdrs,
|
||||
sizeof(hdrs) / sizeof(nghttp2_nv), sock) != 0)
|
||||
{
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
result = server_send_response(handle->httpsession->ngsession,
|
||||
sock->h2.stream_id, hdrs,
|
||||
sizeof(hdrs) / sizeof(nghttp2_nv), sock);
|
||||
|
||||
http_do_bio(handle->httpsession);
|
||||
cb(handle, result, cbarg);
|
||||
@@ -1528,10 +1599,32 @@ isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
||||
void
|
||||
isc__nm_http_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
UNUSED(handle);
|
||||
UNUSED(cb);
|
||||
UNUSED(cbarg);
|
||||
return;
|
||||
isc_result_t result;
|
||||
http_cstream_t *cstream = NULL;
|
||||
|
||||
result = get_http_cstream(handle->sock, &cstream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
handle->sock->h2.connect.cstream = cstream;
|
||||
cstream->read_cb = cb;
|
||||
cstream->read_cbarg = cbarg;
|
||||
cstream->reading = true;
|
||||
|
||||
if (cstream->sending) {
|
||||
isc_nm_http_session_t *session = handle->sock->h2.session;
|
||||
|
||||
handle->sock->h2.connect.cstream = NULL;
|
||||
ISC_LIST_APPEND(session->cstreams, cstream, link);
|
||||
result = client_submit_request(session, cstream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ISC_LIST_UNLINK(session->cstreams, cstream, link);
|
||||
return;
|
||||
}
|
||||
|
||||
http_do_bio(session);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1783,8 +1876,8 @@ isc__nm_http_stoplistening(isc_nmsocket_t *sock) {
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_http_clear_handlers(isc_nmsocket_t *sock) {
|
||||
static void
|
||||
clear_handlers(isc_nmsocket_t *sock) {
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
isc_nm_httpcbarg_t *httpcbarg = NULL;
|
||||
|
||||
@@ -1814,8 +1907,8 @@ isc__nm_http_clear_handlers(isc_nmsocket_t *sock) {
|
||||
RWUNLOCK(&sock->h2.lock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_http_clear_session(isc_nmsocket_t *sock) {
|
||||
static void
|
||||
clear_session(isc_nmsocket_t *sock) {
|
||||
if (sock->type != isc_nm_httpsocket && sock->h2.session != NULL) {
|
||||
isc_nm_http_session_t *session = sock->h2.session;
|
||||
INSIST(ISC_LIST_EMPTY(session->sstreams));
|
||||
@@ -2114,6 +2207,57 @@ end:
|
||||
return (res);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_http_initsocket(isc_nmsocket_t *sock) {
|
||||
REQUIRE(sock != NULL);
|
||||
|
||||
sock->h2 = (isc_nmsocket_h2_t){
|
||||
.request_type = ISC_HTTP_REQ_UNSUPPORTED,
|
||||
.request_scheme = ISC_HTTP_SCHEME_UNSUPPORTED,
|
||||
};
|
||||
|
||||
if (sock->type == isc_nm_httplistener) {
|
||||
ISC_LIST_INIT(sock->h2.handlers);
|
||||
ISC_LIST_INIT(sock->h2.handler_cbargs);
|
||||
isc_rwlock_init(&sock->h2.lock, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_http_cleanup_data(isc_nmsocket_t *sock) {
|
||||
if (sock->type == isc_nm_httplistener) {
|
||||
clear_handlers(sock);
|
||||
isc_rwlock_destroy(&sock->h2.lock);
|
||||
}
|
||||
|
||||
if (sock->h2.request_path != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.request_path);
|
||||
sock->h2.request_path = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.query_data != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.query_data);
|
||||
sock->h2.query_data = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.connect.uri != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.connect.uri);
|
||||
sock->h2.connect.uri = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.connect.cstream != NULL) {
|
||||
put_http_cstream(sock->mgr->mctx, sock->h2.connect.cstream);
|
||||
sock->h2.connect.cstream = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.buf != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.buf);
|
||||
sock->h2.buf = NULL;
|
||||
}
|
||||
|
||||
clear_session(sock);
|
||||
}
|
||||
|
||||
/* DoH GET Query String Scanner-less Recursive Descent Parser/Verifier
|
||||
|
||||
It is based on the following grammar (using WSN/EBNF):
|
||||
|
||||
@@ -760,7 +760,7 @@ typedef struct isc_nmsocket_h2 {
|
||||
struct {
|
||||
char *uri;
|
||||
bool post;
|
||||
void *stream;
|
||||
void *cstream;
|
||||
} connect;
|
||||
} isc_nmsocket_h2_t;
|
||||
|
||||
@@ -1524,10 +1524,10 @@ void
|
||||
isc__nm_http_stoplistening(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_http_clear_handlers(isc_nmsocket_t *sock);
|
||||
isc__nm_http_initsocket(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_http_clear_session(isc_nmsocket_t *sock);
|
||||
isc__nm_http_cleanup_data(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
||||
|
||||
@@ -1008,33 +1008,7 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
|
||||
isc_condition_destroy(&sock->cond);
|
||||
isc_condition_destroy(&sock->scond);
|
||||
isc__nm_tls_cleanup_data(sock);
|
||||
|
||||
if (sock->type == isc_nm_httplistener) {
|
||||
isc__nm_http_clear_handlers(sock);
|
||||
isc_rwlock_destroy(&sock->h2.lock);
|
||||
}
|
||||
|
||||
if (sock->h2.request_path != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.request_path);
|
||||
sock->h2.request_path = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.query_data != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.query_data);
|
||||
sock->h2.query_data = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.connect.uri != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.connect.uri);
|
||||
sock->h2.query_data = NULL;
|
||||
}
|
||||
|
||||
if (sock->h2.buf != NULL) {
|
||||
isc_mem_free(sock->mgr->mctx, sock->h2.buf);
|
||||
sock->h2.buf = NULL;
|
||||
}
|
||||
|
||||
isc__nm_http_clear_session(sock);
|
||||
isc__nm_http_cleanup_data(sock);
|
||||
#ifdef NETMGR_TRACE
|
||||
LOCK(&sock->mgr->lock);
|
||||
ISC_LIST_UNLINK(sock->mgr->active_sockets, sock, active_link);
|
||||
@@ -1290,16 +1264,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
||||
|
||||
atomic_store(&sock->active_child_connections, 0);
|
||||
|
||||
sock->h2 = (isc_nmsocket_h2_t){
|
||||
.request_type = ISC_HTTP_REQ_UNSUPPORTED,
|
||||
.request_scheme = ISC_HTTP_SCHEME_UNSUPPORTED,
|
||||
};
|
||||
|
||||
if (type == isc_nm_httplistener) {
|
||||
ISC_LIST_INIT(sock->h2.handlers);
|
||||
ISC_LIST_INIT(sock->h2.handler_cbargs);
|
||||
isc_rwlock_init(&sock->h2.lock, 0, 1);
|
||||
}
|
||||
isc__nm_http_initsocket(sock);
|
||||
|
||||
sock->magic = NMSOCK_MAGIC;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user