static void on_read_proxy_line(h2o_socket_t *sock, const char *err) { struct st_h2o_accept_data_t *data = sock->data; if (err != NULL) { free_accept_data(data); h2o_socket_close(sock); return; } struct sockaddr_storage addr; socklen_t addrlen; ssize_t r = parse_proxy_line(sock->input->bytes, sock->input->size, (void *)&addr, &addrlen); switch (r) { case -1: /* error, just pass the input to the next handler */ break; case -2: /* incomplete */ return; default: h2o_buffer_consume(&sock->input, r); if (addrlen != 0) h2o_socket_setpeername(sock, (void *)&addr, addrlen); break; } if (data->ctx->ssl_ctx != NULL) { h2o_socket_ssl_handshake(sock, data->ctx->ssl_ctx, NULL, on_ssl_handshake_complete); } else { struct st_h2o_accept_data_t *data = sock->data; sock->data = NULL; h2o_http1_accept(data->ctx, sock, data->connected_at); free_accept_data(data); } }
static void on_connect(h2o_socket_t *sock, const char *err) { h2o_socketpool_connect_request_t *req = sock->data; const char *errstr = NULL; assert(req->sock == sock); if (err != NULL) { __sync_sub_and_fetch(&req->pool->targets.entries[req->selected_target]->_shared.leased_count, 1); h2o_socket_close(sock); if (req->remaining_try_count == 0) { req->sock = NULL; errstr = "connection failed"; /* shouldn't we return err? */ } else { try_connect(req); return; } } else { h2o_url_t *target_url = &req->pool->targets.entries[req->selected_target]->url; if (target_url->scheme->is_ssl) { assert(req->pool->_ssl_ctx != NULL && "h2o_socketpool_set_ssl_ctx must be called for a pool that contains SSL target"); h2o_socket_ssl_handshake(sock, req->pool->_ssl_ctx, target_url->host.base, on_handshake_complete); return; } } call_connect_cb(req, errstr); }
void h2o_accept(h2o_accept_ctx_t *ctx, h2o_socket_t *sock) { struct timeval connected_at = *h2o_get_timestamp(ctx->ctx, NULL, NULL); if (ctx->expect_proxy_line || ctx->ssl_ctx != NULL) { create_accept_data(ctx, sock, connected_at); if (ctx->expect_proxy_line) { h2o_socket_read_start(sock, on_read_proxy_line); } else { h2o_socket_ssl_handshake(sock, ctx->ssl_ctx, NULL, on_ssl_handshake_complete); } } else { h2o_http1_accept(ctx, sock, connected_at); } }