config.c

来自「《jsp编程起步》里面的所有源代码」· C语言 代码 · 共 936 行 · 第 1/2 页

C
936
字号
}/** * initialize a single srun host */static voidcse_init_host_node(config_t *config, registry_t *node,		   int is_backup, int is_default){  int port;  char *host;  registry_t *host_node = cse_next_link(node, "srun-host");  registry_t *port_node = cse_next_link(node, "srun-port");  srun_t *srun = 0;  registry_t *subnode;  if (! host_node && ! is_default)    host_node = cse_next_link(node, "host");  if (! port_node && ! is_default)    port_node = cse_next_link(node, "port");      if (port_node && port_node->value && *port_node->value) {    port = atoi(port_node->value);  }  else    port = 6802;      if (host_node && host_node->value && *host_node->value) {    host = host_node->value;  }  else    host = "localhost";  srun = cse_add_host_int(config, host, port, is_backup, is_default);  if (! srun)    return;  subnode = cse_next_link(node, "connect-timeout");  if (subnode && subnode->value && *subnode->value)    srun->connect_timeout = atoi(subnode->value);    subnode = cse_next_link(node, "live-time");  if (subnode && subnode->value && *subnode->value) {    srun->live_time = atoi(subnode->value);    if (srun->live_time < 5)      srun->live_time = 5;  }    subnode = cse_next_link(node, "dead-time");  if (subnode && subnode->value && *subnode->value) {    srun->dead_time = atoi(subnode->value);    if (srun->dead_time < 5)      srun->dead_time = 5;  }}/** * Initialize all the load-balancing hosts in the configuration. */static void cse_init_hosts(config_t *config, registry_t *top){  int has_srun = 0;  registry_t *node;    for (node = cse_next_link(top, "srun");       node;       node = cse_next_link(node->next, "srun")) {    has_srun = 1;    cse_init_host_node(config, node->first, 0, 0);  }  for (node = cse_next_link(top, "srun-backup");       node;       node = cse_next_link(node->next, "srun-backup")) {    has_srun = 1;    cse_init_host_node(config, node->first, 1, 0);  }  if (! has_srun) {    cse_init_host_node(config, top, 0, 1);  }}/** * Logging for the configuration file. */voidcse_log_config(config_t *config){  location_t *loc = config->locations;  for (; loc; loc = loc->next) {    LOG(("cfg host:%s prefix:%s suffix:%s next:%x\n",          loc->host ? loc->host : "null",         loc->prefix ? loc->prefix : "null",         loc->suffix ? loc->suffix : "null",         loc->next));  }}static voidcse_init_error_page(config_t *config, registry_t *node){  for (node = cse_next_link(node, "error-page");       node;       node = cse_next_link(node->next, "error-page")) {    char *exn = cse_find_value(node->first, "exception-type");    char *code = cse_find_value(node->first, "error-code");        if (exn && ! strcmp(exn, "connection"))      config->error_page = cse_find_value(node->first, "location");    else if (! exn && ! code && ! config->error_page)      config->error_page = cse_find_value(node->first, "location");  }}/** * Initialize the configuration. */voidcse_init_config(config_t *config){  registry_t *root = 0;  registry_t *node = 0;  FILE *is;  char *caucho_status;  int i;  LOG(("initializing from %s\n", config->path));  if (! config->p)    config->p = cse_create_pool();  if (! config->resin_home) {    int p = strlen(config->path);        for (;         p >= 0 && (config->path[p] != '/' && config->path[p] != '\\');         p--) {    }        for (p--;         p >= 0 && (config->path[p] != '/' && config->path[p] != '\\');         p--) {    }    if (p >= 0) {      config->resin_home = strdup(config->path);      config->resin_home[p] = 0;    }    else {      config->resin_home = ".";    }  }  /*  // XXX: in theory, should free these, but they only change during  // development, so it really shouldn't matter  */  config->registry = 0;  config->locations = 0;  for (i = 0; i < CACHE_SIZE; i++) {    if (g_url_cache[i].uri) {      free(g_url_cache[i].uri);      free(g_url_cache[i].host);    }    g_url_cache[i].uri = 0;  }    config->update_count++;  config->disable_caucho_status = 0;  config->srun_list = 0;  config->srun_capacity = 0;  config->srun_size = 0;  config->depend_list = 0;  cse_add_depend(config, config->path);  is = fopen(config->path, "r");  if (! is) {    cse_error(config, "Resin cannot open config file `%s'\n", config->path);    return;  }  root = cse_parse(is, config, config->path);  fclose(is);  config->registry = root;  cse_print_registry(root);    if (root)    node = cse_next_link(root->first, "caucho.com");  if (node)    node = cse_next_link(node->first, "http-server");  if (node) {    caucho_status = cse_find_value(node->first, "caucho-status");	if (caucho_status &&            (! strcmp(caucho_status, "false") ||             ! strcmp(caucho_status, "no")))          config->disable_caucho_status = 1;  }  if (node)    cse_init_server(config, node);  if (node)    cse_init_hosts(config, node->first);  if (node)    cse_init_error_page(config, node->first);  if (! config->lock)    config->lock = cse_create_lock();}/** * Check the configuration files for any changes.  If there are any changes, * reload the configuration files. */voidcse_update_config(config_t *config, int now){  struct stat st;  depend_t *depend;  int has_changed = 0;  int diff = config->last_update - now;  if (diff > -15 && diff < 15)    return;  config->last_update = now;    for (depend = config->depend_list;       depend && ! has_changed;       depend = depend->next) {    if (stat(depend->path, &st))      has_changed = depend->last_modified != 0;    else if (depend->last_modified != st.st_mtime)      has_changed = 1;    else if (depend->last_size != st.st_size)      has_changed = 1;    if (has_changed) {      LOG(("%s mod:%d->%d size:%d->%d\n", depend->path,           depend->last_modified, st.st_mtime,           depend->last_size, st.st_size));    }  }  if (has_changed) {    cse_lock(config->lock);    cse_close_sockets(config);    cse_free_pool(config->p);    cse_init_config(config);    cse_unlock(config->lock);  }}/** * tests if 'full' starts with 'part' * * If it's not an exact match, the next character of 'full' must be '/'. * That way, a servlet mapping of '/foo/ *' will match /foo, /foo/bar, but * not /foolish. */static intcse_starts_with(const char *full, const char *part){  char ch1, ch2;  while ((ch2 = *part++) && (ch1 = *full++) && ch1 == ch2) {  }  if (ch2)    return 0;  else if (! *full)    return 1;  else    return *full == '/';}static intcse_match_suffix(const char *full, const char *suffix){  int len = strlen(suffix);  do {    char *match = strstr(full, suffix);    if (! match)      return 0;        if (! match[len] || match[len] == '/')      return 1;#ifdef WIN32    if (match[len] == '.') {      for (; match[len] == '.'; len++) {      }      if (! match[len] || match[len] == '/')     	return 1;    }#endif    full = match + len;  } while (*full);  return 0;}/** * Match the url to the location pattern. * * The match is cached by url_cache so common urls will be served quickly. * * @param loc the location pattern. * @param host the request's host * @param port the request's port * @param uri the request's uri */static intcse_match_location(config_t *config,                   location_t *loc,                   const char *host, int port,                   const char *uri){  int hash = port;  int i;  int is_match = 0;    hash_t *entry;  char *test_uri;  char *test_host;  int test_port;  int test_count;  int test_match;  if (! host)    host = "";  if (! uri)    uri = "";    for (i = 0; host && host[i]; i++)    hash = 65531 * hash + host[i];    for (i = 0; uri && uri[i]; i++)    hash = 65531 * hash + uri[i];  if (hash < 0)    hash = -hash;  hash = hash % CACHE_SIZE;  entry = &g_url_cache[hash];  test_count = entry->count;  test_uri = entry->uri;  test_host = entry->host;  test_port = entry->port;  test_match = entry->is_match;  if (test_count != entry->count) {  }  else if (! test_uri || strcmp(test_uri, uri)) {  }  else if (! test_host || strcmp(test_host, host)) {  }  else if (test_port && test_port != port) {  }  else    return test_match;    for (; loc; loc = loc->next) {    LOG(("match host:%s:%d prefix:%s suffix:%s with host:%s uri:%s next:%x\n",          loc->host ? loc->host : "null",         loc->port,         loc->prefix ? loc->prefix : "null",         loc->suffix ? loc->suffix : "null",         host, uri, loc->next));        if (*(loc->host) && ! strstr(loc->host, host))      continue;    else if (port && loc->port && port != loc->port)      continue;    else if (loc->is_exact && ! strcmp(uri, loc->prefix)) {      is_match = 1;      break;    }    else if (loc->is_exact)      continue;          else if (! cse_starts_with(uri, loc->prefix))      continue;        else if (loc->suffix && ! cse_match_suffix(uri, loc->suffix))      continue;    is_match = 1;    break;  }  if (! is_match && strstr(uri, "/j_security_check"))    is_match = 1;  cse_lock(config->lock);  entry->count++;  entry->is_match = is_match;  if (entry->uri) {    free(entry->host);    free(entry->uri);        entry->uri = 0;    entry->host = 0;  }  LOG(("entry %s %s\n", host, uri));    entry->host = strdup(host);  entry->uri = strdup(uri);  entry->port = port;  entry->count++;  cse_unlock(config->lock);  return is_match;}/** * Tests if the request matches a Resin URL. * * @param config the plugin configuration structure * @param host the request's host * @param port the request's port * @param url the request's uri */intcse_match_request(config_t *config, const char *host,                  int port, const char *uri){  char buf[16 * 1024];  int len = sizeof(buf) - 1;  int i, k;  int ch;  k = 0;  for (i = 0; (ch = uri[i]) && i + 1 < len; i++) {    if ((ch == ';' || ch == '?') &&        ! strncmp(uri + i, "jsessionid=", sizeof("jsessionid="))) {      break;    }    else if (ch == '/' && k > 0 && buf[k - 1] == '/')      continue;    else {#ifdef WIN32      buf[k++] = tolower(ch);#else      buf[k++] = ch;#endif    }  }  buf[k] = 0;  return (cse_match_location(config, config->locations, host, port, buf));}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?