Beispiel #1
0
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);
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
    }
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
}
Beispiel #15
0
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);
}
Beispiel #16
0
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);
}
Beispiel #17
0
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);
}
Beispiel #18
0
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;
}