static void on_dispose(void *_ctx) { struct st_h2o_mruby_http_request_context_t *ctx = _ctx; /* clear the refs */ if (ctx->client != NULL) { h2o_http1client_cancel(ctx->client); ctx->client = NULL; } if (!mrb_nil_p(ctx->refs.request)) DATA_PTR(ctx->refs.request) = NULL; if (!mrb_nil_p(ctx->refs.input_stream)) DATA_PTR(ctx->refs.input_stream) = NULL; /* clear bufs */ h2o_buffer_dispose(&ctx->req.buf); h2o_buffer_dispose(&ctx->resp.after_closed); /* notify the app, if it is waiting to hear from us */ if (!mrb_nil_p(ctx->receiver)) { mrb_state *mrb = ctx->generator->ctx->mrb; int gc_arena = mrb_gc_arena_save(mrb); h2o_mruby_run_fiber(ctx->generator, detach_receiver(ctx), create_downstream_closed_exception(mrb), gc_arena, NULL); } }
static void on_generator_dispose(void *_self) { struct rp_generator_t *self = _self; assert(self->client == NULL); h2o_buffer_dispose(&self->last_content_before_send); h2o_buffer_dispose(&self->buf_sending); }
void h2o_http2_stream_close(h2o_http2_conn_t *conn, h2o_http2_stream_t *stream) { h2o_http2_conn_unregister_stream(conn, stream); h2o_buffer_dispose(&stream->_req_body); h2o_dispose_request(&stream->req); if (stream->stream_id == 1 && conn->_http1_req_input != NULL) h2o_buffer_dispose(&conn->_http1_req_input); free(stream); }
static void requests_status_per_thread(void *priv, h2o_context_t *ctx) { struct st_requests_status_ctx_t *rsc = priv; struct st_collect_req_status_cbdata_t cbdata = {rsc->logconf}; /* we encountered an error at init() time, return early */ if (rsc->logconf == NULL) return; h2o_buffer_init(&cbdata.buffer, &h2o_socket_buffer_prototype); ctx->globalconf->http1.callbacks.foreach_request(ctx, collect_req_status, &cbdata); ctx->globalconf->http2.callbacks.foreach_request(ctx, collect_req_status, &cbdata); /* concat JSON elements */ if (cbdata.buffer->size != 0) { #ifndef _MSC_VER pthread_mutex_lock(&rsc->mutex); #else uv_mutex_lock(&rsc->mutex); #endif if (rsc->req_data.len == 0) h2o_buffer_consume(&cbdata.buffer, 1); /* skip preceeding comma */ rsc->req_data.base = h2o_mem_realloc(rsc->req_data.base, rsc->req_data.len + cbdata.buffer->size); memcpy(rsc->req_data.base + rsc->req_data.len, cbdata.buffer->bytes, cbdata.buffer->size); rsc->req_data.len += cbdata.buffer->size; #ifndef _MSC_VER pthread_mutex_unlock(&rsc->mutex); #else uv_mutex_unlock(&rsc->mutex); #endif } h2o_buffer_dispose(&cbdata.buffer); }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { SSL_free(ssl->ssl); h2o_buffer_dispose(&ssl->input.encrypted); h2o_mem_clear_pool(&ssl->output.pool); free(ssl); }
int h2o_read_command(const char *cmd, char **argv, h2o_buffer_t **resp, int *child_status) { int respfds[2] = {-1, -1}; pid_t pid = -1; int mutex_locked = 0, ret = -1; h2o_buffer_init(resp, &h2o_socket_buffer_prototype); pthread_mutex_lock(&cloexec_mutex); mutex_locked = 1; /* create pipe for reading the result */ if (pipe(respfds) != 0) goto Exit; fcntl(respfds[0], F_SETFD, O_CLOEXEC); /* spawn */ int mapped_fds[] = {respfds[1], 1, /* stdout of the child process is read from the pipe */ -1}; if ((pid = h2o_spawnp(cmd, argv, mapped_fds, 1)) == -1) goto Exit; close(respfds[1]); respfds[1] = -1; pthread_mutex_unlock(&cloexec_mutex); mutex_locked = 0; /* read the response from pipe */ while (1) { h2o_iovec_t buf = h2o_buffer_reserve(resp, 8192); ssize_t r; while ((r = read(respfds[0], buf.base, buf.len)) == -1 && errno == EINTR) ; if (r <= 0) break; (*resp)->size += r; } Exit: if (mutex_locked) pthread_mutex_unlock(&cloexec_mutex); if (pid != -1) { /* wait for the child to complete */ pid_t r; while ((r = waitpid(pid, child_status, 0)) == -1 && errno == EINTR) ; if (r == pid) { /* success */ ret = 0; } } if (respfds[0] != -1) close(respfds[0]); if (respfds[1] != -1) close(respfds[1]); if (ret != 0) h2o_buffer_dispose(resp); return ret; }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
void h2o_socket_dispose_export(h2o_socket_export_t *info) { assert(info->fd != -1); if (info->ssl != NULL) destroy_ssl(info->ssl); h2o_buffer_dispose(&info->input); close(info->fd); info->fd = -1; }
void h2o_mruby_send_chunked_dispose(h2o_mruby_generator_t *generator) { h2o_mruby_chunked_t *chunked = generator->chunked; h2o_doublebuffer_dispose(&chunked->sending); switch (chunked->type) { case H2O_MRUBY_CHUNKED_TYPE_CALLBACK: h2o_buffer_dispose(&chunked->callback.receiving); close_body_obj(generator); break; case H2O_MRUBY_CHUNKED_TYPE_SHORTCUT: /* note: no need to free reference from chunked->client, since it is disposed at the same moment */ if (chunked->shortcut.remaining != NULL) h2o_buffer_dispose(&chunked->shortcut.remaining); break; } }
static void close_client(struct st_h2o_http1client_t *client) { if (client->sock != NULL) { if (client->super.connpool != NULL && client->_do_keepalive) { /* we do not send pipelined requests, and thus can trash all the received input at the end of the request */ h2o_buffer_consume(&client->sock->input, client->sock->input->size); h2o_socketpool_return(client->super.connpool->socketpool, client->sock); } else { h2o_socket_close(client->sock); } } if (h2o_timer_is_linked(&client->super._timeout)) h2o_timer_unlink(&client->super._timeout); if (client->_body_buf != NULL) h2o_buffer_dispose(&client->_body_buf); if (client->_body_buf_in_flight != NULL) h2o_buffer_dispose(&client->_body_buf_in_flight); free(client); }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { if (!ssl->ssl->server) free(ssl->handshake.client.server_name); SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
int h2o_read_command(const char *cmd, char **argv, h2o_buffer_t **resp, int *child_status) { int respfds[2] = {-1, -1}; posix_spawn_file_actions_t file_actions; pid_t pid = -1; int ret = -1; extern char **environ; h2o_buffer_init(resp, &h2o_socket_buffer_prototype); /* create pipe for reading the result */ if (pipe(respfds) != 0) goto Exit; /* spawn */ posix_spawn_file_actions_init(&file_actions); posix_spawn_file_actions_adddup2(&file_actions, respfds[1], 1); if ((errno = posix_spawnp(&pid, cmd, &file_actions, NULL, argv, environ)) != 0) { pid = -1; goto Exit; } close(respfds[1]); respfds[1] = -1; /* read the response from pipe */ while (1) { h2o_iovec_t buf = h2o_buffer_reserve(resp, 8192); ssize_t r; while ((r = read(respfds[0], buf.base, buf.len)) == -1 && errno == EINTR) ; if (r <= 0) break; (*resp)->size += r; } Exit: if (pid != -1) { /* wait for the child to complete */ pid_t r; while ((r = waitpid(pid, child_status, 0)) == -1 && errno == EINTR) ; if (r == pid) { /* success */ ret = 0; } } if (respfds[0] != -1) close(respfds[0]); if (respfds[1] != -1) close(respfds[1]); if (ret != 0) h2o_buffer_dispose(resp); return ret; }
static void on_generator_dispose(void *_self) { struct rp_generator_t *self = _self; if (self->client != NULL) { h2o_http1client_cancel(self->client); self->client = NULL; } h2o_buffer_dispose(&self->last_content_before_send); h2o_doublebuffer_dispose(&self->sending); }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { if (!SSL_is_server(ssl->ssl)) { free(ssl->handshake.client.server_name); free(ssl->handshake.client.session_cache_key.base); } SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
static void check_flatten(h2o_hpack_header_table_t *header_table, h2o_res_t *res, const char *expected, size_t expected_len) { h2o_buffer_t *buf; h2o_http2_frame_t frame; h2o_buffer_init(&buf, &h2o_socket_buffer_prototype); h2o_hpack_flatten_headers(&buf, header_table, 1, H2O_HTTP2_SETTINGS_DEFAULT.max_frame_size, res, NULL, NULL); ok(h2o_http2_decode_frame(&frame, (uint8_t*)buf->bytes, buf->size, &H2O_HTTP2_SETTINGS_DEFAULT) > 0); ok(h2o_memis(frame.payload, frame.length, expected, expected_len)); h2o_buffer_dispose(&buf); }
static void dispose_socket(h2o_socket_t *sock, int status) { void (*close_cb)(void *data); void *close_cb_data; if (sock->ssl != NULL) destroy_ssl(sock->ssl); h2o_buffer_dispose(&sock->input); close_cb = sock->on_close.cb; close_cb_data = sock->on_close.data; do_dispose_socket(sock); if (close_cb != NULL) close_cb(close_cb_data); }
static void dispose_socket(h2o_socket_t *sock, int status) { void (*close_cb)(void *data); void *close_cb_data; if (sock->ssl != NULL) { destroy_ssl(sock->ssl); sock->ssl = NULL; } h2o_buffer_dispose(&sock->input); if (sock->_peername != NULL) { free(sock->_peername); sock->_peername = NULL; } close_cb = sock->on_close.cb; close_cb_data = sock->on_close.data; do_dispose_socket(sock); if (close_cb != NULL) close_cb(close_cb_data); }
int h2o_read_command(const char *cmd, char **argv, h2o_buffer_t **resp, int *child_status) { int respfds[2] = {-1, -1}; pid_t pid = -1; int mutex_locked = 0, ret = -1; h2o_buffer_init(resp, &h2o_socket_buffer_prototype); #ifndef _MSC_VER pthread_mutex_lock(&cloexec_mutex); mutex_locked = 1; #else uv_mutex_lock(&cloexec_mutex); mutex_locked = 1; #endif /* create pipe for reading the result */ #ifdef _MSC_VER if (_pipe(respfds, 4096, O_BINARY) == -1) //on fail //-- : Debug{ //printf("Pipe Failed \n"); goto Exit; #else if (pipe(respfds) != 0) //on fail goto Exit; #endif #ifndef _MSC_VER fcntl(respfds[0], F_SETFD, O_CLOEXEC); #endif /* spawn */ int mapped_fds[] = {respfds[1], 1, /* stdout of the child process is read from the pipe */ -1}; if ((pid = h2o_spawnp(cmd, argv, mapped_fds, 1)) == -1) goto Exit; close(respfds[1]); respfds[1] = -1; #ifndef _MSC_VER pthread_mutex_unlock(&cloexec_mutex); #else uv_mutex_unlock(&cloexec_mutex); #endif mutex_locked = 0; /* read the response from pipe */ while (1) { h2o_iovec_t buf = h2o_buffer_reserve(resp, 8192); ssize_t r; #ifndef _MSC_VER while ((r = read(respfds[0], buf.base, buf.len)) == -1 && errno == EINTR) ; #else while ((r = _read(respfds[0], buf.base, buf.len)) == -1 && errno == EINTR) ; #endif if (r <= 0) break; (*resp)->size += r; } Exit: if (mutex_locked) #ifndef _MSC_VER pthread_mutex_unlock(&cloexec_mutex); #else uv_mutex_unlock(&cloexec_mutex); #endif //Child _ waiting doesn't work same way in Windows so #ifndef _MSC_VER if (pid != -1) { /* wait for the child to complete */ pid_t r; while ((r = waitpid(pid, child_status, 0)) == -1 && errno == EINTR) ; if (r == pid) { /* success */ ret = 0; } } #else //If you can come up with a way to wait for a child to exist in Windows put here.s #endif #ifndef _MSC_VER if (respfds[0] != -1) close(respfds[0]); if (respfds[1] != -1) close(respfds[1]); #else if (respfds[0] != -1) _close(respfds[0]); if (respfds[1] != -1) _close(respfds[1]); #endif if (ret != 0) h2o_buffer_dispose(resp); return ret; }