コード例 #1
0
ファイル: config.c プロジェクト: Gwill/h2o
static int on_config_virtual_host(h2o_configurator_t *configurator, void *_config, const char *file, yoml_t *node)
{
    h2o_global_configuration_t *config = _config;
    size_t i;

    if (node->type != YOML_TYPE_MAPPING) {
        h2o_config_print_error(configurator, file, node, "argument must be a mapping");
        return -1;
    }

    for (i = 0; i != node->data.mapping.size; ++i) {
        yoml_t *key = node->data.mapping.elements[i].key;
        yoml_t *value = node->data.mapping.elements[i].value;
        h2o_host_configuration_t *host_config;
        if (key->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(configurator, file, key, "key (representing the hostname) must be a string");
            return -1;
        }
        host_config = h2o_config_register_virtual_host(config, key->data.scalar);
        if (apply_commands(host_config, file, value, config) != 0)
            return -1;
    }

    return 0;
}
コード例 #2
0
ファイル: config.c プロジェクト: Gwill/h2o
static int on_config_mime_types(h2o_configurator_t *configurator, void *_config, const char *file, yoml_t *node)
{
    h2o_host_configuration_t *host_config = _config;
    size_t i;

    if (node->type != YOML_TYPE_MAPPING) {
        h2o_config_print_error(configurator, file, node, "argument must be a mapping");
        return -1;
    }

    for (i = 0; i != node->data.mapping.size; ++i) {
        yoml_t *key = node->data.mapping.elements[i].key;
        yoml_t *value = node->data.mapping.elements[i].value;
        if (key->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(configurator, file, key, "key (representing the extension) must be a string");
            return -1;
        }
        if (value->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(configurator, file, node, "value (representing the mime-type) must be a string");
            return -1;
        }
        h2o_define_mimetype(&host_config->mimemap, key->data.scalar, value->data.scalar);
    }

    return 0;
}
コード例 #3
0
ファイル: config.c プロジェクト: Gwill/h2o
static int on_config_files(h2o_configurator_t *configurator, void *_config, const char *file, yoml_t *node)
{
    h2o_host_configuration_t *host_config = _config;
    size_t i;

    if (node->type != YOML_TYPE_MAPPING) {
        h2o_config_print_error(configurator, file, node, "argument must be a mapping");
        return -1;
    }

    for (i = 0; i != node->data.mapping.size; ++i) {
        yoml_t *key = node->data.mapping.elements[i].key;
        yoml_t *value = node->data.mapping.elements[i].value;
        if (key->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(configurator, file, key, "key (representing the virtual path) must be a string");
            return -1;
        }
        if (value->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(configurator, file, key, "value (representing the local path) must be a string");
            return -1;
        }
        h2o_register_file_handler(host_config, key->data.scalar, value->data.scalar, "index.html" /* FIXME */);
    }

    return 0;
}
コード例 #4
0
ファイル: file.c プロジェクト: lhjay1/h2o
static int assert_is_extension(h2o_configurator_command_t *cmd, const char *file, yoml_t *node)
{
    if (node->type != YOML_TYPE_SCALAR) {
        h2o_config_print_error(cmd, file, node, "expected a scalar (extension)");
        return -1;
    }
    if (node->data.scalar[0] != '.') {
        h2o_config_print_error(cmd, file, node, "given extension \"%s\" does not start with a \".\"", node->data.scalar);
        return -1;
    }
    return 0;
}
コード例 #5
0
ファイル: file.c プロジェクト: lhjay1/h2o
static int assert_is_mimetype(h2o_configurator_command_t *cmd, const char *file, yoml_t *node)
{
    if (node->type != YOML_TYPE_SCALAR) {
        h2o_config_print_error(cmd, file, node, "expected a scalar (mime-type)");
        return -1;
    }
    if (strchr(node->data.scalar, '/') == NULL) {
        h2o_config_print_error(cmd, file, node, "the string \"%s\" does not look like a mime-type", node->data.scalar);
        return -1;
    }
    return 0;
}
コード例 #6
0
ファイル: file.c プロジェクト: lhjay1/h2o
static int set_mimetypes(h2o_configurator_command_t *cmd, h2o_mimemap_t *mimemap, const char *file, yoml_t *node)
{
    size_t i, j;

    assert(node->type == YOML_TYPE_MAPPING);

    for (i = 0; i != node->data.mapping.size; ++i) {
        yoml_t *key = node->data.mapping.elements[i].key;
        yoml_t *value = node->data.mapping.elements[i].value;
        if (assert_is_mimetype(cmd, file, key) != 0)
            return -1;
        switch (value->type) {
        case YOML_TYPE_SCALAR:
            if (assert_is_extension(cmd, file, value) != 0)
                return -1;
            h2o_mimemap_set_type(mimemap, value->data.scalar + 1, key->data.scalar);
            break;
        case YOML_TYPE_SEQUENCE:
            for (j = 0; j != value->data.sequence.size; ++j) {
                yoml_t *ext_node = value->data.sequence.elements[j];
                if (assert_is_extension(cmd, file, ext_node) != 0)
                    return -1;
                h2o_mimemap_set_type(mimemap, ext_node->data.scalar + 1, key->data.scalar);
            }
            break;
        default:
            h2o_config_print_error(cmd, file, value, "only scalar or sequence of scalar is permitted at the value part of the argument");
            return -1;
        }
    }

    return 0;
}
コード例 #7
0
ファイル: config.c プロジェクト: Gwill/h2o
ssize_t h2o_config_get_one_of(h2o_configurator_t *configurator, const char *file, yoml_t *node, const char *candidates)
{
    const char *config_str, *cand_str;
    ssize_t config_str_len, cand_index;

    if (node->type != YOML_TYPE_SCALAR)
        goto Error;

    config_str = node->data.scalar;
    config_str_len = strlen(config_str);

    cand_str = candidates;
    for (cand_index = 0; ; ++cand_index) {
        if (strncasecmp(cand_str, config_str, config_str_len) == 0
            && (cand_str[config_str_len] == '\0' || cand_str[config_str_len] == ',')) {
            /* found */
            return cand_index;
        }
        cand_str = strchr(cand_str, ',');
        if (cand_str == NULL)
            goto Error;
        cand_str += 1; /* skip ',' */
    }
    /* not reached */

Error:
    h2o_config_print_error(configurator, file, node, "argument must be one of: %s", candidates);
    return -1;
}
コード例 #8
0
ファイル: main.c プロジェクト: Debug-Orz/h2o
static SSL_CTX *on_config_listen_setup_ssl(h2o_configurator_command_t *cmd, const char *config_file, yoml_t *config_node)
{
    SSL_CTX *ssl_ctx = NULL;
    const char *cert_file = NULL, *key_file = NULL;
    yoml_t *t;

    /* parse */
    if (config_node->type != YOML_TYPE_MAPPING) {
        h2o_config_print_error(cmd, config_file, config_node, "`ssl` is not a mapping");
        goto Error;
    }
    if ((t = yoml_get(config_node, "certificate-file")) == NULL) {
        h2o_config_print_error(cmd, config_file, config_node, "could not find mandatory property `certificate-file`");
        goto Error;
    } else if (t->type != YOML_TYPE_SCALAR) {
        h2o_config_print_error(cmd, config_file, t, "the property must be a string");
        goto Error;
    }
    cert_file = t->data.scalar;
    if ((t = yoml_get(config_node, "key-file")) == NULL) {
        h2o_config_print_error(cmd, config_file, config_node, "could not find mandatory property `key-file`");
        goto Error;
    } else if (t->type != YOML_TYPE_SCALAR) {
        h2o_config_print_error(cmd, config_file, t, "the property must be a string");
        goto Error;
    }
    key_file = t->data.scalar;

    /* setup */
    init_openssl();
    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
    setup_ecc_key(ssl_ctx);
    if (SSL_CTX_use_certificate_file(ssl_ctx, cert_file, SSL_FILETYPE_PEM) != 1) {
        h2o_config_print_error(cmd, config_file, config_node, "failed to load certificate file:%s\n", cert_file);
        ERR_print_errors_fp(stderr);
        goto Error;
    }
    if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
        h2o_config_print_error(cmd, config_file, config_node, "failed to load private key file:%s\n", key_file);
        ERR_print_errors_fp(stderr);
        goto Error;
    }

    /* setup protocol negotiation methods */
#if H2O_USE_NPN
    h2o_ssl_register_npn_protocols(ssl_ctx, h2o_http2_npn_protocols);
#endif
#if H2O_USE_ALPN
    h2o_ssl_register_alpn_protocols(ssl_ctx, h2o_http2_alpn_protocols);
#endif

    return ssl_ctx;
Error:
    if (ssl_ctx != NULL)
        SSL_CTX_free(ssl_ctx);
    return NULL;
}
コード例 #9
0
ファイル: config.c プロジェクト: Gwill/h2o
static int apply_commands(void *config, const char *file, yoml_t *node, h2o_global_configuration_t *global_config)
{
    yoml_t *key, *value;
    size_t i;

    if (node->type != YOML_TYPE_MAPPING) {
        h2o_config_print_error(NULL, file, node, "node must be a MAPPING");
        return -1;
    }

    for (i = 0; i != node->data.mapping.size; ++i) {
        h2o_configurator_t *configurator;
        key = node->data.mapping.elements[i].key;
        value = node->data.mapping.elements[i].value;
        if (key->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(NULL, file, key, "command must be a string");
            return -1;
        }
        if (config == global_config) {
            if ((configurator = h2o_config_get_configurator(&global_config->global_configurators, key->data.scalar)) != NULL) {
                if (configurator->on_cmd(configurator, config, file, value) != 0)
                    return -1;
            } else if ((configurator = h2o_config_get_configurator(&global_config->host_configurators, key->data.scalar)) != NULL) {
                if (configurator->on_cmd(configurator, &global_config->default_host, file, value) != 0)
                    return -1;
            } else {
                goto UnknownCommand;
            }
        } else {
            if ((configurator = h2o_config_get_configurator(&global_config->host_configurators, key->data.scalar)) == NULL)
                goto UnknownCommand;
            if (configurator->on_cmd(configurator, config, file, value) != 0)
                return -1;
        }
    }

    return 0;

UnknownCommand:
    h2o_config_print_error(NULL, file, key, "unknown command: %s", key->data.scalar);
    return -1;
}
コード例 #10
0
ファイル: config.c プロジェクト: Gwill/h2o
int h2o_config_scanf(h2o_configurator_t *configurator, const char *file, yoml_t *node, const char *fmt, ...)
{
    va_list args;
    int sscan_ret;

    if (node->type != YOML_TYPE_SCALAR)
        goto Error;
    va_start(args, fmt);
    sscan_ret = vsscanf(node->data.scalar, fmt, args);
    va_end(args);
    if (sscan_ret != 1)
        goto Error;

    return 0;
Error:
    h2o_config_print_error(configurator, file, node, "argument must match the format: %s", fmt);
    return -1;
}
コード例 #11
0
ファイル: file.c プロジェクト: lhjay1/h2o
static int on_config_index(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, const char *file, yoml_t *node)
{
    struct st_h2o_file_configurator_t *self = (void*)cmd->configurator;
    size_t i;

    free(self->vars->index_files);
    self->vars->index_files = h2o_malloc(sizeof(self->vars->index_files[0]) * (node->data.sequence.size + 1));
    for (i = 0; i != node->data.sequence.size; ++i) {
        yoml_t *element = node->data.sequence.elements[i];
        if (element->type != YOML_TYPE_SCALAR) {
            h2o_config_print_error(cmd, file, element, "argument must be a sequence of scalars");
            return -1;
        }
        self->vars->index_files[i] = element->data.scalar;
    }
    self->vars->index_files[i] = NULL;

    return 0;
}
コード例 #12
0
ファイル: main.c プロジェクト: Debug-Orz/h2o
static int on_config_listen(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, const char *config_file, yoml_t *config_node)
{
    struct config_t *conf = H2O_STRUCT_FROM_MEMBER(struct config_t, global_config, ctx->globalconf);
    const char *hostname = NULL, *servname = NULL;
    SSL_CTX *ssl_ctx = NULL;
    struct addrinfo hints, *res;
    int error;

    /* fetch servname (and hostname) */
    switch (config_node->type) {
    case YOML_TYPE_SCALAR:
        servname = config_node->data.scalar;
        break;
    case YOML_TYPE_MAPPING:
        {
            yoml_t *t;
            if ((t = yoml_get(config_node, "host")) != NULL) {
                if (t->type != YOML_TYPE_SCALAR) {
                    h2o_config_print_error(cmd, config_file, t, "`host` is not a string");
                    return -1;
                }
                hostname = t->data.scalar;
            }
            if ((t = yoml_get(config_node, "port")) == NULL) {
                h2o_config_print_error(cmd, config_file, config_node, "cannot find mandatory property `port`");
                return -1;
            }
            if (t->type != YOML_TYPE_SCALAR) {
                h2o_config_print_error(cmd, config_file, config_node, "`port` is not a string");
                return -1;
            }
            servname = t->data.scalar;
            if ((t = yoml_get(config_node, "ssl")) != NULL) {
                if ((ssl_ctx = on_config_listen_setup_ssl(cmd, config_file, t)) == NULL)
                    return -1;
            }
        }
        break;
    default:
        h2o_config_print_error(cmd, config_file, config_node, "value must be a string or a mapping (with keys: `port` and optionally `host`)");
        return -1;
    }

    /* call getaddrinfo */
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE;
    if ((error = getaddrinfo(hostname, servname, &hints, &res)) != 0) {
        h2o_config_print_error(cmd, config_file, config_node, "failed to resolve the listening address: %s", gai_strerror(error));
        return -1;
    } else if (res == NULL) {
        h2o_config_print_error(cmd, config_file, config_node, "failed to resolve the listening address: getaddrinfo returned an empty list");
        return -1;
    }

    { /* save the entries */
        struct addrinfo *ai;
        for (ai = res; ai != NULL; ai = ai->ai_next) {
            struct listener_config_t *listener = h2o_malloc(sizeof(*listener));
            listener->fd = -1;
            listener->family = ai->ai_family;
            listener->socktype = ai->ai_socktype;
            listener->protocol = ai->ai_protocol;
            memcpy(&listener->addr, ai->ai_addr, ai->ai_addrlen);
            listener->addrlen = ai->ai_addrlen;
            listener->ssl_ctx = ssl_ctx;
            conf->listeners = h2o_realloc(conf->listeners, sizeof(*conf->listeners) * (conf->num_listeners + 1));
            conf->listeners[conf->num_listeners++] = listener;
        }
    }

    /* release res */
    freeaddrinfo(res);

    return 0;
}