예제 #1
0
파일: lwan.c 프로젝트: dreamsxin/lwan
static void parse_listener_prefix(struct config *c, struct config_line *l,
                                  struct lwan *lwan,
                                  const struct lwan_module *module,
                                  void *handler)
{
    struct lwan_url_map url_map = {};
    struct hash *hash = hash_str_new(free, free);
    char *prefix = strdupa(l->value);
    struct config *isolated;

    isolated = config_isolate_section(c, l);
    if (!isolated) {
        config_error(c, "Could not isolate configuration file");
        goto out;
    }

    while (config_read_line(c, l)) {
        switch (l->type) {
        case CONFIG_LINE_TYPE_LINE:
            if (streq(l->key, "module")) {
                if (module) {
                    config_error(c, "Module already specified");
                    goto out;
                }
                module = find_module(l->value);
                if (!module) {
                    config_error(c, "Could not find module \"%s\"", l->value);
                    goto out;
                }
            } else if (streq(l->key, "handler")) {
                if (handler) {
                    config_error(c, "Handler already specified");
                    goto out;
                }
                handler = find_handler(l->value);
                if (!handler) {
                    config_error(c, "Could not find handler \"%s\"", l->value);
                    goto out;
                }
            } else {
                hash_add(hash, strdup(l->key), strdup(l->value));
            }

            break;
        case CONFIG_LINE_TYPE_SECTION:
            if (streq(l->key, "authorization")) {
                parse_listener_prefix_authorization(c, l, &url_map);
            } else {
                if (!config_skip_section(c, l)) {
                    config_error(c, "Could not skip section");
                    goto out;
                }
            }

            break;
        case CONFIG_LINE_TYPE_SECTION_END:
            goto add_map;
        }
    }

    config_error(c, "Expecting section end while parsing prefix");
    goto out;

add_map:
    if (module == handler && !handler) {
        config_error(c, "Missing module or handler");
        goto out;
    }
    if (module && handler) {
        config_error(c, "Handler and module are mutually exclusive");
        goto out;
    }

    if (handler) {
        url_map.handler = handler;
        url_map.flags |= HANDLER_PARSE_MASK | HANDLER_DATA_IS_HASH_TABLE;
        url_map.data = hash;
        url_map.module = NULL;

        hash = NULL;
    } else if (module && module->create_from_hash && module->handle_request) {
        url_map.data = module->create_from_hash(prefix, hash);

        if (module->parse_conf && !module->parse_conf(url_map.data, isolated)) {
            const char *msg = config_last_error(isolated);

            config_error(c, "Error from module: %s", msg ? msg : "Unknown");
            goto out;
        }

        url_map.handler = module->handle_request;
        url_map.flags |= module->flags;
        url_map.module = module;
    } else {
        config_error(c, "Invalid handler");
        goto out;
    }

    add_url_map(&lwan->url_map_trie, prefix, &url_map);

out:
    hash_free(hash);
    config_close(isolated);
}
예제 #2
0
파일: lwan.c 프로젝트: lpereira/lwan
static void parse_listener_prefix(struct config *c,
                                  struct config_line *l,
                                  struct lwan *lwan,
                                  const struct lwan_module *module,
                                  void *handler)
{
    struct lwan_url_map url_map = {};
    struct hash *hash = hash_str_new(free, free);
    char *prefix = strdupa(l->value);
    struct config *isolated;

    isolated = config_isolate_section(c, l);
    if (!isolated) {
        config_error(c, "Could not isolate configuration file");
        goto out;
    }

    while (config_read_line(c, l)) {
        switch (l->type) {
        case CONFIG_LINE_TYPE_LINE:
            hash_add(hash, strdup(l->key), strdup(l->value));
            break;

        case CONFIG_LINE_TYPE_SECTION:
            if (streq(l->key, "authorization")) {
                parse_listener_prefix_authorization(c, l, &url_map);
            } else if (!config_skip_section(c, l)) {
                config_error(c, "Could not skip section");
                goto out;
            }
            break;

        case CONFIG_LINE_TYPE_SECTION_END:
            goto add_map;
        }
    }

    config_error(c, "Expecting section end while parsing prefix");
    goto out;

add_map:
    assert((handler && !module) || (!handler && module));

    if (handler) {
        url_map.handler = handler;
        url_map.flags |= HANDLER_PARSE_MASK | HANDLER_DATA_IS_HASH_TABLE;
        url_map.data = hash;
        url_map.module = NULL;

        hash = NULL;
    } else if (module->create_from_hash && module->handle_request) {
        url_map.data = module->create_from_hash(prefix, hash);
        if (!url_map.data) {
            config_error(c, "Could not create module instance");
            goto out;
        }

        if (module->parse_conf && !module->parse_conf(url_map.data, isolated)) {
            const char *msg = config_last_error(isolated);

            config_error(c, "Error from module: %s", msg ? msg : "Unknown");
            goto out;
        }

        url_map.handler = module->handle_request;
        url_map.flags |= module->flags;
        url_map.module = module;
    } else if (UNLIKELY(!module->create_from_hash)) {
        config_error(c, "Module isn't prepared to load settings from a file; "
                        "create_from_hash() method isn't present");
        goto out;
    } else if (UNLIKELY(!module->handle_request)) {
        config_error(c, "Module does not have handle_request() method");
        goto out;
    }

    add_url_map(&lwan->url_map_trie, prefix, &url_map);

out:
    hash_free(hash);
    config_close(isolated);
}
예제 #3
0
파일: lwan.c 프로젝트: LegendZhu/lwan
static void parse_listener_prefix(config_t *c, config_line_t *l, lwan_t *lwan,
    const lwan_module_t *module)
{
    lwan_url_map_t url_map = { };
    struct hash *hash = hash_str_new(free, free);
    void *handler = NULL;
    char *prefix = strdupa(l->line.value);
    config_t isolated = { };

    if (!config_isolate_section(c, l, &isolated)) {
        config_error(c, "Could not isolate configuration file");
        goto out;
    }

    while (config_read_line(c, l)) {
      switch (l->type) {
      case CONFIG_LINE_TYPE_LINE:
          if (!strcmp(l->line.key, "module")) {
              if (module) {
                  config_error(c, "Module already specified");
                  goto out;
              }
              module = lwan_module_find(lwan, l->line.value);
              if (!module) {
                  config_error(c, "Could not find module \"%s\"", l->line.value);
                  goto out;
              }
          } else if (!strcmp(l->line.key, "handler")) {
              handler = find_handler_symbol(l->line.value);
              if (!handler) {
                  config_error(c, "Could not find handler \"%s\"", l->line.value);
                  goto out;
              }
          } else {
              hash_add(hash, strdup(l->line.key), strdup(l->line.value));
          }

          break;
      case CONFIG_LINE_TYPE_SECTION:
          if (!strcmp(l->section.name, "authorization")) {
              parse_listener_prefix_authorization(c, l, &url_map);
          } else {
              if (!config_skip_section(c, l)) {
                  config_error(c, "Could not skip section");
                  goto out;
              }
          }

          break;
      case CONFIG_LINE_TYPE_SECTION_END:
          goto add_map;
      }
    }

    config_error(c, "Expecting section end while parsing prefix");
    goto out;

add_map:
    if (module == handler && !handler) {
        config_error(c, "Missing module or handler");
        goto out;
    }
    if (module && handler) {
        config_error(c, "Handler and module are mutually exclusive");
        goto out;
    }

    if (handler) {
        url_map.handler = handler;
        url_map.flags |= HANDLER_PARSE_MASK;
        url_map.data = hash;
        url_map.module = NULL;

        hash = NULL;
    } else if (module && module->init_from_hash && module->handle) {
        url_map.data = module->init_from_hash(hash);
        if (isolated.file && module->parse_conf) {
            if (!module->parse_conf(url_map.data, &isolated)) {
                config_error(c, "Error from module: %s",
                    isolated.error_message ? isolated.error_message : "Unknown");
                goto out;
            }
        }
        url_map.handler = module->handle;
        url_map.flags |= module->flags;
        url_map.module = module;
    } else {
        config_error(c, "Invalid handler");
        goto out;
    }

    add_url_map(&lwan->url_map_trie, prefix, &url_map);

out:
    hash_free(hash);
    config_close(&isolated);
}