Beispiel #1
0
static void push_one_path(h2o_mem_pool_t *pool, h2o_iovec_vector_t *paths_to_push, h2o_iovec_t *url,
                          h2o_iovec_t base_path, const h2o_url_scheme_t *input_scheme, h2o_iovec_t input_authority,
                          const h2o_url_scheme_t *base_scheme, h2o_iovec_t *base_authority)
{
    h2o_url_t parsed, resolved;

    /* check the authority, and extract absolute path */
    if (h2o_url_parse_relative(url->base, url->len, &parsed) != 0)
        return;

    /* fast-path for abspath form */
    if (base_scheme == NULL && parsed.scheme == NULL && parsed.authority.base == NULL && url->len != 0 && url->base[0] == '/') {
        h2o_vector_reserve(pool, paths_to_push, paths_to_push->size + 1);
        paths_to_push->entries[paths_to_push->size++] = h2o_strdup(pool, url->base, url->len);
        return;
    }

    /* check scheme and authority if given URL contains either of the two, or if base is specified */
    h2o_url_t base = {input_scheme, input_authority, {}, base_path, 65535};
    if (base_scheme != NULL) {
        base.scheme = base_scheme;
        base.authority = *base_authority;
    }
    h2o_url_resolve(pool, &base, &parsed, &resolved);
    if (input_scheme != resolved.scheme)
        return;
    if (!h2o_lcstris(input_authority.base, input_authority.len, resolved.authority.base, resolved.authority.len))
        return;

    h2o_vector_reserve(pool, paths_to_push, paths_to_push->size + 1);
    paths_to_push->entries[paths_to_push->size++] = resolved.path;
}
Beispiel #2
0
void h2o_duration_stats_register(h2o_globalconf_t *conf)
{
    int i, k;
    h2o_logger_t *logger;
    h2o_hostconf_t *hconf;

    durations_logger = logger = h2o_mem_alloc(sizeof(*logger));
    memset(logger, 0, sizeof(*logger));
    logger->_config_slot = conf->_num_config_slots++;
    logger->log_access = stat_access;
    logger->on_context_init = on_context_init;
    logger->on_context_dispose = on_context_dispose;

    for (k = 0; conf->hosts[k]; k++) {
        hconf = conf->hosts[k];
        for (i = 0; i < hconf->paths.size; i++) {
            int j;
            for (j = 0; j < hconf->paths.entries[i].handlers.size; j++) {
                h2o_pathconf_t *pathconf = &hconf->paths.entries[i];
                h2o_vector_reserve(NULL, &pathconf->loggers, pathconf->loggers.size + 1);
                pathconf->loggers.entries[pathconf->loggers.size++] = (void *)logger;
            }
        }
    }
}
Beispiel #3
0
void h2o_context_init_pathconf_context(h2o_context_t *ctx, h2o_pathconf_t *pathconf)
{
    /* add pathconf to the inited list (or return if already inited) */
    size_t i;
    for (i = 0; i != ctx->_pathconfs_inited.size; ++i)
        if (ctx->_pathconfs_inited.entries[i] == pathconf)
            return;
    h2o_vector_reserve(NULL, &ctx->_pathconfs_inited, ctx->_pathconfs_inited.size + 1);
    ctx->_pathconfs_inited.entries[ctx->_pathconfs_inited.size++] = pathconf;

#define DOIT(type, list)                                                                                                           \
    do {                                                                                                                           \
        size_t i;                                                                                                                  \
        for (i = 0; i != pathconf->list.size; ++i) {                                                                               \
            type *o = pathconf->list.entries[i];                                                                                   \
            if (o->on_context_init != NULL)                                                                                        \
                o->on_context_init(o, ctx);                                                                                        \
        }                                                                                                                          \
    } while (0)

    DOIT(h2o_handler_t, handlers);
    DOIT(h2o_filter_t, filters);
    DOIT(h2o_logger_t, loggers);

#undef DOIT
}
Beispiel #4
0
ssize_t h2o_server_starter_get_fds(int **_fds)
{
    const char *ports_env, *start, *end, *eq;
    size_t t;
    H2O_VECTOR(int)fds = {};

    if ((ports_env = getenv("SERVER_STARTER_PORT")) == NULL)
        return 0;
    if (ports_env[0] == '\0') {
        fprintf(stderr, "$SERVER_STARTER_PORT is empty\n");
        return -1;
    }

    /* ports_env example: 127.0.0.1:80=3;/tmp/sock=4 */
    for (start = ports_env; *start != '\0'; start = *end == ';' ? end + 1 : end) {
        if ((end = strchr(start, ';')) == NULL)
            end = start + strlen(start);
        if ((eq = memchr(start, '=', end - start)) == NULL) {
            fprintf(stderr, "invalid $SERVER_STARTER_PORT, an element without `=` in: %s\n", ports_env);
            return -1;
        }
        if ((t = h2o_strtosize(eq + 1, end - eq - 1)) == SIZE_MAX) {
            fprintf(stderr, "invalid file descriptor number in $SERVER_STARTER_PORT: %s\n", ports_env);
            return -1;
        }
        h2o_vector_reserve(NULL, (void *)&fds, sizeof(fds.entries[0]), fds.size + 1);
        fds.entries[fds.size++] = (int)t;
    }

    *_fds = fds.entries;
    return fds.size;
}
Beispiel #5
0
void h2o_config_setenv(h2o_envconf_t *envconf, const char *name, const char *value)
{
    size_t name_len = strlen(name), i;
    h2o_iovec_t *value_slot;

    /* remove from the list of unsets */
    for (i = 0; i != envconf->unsets.size; ++i) {
        if (h2o_memis(envconf->unsets.entries[i].base, envconf->unsets.entries[i].len, name, name_len)) {
            h2o_mem_release_shared(envconf->unsets.entries[i].base);
            h2o_vector_erase(&envconf->unsets, i);
            break;
        }
    }
    /* find the slot */
    for (i = 0; i != envconf->sets.size; i += 2) {
        if (h2o_memis(envconf->sets.entries[i].base, envconf->sets.entries[i].len, name, name_len)) {
            value_slot = envconf->sets.entries + i + 1;
            h2o_mem_release_shared(value_slot->base);
            goto SetValue;
        }
    }
    /* name not found in existing sets */
    h2o_vector_reserve(NULL, &envconf->sets, envconf->sets.size + 2);
    envconf->sets.entries[envconf->sets.size++] = h2o_strdup_shared(NULL, name, name_len);
    value_slot = envconf->sets.entries + envconf->sets.size++;
SetValue:
    *value_slot = h2o_strdup_shared(NULL, value, SIZE_MAX);
}
Beispiel #6
0
void finalostream_send(h2o_ostream_t *self, h2o_req_t *req, h2o_iovec_t *bufs, size_t bufcnt, int is_final)
{
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _ostr_final, self);
    h2o_http2_conn_t *conn = (h2o_http2_conn_t*)req->conn;

    assert(stream->_data.size == 0);

    /* send headers */
    switch (stream->state) {
    case H2O_HTTP2_STREAM_STATE_SEND_HEADERS:
        send_headers(conn, stream);
        /* fallthru */
    case H2O_HTTP2_STREAM_STATE_SEND_BODY:
        if (is_final)
            stream->state = H2O_HTTP2_STREAM_STATE_END_STREAM;
        break;
    case H2O_HTTP2_STREAM_STATE_END_STREAM:
        /* might get set by h2o_http2_stream_reset */
        return;
    default:
        assert(!"cannot be in a receiving state");
    }

    /* save the contents in queue */
    if (bufcnt != 0) {
        h2o_vector_reserve(&req->pool, (h2o_vector_t*)&stream->_data, sizeof(h2o_iovec_t), bufcnt);
        memcpy(stream->_data.entries, bufs, sizeof(h2o_iovec_t) * bufcnt);
        stream->_data.size = bufcnt;
    }

    h2o_http2_conn_register_for_proceed_callback(conn, stream);
}
Beispiel #7
0
static void load_digest(h2o_cache_digests_t **digests, const char *gcs_base64, size_t gcs_base64_len, int with_validators,
                        int complete)
{
    h2o_cache_digests_frame_t frame = {};
    h2o_iovec_t gcs_bin;
    struct st_golombset_decode_t ctx = {};
    uint64_t nbits, pbits;

    /* decode base64 */
    if ((gcs_bin = h2o_decode_base64url(NULL, gcs_base64, gcs_base64_len)).base == NULL)
        goto Exit;

    /* prepare GCS context */
    ctx.src = (void *)(gcs_bin.base - 1);
    ctx.src_max = (void *)(gcs_bin.base + gcs_bin.len);
    ctx.src_shift = 0;

    /* decode nbits and pbits */
    if (golombset_decode_bits(&ctx, 5, &nbits) != 0 || golombset_decode_bits(&ctx, 5, &pbits) != 0)
        goto Exit;
    frame.capacity_bits = (unsigned)(nbits + pbits);

    /* decode the values */
    uint64_t value = UINT64_MAX, decoded;
    while (golombset_decode_value(&ctx, (unsigned)pbits, &decoded) == 0) {
        value += decoded + 1;
        if (value >= (uint64_t) 1 << frame.capacity_bits)
            goto Exit;
        h2o_vector_reserve(NULL, &frame.keys, frame.keys.size + 1);
        frame.keys.entries[frame.keys.size++] = value;
    }

    /* store the result */
    if (*digests == NULL) {
        *digests = h2o_mem_alloc(sizeof(**digests));
        **digests = (h2o_cache_digests_t){};
    }
    h2o_cache_digests_frame_vector_t *target = with_validators ? &(*digests)->fresh.url_and_etag : &(*digests)->fresh.url_only;
    h2o_vector_reserve(NULL, target, target->size + 1);
    target->entries[target->size++] = frame;
    frame = (h2o_cache_digests_frame_t){};
    (*digests)->fresh.complete = complete;

Exit:
    free(frame.keys.entries);
    free(gcs_bin.base);
}
Beispiel #8
0
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node)
{
    struct headers_configurator_t *self = (void *)_self;

    h2o_vector_reserve(NULL, (h2o_vector_t *)&self->cmds[1], sizeof(self->cmds[0].entries[0]), self->cmds[0].size);
    memcpy(self->cmds[1].entries, self->cmds[0].entries, sizeof(self->cmds->entries[0]) * self->cmds->size);
    self->cmds[1].size = self->cmds[0].size;
    ++self->cmds;
    return 0;
}
Beispiel #9
0
void h2o_config_register_status_handler(h2o_globalconf_t *config, h2o_status_handler_t *status_handler)
{
    /* check if the status handler is already registered */
    size_t i;
    for (i = 0; i != config->statuses.size; ++i)
        if (config->statuses.entries[i] == status_handler)
            return;
    /* register the new handler */
    h2o_vector_reserve(NULL, &config->statuses, config->statuses.size + 1);
    config->statuses.entries[config->statuses.size++] = status_handler;
}
Beispiel #10
0
h2o_pathconf_t *h2o_config_register_path(h2o_hostconf_t *hostconf, const char *pathname)
{
    h2o_pathconf_t *pathconf;

    h2o_vector_reserve(NULL, &hostconf->paths, hostconf->paths.size + 1);
    pathconf = hostconf->paths.entries + hostconf->paths.size++;

    h2o_config_init_pathconf(pathconf, hostconf->global, pathname, hostconf->mimemap);

    return pathconf;
}
Beispiel #11
0
Datei: config.c Projekt: ifzz/h2o
h2o_handler_t *h2o_create_handler(h2o_pathconf_t *conf, size_t sz)
{
    h2o_handler_t *handler = h2o_mem_alloc(sz);

    memset(handler, 0, sz);
    handler->_config_slot = conf->global->_num_config_slots++;

    h2o_vector_reserve(NULL, (void *)&conf->handlers, sizeof(conf->handlers.entries[0]), conf->handlers.size + 1);
    conf->handlers.entries[conf->handlers.size++] = handler;

    return handler;
}
Beispiel #12
0
void h2o_configurator_define_command(h2o_configurator_t *configurator, const char *name, int flags, h2o_configurator_command_cb cb)
{
    h2o_configurator_command_t *cmd;

    h2o_vector_reserve(NULL, (void *)&configurator->commands, sizeof(configurator->commands.entries[0]),
                       configurator->commands.size + 1);
    cmd = configurator->commands.entries + configurator->commands.size++;
    cmd->configurator = configurator;
    cmd->flags = flags;
    cmd->name = name;
    cmd->cb = cb;
}
Beispiel #13
0
void h2o_config_unsetenv(h2o_envconf_t *envconf, const char *name)
{
    size_t i, name_len = strlen(name);

    /* do nothing if already set */
    for (i = 0; i != envconf->unsets.size; ++i)
        if (h2o_memis(envconf->unsets.entries[i].base, envconf->unsets.entries[i].len, name, name_len))
            return;
    /* register */
    h2o_vector_reserve(NULL, &envconf->unsets, envconf->unsets.size + 1);
    envconf->unsets.entries[envconf->unsets.size++] = h2o_strdup_shared(NULL, name, name_len);
}
Beispiel #14
0
h2o_logger_t *h2o_create_logger(h2o_pathconf_t *conf, size_t sz)
{
    h2o_logger_t *logger = h2o_mem_alloc(sz);

    memset(logger, 0, sz);
    logger->_config_slot = conf->global->_num_config_slots++;

    h2o_vector_reserve(NULL, &conf->loggers, conf->loggers.size + 1);
    conf->loggers.entries[conf->loggers.size++] = logger;

    return logger;
}
Beispiel #15
0
static h2o_header_t *add_header(h2o_mempool_t *pool, h2o_headers_t *headers, h2o_buf_t *name, const char *value, size_t value_len)
{
    h2o_header_t *slot;

    h2o_vector_reserve(pool, (h2o_vector_t*)headers, sizeof(h2o_header_t), headers->size + 1);
    slot = headers->entries + headers->size++;

    slot->name = name;
    slot->value.base = (char*)value;
    slot->value.len = value_len;

    return slot;
}
Beispiel #16
0
static ssize_t init_headers(h2o_mem_pool_t *pool, h2o_headers_t *headers, const struct phr_header *src, size_t len,
                            h2o_iovec_t *connection, h2o_iovec_t *host, h2o_iovec_t *upgrade, h2o_iovec_t *expect)
{
    ssize_t entity_header_index = -1;

    assert(headers->size == 0);

    /* setup */
    if (len != 0) {
        size_t i;
        h2o_vector_reserve(pool, headers, len);
        for (i = 0; i != len; ++i) {
            const h2o_token_t *name_token;
            char orig_case[src[i].name_len];

            /* preserve the original case */
            memcpy(orig_case, src[i].name, src[i].name_len);
            /* convert to lower-case in-place */
            h2o_strtolower((char *)src[i].name, src[i].name_len);
            if ((name_token = h2o_lookup_token(src[i].name, src[i].name_len)) != NULL) {
                if (name_token->is_init_header_special) {
                    if (name_token == H2O_TOKEN_HOST) {
                        host->base = (char *)src[i].value;
                        host->len = src[i].value_len;
                    } else if (name_token == H2O_TOKEN_CONTENT_LENGTH) {
                        if (entity_header_index == -1)
                            entity_header_index = i;
                    } else if (name_token == H2O_TOKEN_TRANSFER_ENCODING) {
                        entity_header_index = i;
                    } else if (name_token == H2O_TOKEN_EXPECT) {
                        expect->base = (char *)src[i].value;
                        expect->len = src[i].value_len;
                    } else if (name_token == H2O_TOKEN_UPGRADE) {
                        upgrade->base = (char *)src[i].value;
                        upgrade->len = src[i].value_len;
                    } else {
                        assert(!"logic flaw");
                    }
                } else {
                    h2o_add_header(pool, headers, name_token, orig_case, src[i].value, src[i].value_len);
                    if (name_token == H2O_TOKEN_CONNECTION)
                        *connection = headers->entries[headers->size - 1].value;
                }
            } else {
                h2o_add_header_by_str(pool, headers, src[i].name, src[i].name_len, 0, orig_case, src[i].value, src[i].value_len);
            }
        }
    }

    return entity_header_index;
}
Beispiel #17
0
h2o_filter_t *h2o_create_filter(h2o_pathconf_t *conf, size_t sz)
{
    h2o_filter_t *filter = h2o_mem_alloc(sz);

    memset(filter, 0, sz);
    filter->_config_slot = conf->global->_num_config_slots++;

    h2o_vector_reserve(NULL, &conf->filters, conf->filters.size + 1);
    memmove(conf->filters.entries + 1, conf->filters.entries, conf->filters.size * sizeof(conf->filters.entries[0]));
    conf->filters.entries[0] = filter;
    ++conf->filters.size;

    return filter;
}
Beispiel #18
0
static ssize_t add_header(h2o_mem_pool_t *pool, h2o_headers_t *headers, h2o_iovec_t *name, const char *orig_name, const char *value,
                          size_t value_len, h2o_header_flags_t flags)
{
    h2o_header_t *slot;

    h2o_vector_reserve(pool, headers, headers->size + 1);
    slot = headers->entries + headers->size++;

    slot->name = name;
    slot->value.base = (char *)value;
    slot->value.len = value_len;
    slot->orig_name = orig_name ? h2o_strdup(pool, orig_name, name->len).base : NULL;
    slot->flags = flags;
    return headers->size - 1;
}
Beispiel #19
0
static int on_config_exit(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node)
{
    struct headers_configurator_t *self = (void *)_self;

    if (ctx->pathconf != NULL && self->cmds->size != 0) {
        h2o_vector_reserve(NULL, (h2o_vector_t *)self->cmds, sizeof(self->cmds->entries[0]), sizeof(self->cmds->size));
        self->cmds->entries[self->cmds->size] = (h2o_headers_command_t){H2O_HEADERS_CMD_NULL};
        h2o_headers_register(ctx->pathconf, self->cmds->entries);
    } else {
        free(self->cmds->entries);
        memset(self->cmds, 0, sizeof(*self->cmds));
    }

    --self->cmds;
    return 0;
}
Beispiel #20
0
static int write_bio(BIO *b, const char *in, int len)
{
    h2o_socket_t *sock = b->ptr;
    void *bytes_alloced;

    if (len == 0)
        return 0;

    bytes_alloced = h2o_mempool_alloc(&sock->ssl->output.pool, len);
    memcpy(bytes_alloced, in, len);

    h2o_vector_reserve(&sock->ssl->output.pool, (h2o_vector_t*)&sock->ssl->output.bufs, sizeof(h2o_buf_t), sock->ssl->output.bufs.size + 1);
    sock->ssl->output.bufs.entries[sock->ssl->output.bufs.size++] = h2o_buf_init(bytes_alloced, len);

    return len;
}
Beispiel #21
0
static int add_cmd(h2o_configurator_command_t *cmd, yoml_t *node, int cmd_id, h2o_iovec_t *name, h2o_iovec_t value)
{
    struct headers_configurator_t *self = (void *)cmd->configurator;

    if (h2o_iovec_is_token(name)) {
        const h2o_token_t *token = (void *)name;
        if (h2o_headers_is_prohibited_name(token)) {
            h2o_configurator_errprintf(cmd, node, "the named header cannot be rewritten");
            return -1;
        }
    }

    h2o_vector_reserve(NULL, (h2o_vector_t *)self->cmds, sizeof(self->cmds->entries[0]), self->cmds->size + 1);
    self->cmds->entries[self->cmds->size++] = (h2o_headers_command_t){cmd_id, name, value};
    return 0;
}
Beispiel #22
0
static int on_config(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, const char *file, yoml_t *node)
{
    struct st_h2o_access_log_configurator_t *self = (void*)cmd->configurator;
    const char *path, *fmt = NULL;
    h2o_access_log_filehandle_t *fh;

    switch (node->type) {
    case  YOML_TYPE_SCALAR:
        path = node->data.scalar;
        break;
    case YOML_TYPE_MAPPING:
        {
            yoml_t *t;
            /* get path */
            if ((t = yoml_get(node, "path")) == NULL) {
                h2o_configurator_errprintf(cmd, file, node, "could not find mandatory key `path`");
                return -1;
            }
            if (t->type != YOML_TYPE_SCALAR) {
                h2o_configurator_errprintf(cmd, file, t, "`path` must be scalar");
                return -1;
            }
            path = t->data.scalar;
            /* get format */
            if ((t = yoml_get(node, "format")) != NULL) {
                if (t->type != YOML_TYPE_SCALAR) {
                    h2o_configurator_errprintf(cmd, file, t, "`format` must be a scalar");
                    return -1;
                }
                fmt = t->data.scalar;
            }
        }
        break;
    default:
        h2o_configurator_errprintf(cmd, file, node, "node must be a scalar or a mapping");
        return -1;
    }

    if ((fh = h2o_access_log_open_handle(path, fmt)) == NULL)
        return -1;

    h2o_vector_reserve(NULL, (h2o_vector_t*)self->handles, sizeof(self->handles->entries[0]), self->handles->size + 1);
    self->handles->entries[self->handles->size++] = fh;

    return 0;
}
Beispiel #23
0
static mrb_value h2o_mrb_push_http2_push_paths(mrb_state *mrb, mrb_value self)
{
    h2o_mruby_internal_context_t *mruby_ctx = (h2o_mruby_internal_context_t *)mrb->ud;
    char *s;
    mrb_int len;

    if (mruby_ctx->state != H2O_MRUBY_STATE_UNDETERMINED)
        mrb_raise(mrb, E_RUNTIME_ERROR, "response already sent");

    mrb_get_args(mrb, "s", &s, &len);

    h2o_vector_reserve(&mruby_ctx->req->pool, (void *)&mruby_ctx->req->http2_push_paths,
                       sizeof(mruby_ctx->req->http2_push_paths.entries[0]), mruby_ctx->req->http2_push_paths.size + 1);
    mruby_ctx->req->http2_push_paths.entries[mruby_ctx->req->http2_push_paths.size++] = h2o_strdup(&mruby_ctx->req->pool, s, len);

    return self;
}
Beispiel #24
0
static void common_init(h2o_socketpool_t *pool, h2o_socketpool_target_t **targets, size_t num_targets, size_t capacity,
                        h2o_balancer_t *balancer)
{
    memset(pool, 0, sizeof(*pool));

    pool->capacity = capacity;
    pool->timeout = 2000;

    pthread_mutex_init(&pool->_shared.mutex, NULL);
    h2o_linklist_init_anchor(&pool->_shared.sockets);

    h2o_vector_reserve(NULL, &pool->targets, num_targets);
    for (; pool->targets.size < num_targets; ++pool->targets.size)
        pool->targets.entries[pool->targets.size] = targets[pool->targets.size];

    pool->balancer = balancer;
}
Beispiel #25
0
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, const char *file, yoml_t *node)
{
    struct st_h2o_access_log_configurator_t *self = (void*)_self;
    size_t i;

    /* push the stack pointer */
    ++self->handles;

    /* link the handles */
    memset(self->handles, 0, sizeof(*self->handles));
    h2o_vector_reserve(NULL, (void*)self->handles, sizeof(self->handles->entries[0]), self->handles[-1].size + 1);
    for (i = 0; i != self->handles[-1].size; ++i) {
        h2o_access_log_filehandle_t *fh = self->handles[-1].entries[i];
        self->handles[0].entries[self->handles[0].size++] = fh;
        h2o_mem_addref_shared(fh);
    }

    return 0;
}
Beispiel #26
0
void finalostream_start_pull(h2o_ostream_t *self, h2o_ostream_pull_cb cb)
{
    h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _ostr_final, self);
    h2o_http2_conn_t *conn = (void*)stream->req.conn;

    assert(stream->req._ostr_top == &stream->_ostr_final);
    assert(stream->state == H2O_HTTP2_STREAM_STATE_SEND_HEADERS);

    /* register the pull callback */
    stream->_pull_cb = cb;

    /* send headers */
    send_headers(conn, stream);

    /* set dummy data in the send buffer */
    h2o_vector_reserve(&stream->req.pool, (h2o_vector_t*)&stream->_data, sizeof(h2o_iovec_t), 1);
    stream->_data.entries[0].base = "<pull interface>";
    stream->_data.entries[0].len = 1;
    stream->_data.size = 1;

    h2o_http2_conn_register_for_proceed_callback(conn, stream);
}
Beispiel #27
0
static int write_bio(BIO *b, const char *in, int len)
{
    h2o_socket_t *sock = b->ptr;
    void *bytes_alloced;

    /* FIXME no support for SSL renegotiation (yet) */
    if (sock->ssl->did_write_in_read != NULL) {
        *sock->ssl->did_write_in_read = 1;
        return -1;
    }

    if (len == 0)
        return 0;

    bytes_alloced = h2o_mem_alloc_pool(&sock->ssl->output.pool, len);
    memcpy(bytes_alloced, in, len);

    h2o_vector_reserve(&sock->ssl->output.pool, (h2o_vector_t*)&sock->ssl->output.bufs, sizeof(h2o_iovec_t), sock->ssl->output.bufs.size + 1);
    sock->ssl->output.bufs.entries[sock->ssl->output.bufs.size++] = h2o_iovec_init(bytes_alloced, len);

    return len;
}
Beispiel #28
0
void h2o_init_request(h2o_req_t *req, h2o_conn_t *conn, h2o_req_t *src)
{
    /* clear all memory (expect memory pool, since it is large) */
    memset(req, 0, offsetof(h2o_req_t, pool));

    /* init memory pool (before others, since it may be used) */
    h2o_mempool_init(&req->pool);

    /* init properties that should be initialized to non-zero */
    req->conn = conn;
    req->_timeout_entry.cb = deferred_proceed_cb;
    req->res.content_length = SIZE_MAX;

    if (src != NULL) {
#define COPY(buf) do { \
    req->buf.base = h2o_mempool_alloc(&req->pool, src->buf.len); \
    memcpy(req->buf.base, src->buf.base, src->buf.len); \
    req->buf.len = src->buf.len; \
} while (0)
        COPY(authority);
        COPY(method);
        COPY(path);
        COPY(scheme);
        req->version = src->version;
        h2o_vector_reserve(&req->pool, (h2o_vector_t*)&req->headers, sizeof(h2o_header_t), src->headers.size);
        memcpy(req->headers.entries, src->headers.entries, src->headers.size);
        req->headers.size = src->headers.size;
        req->entity = src->entity;
        req->http1_is_persistent = src->http1_is_persistent;
        if (src->upgrade.base != NULL) {
            COPY(upgrade);
        } else {
            req->upgrade.base = NULL;
            req->upgrade.len = 0;
        }
#undef COPY
    }
}
Beispiel #29
0
int h2o_http2_casper_lookup(h2o_http2_casper_t *casper, const char *path, size_t path_len, int set)
{
    unsigned key = calc_key(casper, path, path_len);
    size_t i;

    /* FIXME use binary search */
    for (i = 0; i != casper->keys.size; ++i)
        if (key <= casper->keys.entries[i])
            break;
    if (i != casper->keys.size && key == casper->keys.entries[i])
        return 1;
    if (!set)
        return 0;

    /* we need to set a new value */
    free(casper->cookie_cache.base);
    casper->cookie_cache = (h2o_iovec_t){NULL};
    h2o_vector_reserve(NULL, &casper->keys, casper->keys.size + 1);
    memmove(casper->keys.entries + i + 1, casper->keys.entries + i, (casper->keys.size - i) * sizeof(casper->keys.entries[0]));
    ++casper->keys.size;
    casper->keys.entries[i] = key;
    return 0;
}
Beispiel #30
0
ssize_t h2o_init_headers(h2o_mempool_t *pool, h2o_headers_t *headers, const struct phr_header *src, size_t len, h2o_buf_t *connection, h2o_buf_t *host, h2o_buf_t *upgrade)
{
    ssize_t entity_header_index = -1;

    assert(headers->size == 0);

    /* setup */
    if (len != 0) {
        size_t i;
        h2o_vector_reserve(pool, (h2o_vector_t*)headers, sizeof(h2o_header_t), len);
        for (i = 0; i != len; ++i) {
            const h2o_token_t *name_token = h2o_lookup_token(src[i].name, src[i].name_len);
            if (name_token != NULL) {
                if (name_token == H2O_TOKEN_HOST) {
                    host->base = (char*)src[i].value;
                    host->len = src[i].value_len;
                } else if (name_token == H2O_TOKEN_UPGRADE) {
                    upgrade->base = (char*)src[i].value;
                    upgrade->len = src[i].value_len;
                } else if (name_token == H2O_TOKEN_CONTENT_LENGTH) {
                    if (entity_header_index == -1)
                        entity_header_index = i;
                } else if (name_token == H2O_TOKEN_TRANSFER_ENCODING) {
                    entity_header_index = i;
                } else {
                    h2o_header_t *added = add_header(pool, headers, (h2o_buf_t*)name_token, src[i].value, src[i].value_len);
                    if (name_token == H2O_TOKEN_CONNECTION)
                        *connection = added->value;
                }
            } else {
                h2o_add_header_by_str(pool, headers, src[i].name, src[i].name_len, 0, src[i].value, src[i].value_len);
            }
        }
    }

    return entity_header_index;
}