#define HTTP_ENDPOINTS_MAGIC ISC_MAGIC('H', 'T', 'E', 'P')
#define VALID_HTTP_ENDPOINTS(t) ISC_MAGIC_VALID(t, HTTP_ENDPOINTS_MAGIC)
+#define HTTP_HANDLER_MAGIC ISC_MAGIC('H', 'T', 'H', 'L')
+#define VALID_HTTP_HANDLER(t) ISC_MAGIC_VALID(t, HTTP_HANDLER_MAGIC)
+
static bool
http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
isc_nm_cb_t cb, void *cbarg);
};
isc_buffer_initnull(&socket->h2->rbuf);
isc_buffer_initnull(&socket->h2->wbuf);
+ isc_nm_http_endpoints_attach(
+ http_get_listener_endpoints(session->serversocket, socket->tid),
+ &socket->h2->peer_endpoints);
session->nsstreams++;
isc__nm_httpsession_attach(session, &socket->h2->session);
ISC_LIST_APPEND(session->sstreams, socket->h2, link);
return (0);
}
-static isc_nm_httphandler_t *
-find_server_request_handler(const char *request_path,
- isc_nmsocket_t *serversocket, const int tid) {
- isc_nm_httphandler_t *handler = NULL;
-
- REQUIRE(VALID_NMSOCK(serversocket));
-
- handler = http_endpoints_find(
- request_path, http_get_listener_endpoints(serversocket, tid));
-
- return (handler);
-}
-
static isc_http_error_responses_t
server_handle_path_header(isc_nmsocket_t *socket, const uint8_t *value,
const size_t valuelen) {
return (ISC_HTTP_ERROR_BAD_REQUEST);
}
- handler = find_server_request_handler(socket->h2->request_path,
- socket->h2->session->serversocket,
- socket->tid);
+ handler = http_endpoints_find(socket->h2->request_path,
+ socket->h2->peer_endpoints);
if (handler != NULL) {
socket->h2->cb = handler->cb;
socket->h2->cbarg = handler->cbarg;
isc_nmhandle_t *handle = NULL;
REQUIRE(VALID_NMSOCK(socket));
- REQUIRE(socket->h2->cb != NULL);
+
+ /*
+ * In some cases the callback could not have been set (e.g. when
+ * the stream was closed prematurely (before processing its HTTP
+ * path).
+ */
+ if (socket->h2->cb == NULL) {
+ return;
+ }
handle = isc__nmhandle_get(socket, NULL, NULL);
+ if (result != ISC_R_SUCCESS) {
+ data = NULL;
+ }
socket->h2->cb(handle, result, data, socket->h2->cbarg);
isc_nmhandle_detach(&handle);
}
REQUIRE(VALID_NM(mgr));
REQUIRE(!ISC_LIST_EMPTY(eps->handlers));
- REQUIRE(!ISC_LIST_EMPTY(eps->handler_cbargs));
REQUIRE(atomic_load(&eps->in_use) == false);
REQUIRE(isc_tid() == 0);
*eps = (isc_nm_http_endpoints_t){ .mctx = NULL };
isc_mem_attach(mctx, &eps->mctx);
- ISC_LIST_INIT(eps->handler_cbargs);
ISC_LIST_INIT(eps->handlers);
isc_refcount_init(&eps->references, 1);
atomic_init(&eps->in_use, false);
isc_nm_http_endpoints_t *restrict eps;
isc_mem_t *mctx;
isc_nm_httphandler_t *handler = NULL;
- isc_nm_httpcbarg_t *httpcbarg = NULL;
REQUIRE(epsp != NULL);
eps = *epsp;
next = ISC_LIST_NEXT(handler, link);
ISC_LIST_DEQUEUE(eps->handlers, handler, link);
isc_mem_free(mctx, handler->path);
+ handler->magic = 0;
isc_mem_put(mctx, handler, sizeof(*handler));
handler = next;
}
- httpcbarg = ISC_LIST_HEAD(eps->handler_cbargs);
- while (httpcbarg != NULL) {
- isc_nm_httpcbarg_t *next = NULL;
-
- next = ISC_LIST_NEXT(httpcbarg, link);
- ISC_LIST_DEQUEUE(eps->handler_cbargs, httpcbarg, link);
- isc_mem_put(mctx, httpcbarg, sizeof(isc_nm_httpcbarg_t));
- httpcbarg = next;
- }
-
eps->magic = 0;
isc_mem_putanddetach(&mctx, eps, sizeof(*eps));
handler = ISC_LIST_NEXT(handler, link))
{
if (!strcmp(request_path, handler->path)) {
+ INSIST(VALID_HTTP_HANDLER(handler));
+ INSIST(handler->cb != NULL);
break;
}
}
return (handler);
}
-/*
- * In DoH we just need to intercept the request - the response can be sent
- * to the client code via the nmhandle directly as it's always just the
- * http content.
- */
-static void
-http_callback(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *data,
- void *arg) {
- isc_nm_httpcbarg_t *httpcbarg = arg;
-
- REQUIRE(VALID_NMHANDLE(handle));
-
- if (result != ISC_R_SUCCESS) {
- /* Shut down the client, then ourselves */
- httpcbarg->cb(handle, result, NULL, httpcbarg->cbarg);
- /* XXXWPK FREE */
- return;
- }
- httpcbarg->cb(handle, result, data, httpcbarg->cbarg);
-}
-
isc_result_t
isc_nm_http_endpoints_add(isc_nm_http_endpoints_t *restrict eps,
const char *uri, const isc_nm_recv_cb_t cb,
void *cbarg) {
isc_mem_t *mctx;
isc_nm_httphandler_t *restrict handler = NULL;
- isc_nm_httpcbarg_t *restrict httpcbarg = NULL;
- bool newhandler = false;
REQUIRE(VALID_HTTP_ENDPOINTS(eps));
REQUIRE(isc_nm_http_path_isvalid(uri));
+ REQUIRE(cb != NULL);
REQUIRE(atomic_load(&eps->in_use) == false);
mctx = eps->mctx;
- httpcbarg = isc_mem_get(mctx, sizeof(isc_nm_httpcbarg_t));
- *httpcbarg = (isc_nm_httpcbarg_t){ .cb = cb, .cbarg = cbarg };
- ISC_LINK_INIT(httpcbarg, link);
-
if (http_endpoints_find(uri, eps) == NULL) {
handler = isc_mem_get(mctx, sizeof(*handler));
- *handler = (isc_nm_httphandler_t){ .cb = http_callback,
- .cbarg = httpcbarg,
- .path = isc_mem_strdup(
- mctx, uri) };
- ISC_LINK_INIT(handler, link);
-
- newhandler = true;
- }
+ *handler = (isc_nm_httphandler_t){
+ .cb = cb,
+ .cbarg = cbarg,
+ .path = isc_mem_strdup(mctx, uri),
+ .link = ISC_LINK_INITIALIZER,
+ .magic = HTTP_HANDLER_MAGIC
+ };
- if (newhandler) {
ISC_LIST_APPEND(eps->handlers, handler, link);
}
- ISC_LIST_APPEND(eps->handler_cbargs, httpcbarg, link);
+
return (ISC_R_SUCCESS);
}
return;
}
- INSIST(sock->h2->cbarg != NULL);
-
(void)nghttp2_submit_rst_stream(
session->ngsession, NGHTTP2_FLAG_END_STREAM,
sock->h2->stream_id, NGHTTP2_REFUSED_STREAM);
http_cleanup_listener_endpoints(sock);
}
+ if (sock->type == isc_nm_httpsocket &&
+ sock->h2->peer_endpoints != NULL)
+ {
+ isc_nm_http_endpoints_detach(&sock->h2->peer_endpoints);
+ }
+
if (sock->h2->request_path != NULL) {
isc_mem_free(sock->worker->mctx,
sock->h2->request_path);