config.c

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

C
936
字号
/* * Copyright (c) 1999-2000 Caucho Technology.  All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License").  In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright *    notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include  *    an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and *    may not be used to endorse products derived from this software. *    "Resin" or "Caucho" may not appear in the names of products derived *    from this software. * * 4. Caucho Technology requests that attribution be given to Resin *    in any manner possible.  We suggest using the "Resin Powered" *    button or creating a "powered by Resin(tm)" link to *    http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind.  * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL Caucho OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES.       *//* * config.c is responsible for scanning the parsed registry and grabbing * relevant data. * * Important data include the web-app and the servlet-mapping so any filter * can properly dispatch the request. * * Also, config.c needs to grab the srun and srun-backup blocks to properly * send the requests to the proper JVM. */#ifdef WIN32#include <winsock2.h>#else#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <dirent.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/stat.h>#include "cse.h"#define CACHE_SIZE 16384typedef struct hash_t {  char *host;  int port;  char *uri;  int is_match;  int count;} hash_t;static hash_t g_url_cache[CACHE_SIZE];static voidcse_add_unique_location(config_t *config, char *host, int port, char *prefix,                        char *suffix, int is_exact){  location_t *loc;  for (loc = config->locations; loc; loc = loc->next) {    if ((host == 0) != (loc->host == 0))      continue;    else if (host && strcmp(host, loc->host))      continue;    else if (port != loc->port)      continue;    else if (is_exact != loc->is_exact)      continue;    else if ((prefix == 0) != (loc->prefix == 0))      continue;    else if (prefix && strcmp(prefix, loc->prefix))      continue;    else if ((suffix == 0) != (loc->suffix == 0))      continue;    else if (suffix && strcmp(suffix, loc->suffix))      continue;    return;  }  loc = (location_t *) cse_alloc(config->p, sizeof(location_t));  memset(loc, 0, sizeof(location_t));  loc->next = config->locations;  config->locations = loc;  loc->host = host;  loc->port = port;  loc->prefix = prefix;  loc->suffix = suffix;  loc->is_exact = is_exact;  LOG(("loc %s:%d %s %s %x\n",        loc->host ? loc->host : "(null)",       loc->port,       loc->prefix ? loc->prefix : "(null)",       loc->suffix ? loc->suffix : "(null)",       loc->next));}/** * Add a location pattern to the list of recognized locations * * @param config the configuration * @param host the host for the pattern * @param prefix the web-app prefix * @param pattern the url-pattern to match * * @return the new location */static voidcse_add_location(config_t *config, char *host, char *prefix, char *pattern){  char cleanPrefix[4096];  char *port_string;  int prefixLength;  int cleanLength;  int i;  char *loc_host;  int loc_port = 0;  char *loc_prefix = 0;  char *loc_suffix = 0;  int loc_is_exact = 0;    #ifdef WIN32  if (host) {    host = cse_strdup(config->p, host);    for (i = 0; host[i]; i++)      host[i] = tolower(host[i]);  }  if (prefix) {    prefix = cse_strdup(config->p, prefix);    for (i = 0; prefix[i]; i++)      prefix[i] = tolower(prefix[i]);  }  if (pattern) {    pattern = cse_strdup(config->p, pattern);    for (i = 0; pattern[i]; i++)      pattern[i] = tolower(pattern[i]);  }#endif /* WIN32 */  cleanPrefix[0] = 0;  loc_host = host ? cse_strdup(config->p, host) : 0;  if (loc_host && (port_string = strchr(loc_host, ':'))) {    *port_string = 0;    loc_port = atoi(port_string + 1);  }  if (! prefix[0] && pattern[0] && pattern[0] != '/' && pattern[0] != '*')    strcpy(cleanPrefix, "/");  else if (prefix[0] && prefix[0] != '/')    strcpy(cleanPrefix, "/");  strcat(cleanPrefix, prefix);  prefixLength = strlen(cleanPrefix);  if (prefixLength > 0 && cleanPrefix[prefixLength - 1] == '/')    cleanPrefix[prefixLength - 1] = 0;  if (! pattern[0]) {    loc_prefix = cse_strdup(config->p, cleanPrefix);    loc_suffix = 0;  }  else if (pattern[0] == '*') {    loc_prefix = cse_strdup(config->p, cleanPrefix);    loc_suffix = pattern + 1;  }  else {    if (pattern[0] != '/')      strcat(cleanPrefix, "/");    strcat(cleanPrefix, pattern);    cleanLength = strlen(cleanPrefix);    if (strlen(pattern) <= 1)      cleanPrefix[cleanLength - 1] = 0;    else if (cleanPrefix[cleanLength - 1] != '*')      loc_is_exact = 1;    else if (cleanLength > 2)      cleanPrefix[cleanLength - 2] = 0;    loc_prefix = cse_strdup(config->p, cleanPrefix);    loc_suffix = 0;  }  cse_add_unique_location(config, loc_host, loc_port, loc_prefix,                          loc_suffix, loc_is_exact);}/** * Returns true if the path is an absolute path */static intis_path_absolute(char *path){  return (path[0] == '/' || path[0] == '\\' ||          (path[1] == ':' &&           ((path[0] >= 'a' && path[0] <= 'z') ||            (path[0] >= 'A' && path[0] <= 'Z'))));}static char *cse_app_dir(config_t *config, registry_t *node, char *parent){  char buf[4096];  char *value;  if (! node)    return parent;    value = cse_find_value(node->first, "app-dir");    if (! parent || ! *parent)    parent = ".";  if ((! value || ! value[0]) && ! strcmp(node->key, "web-app")) {    value = node->value;        if (value && value[0] == '/')      value++;  }    if (! value || ! value[0]) {    LOG(("app-dir(p) %s\n", parent));    return parent;  }  /* XXX: in theory only for win32 */  if (is_path_absolute(value)) {    LOG(("app-dir(a) %s\n", value));    return value;  }  /* since this only happens on startup, the memory leak is okay */  sprintf(buf, "%s/%s", parent, value);    LOG(("app-dir(r) %s\n", buf));    return cse_strdup(config->p, buf);}static voidcse_init_web_app_contents(config_t *config, registry_t *node,                          char *host, char *prefix){  /* This is added automatically on the Java side, but it seems  // inappropriate to add it to the plugin side.  // cse_add_location(config, host, "", "*.jsp");  // cse_add_location(config, host, "", "*.xtp");  // WEB-INF passes to Resin so Resin can hide it.  */  cse_add_location(config, host, prefix, "/WEB-INF/*");    for (; node; node = node->next) {    if (! strcmp(node->key, "servlet-mapping")) {      registry_t *url_pattern = cse_next_link(node->first, "url-pattern");      if (url_pattern && url_pattern->value)	cse_add_location(config, host, prefix, url_pattern->value);    }  }}/** * Adds a configuration file as a dependency.  If the file changes, * the plugin will reread the configuration. * * @param config the server configuration. * @param path filepath to the dependent file. */static voidcse_add_depend(config_t *config, char *path){  struct stat st;  depend_t *depend;    depend = (depend_t *) cse_alloc(config->p, sizeof(depend_t));  memset(depend, 0, sizeof(depend_t));  depend->next = config->depend_list;  config->depend_list = depend;  depend->path = cse_strdup(config->p, path);  if (! stat(path, &st)) {    depend->last_modified = st.st_mtime;    depend->last_size = st.st_size;  }}/** * Initialize a web application. */static voidcse_init_web_app(config_t *config, registry_t *node,                 char *host, char *prefix, char *app_dir){  char buf[4096];  FILE *file;    if (node)    cse_init_web_app_contents(config, node->first, host, prefix);    /* XXX: should the registry itself get updated? i.e. adding this  // node somewhere?  */  sprintf(buf, "%s/WEB-INF/web.xml", app_dir);  LOG(("web-app %s\n", buf));    cse_add_depend(config, buf);    file = fopen(buf, "r");  if (file) {    registry_t *web = cse_parse(file, config, cse_strdup(config->p, buf));    fclose(file);    if (web && web->first)      cse_init_web_app_contents(config, web->first->first, host, prefix);  }}/** * Initialize the war dir. */static voidcse_init_war_dir(config_t *config, char *host, char *war_dir){#ifndef WIN32  DIR *dir;  struct dirent *dirent;  LOG(("war-dir %s\n", war_dir));    cse_add_depend(config, war_dir);  dir = opendir(war_dir);  if (! dir)    return;    while ((dirent = readdir(dir))) {    char app_dir[4096];    char prefix[4096];    char *name = dirent->d_name;    struct stat st;    sprintf(prefix, "/%s", name);    sprintf(app_dir, "%s/%s", war_dir, name);        if (! stat(app_dir, &st) && S_ISDIR(st.st_mode) && name[0] != '.') {      LOG(("app %s\n", name));          cse_init_web_app(config, 0, host, prefix, app_dir);    }  }  closedir(dir);#endif}/** * Initialize the configuration mapping for the <host> block. * * @param config configuration structure holding the parsed mapping. * @param node the configuration node for the <host> block. * @param host default host name. * @param app_dir current directory. */static voidcse_init_host(config_t *config, registry_t *node, char *host,              char *app_dir){  char *host_dir = cse_app_dir(config, node, app_dir);                                 cse_init_web_app(config, node, host, "", host_dir);  if (! node)    return;  for (node = node->first; node; node = node->next) {    if (! node->value) {    }    else if (! strcmp(node->key, "web-app")) {      char *prefix = node->value;      char *subdir = cse_app_dir(config, node, host_dir);      cse_init_web_app(config, node, host, prefix, subdir);    }    else if (! strcmp(node->key, "war-dir") && node->value) {      char *subdir = node->value;      char war_dir[8192];      if (is_path_absolute(subdir))        sprintf(war_dir, "%s", subdir);      else        sprintf(war_dir, "%s/%s", config->resin_home, subdir);      cse_init_war_dir(config, host, war_dir);    }  }}/** * Initialize the dispatch mappings. */static voidcse_init_server(config_t *config, registry_t *node){  char *app_dir = cse_app_dir(config, node, config->resin_home);  cse_init_host(config, node, "", config->resin_home);  if (! node)    return;  for (node = node->first; node; node = node->next) {    if (node->value && ! strcmp(node->key, "host")) {      char *name = node->value;      char *host_dir = cse_app_dir(config, node, app_dir);      cse_init_host(config, node, name, host_dir);    }  }}/** * Adds a new backup to the configuration */srun_t *cse_add_host(config_t *config, const char *hostname, int port){  return cse_add_host_int(config, hostname, port, 0, 0);}/** * Adds a new backup to the configuration */srun_t *cse_add_backup(config_t *config, const char *hostname, int port){  return cse_add_host_int(config, hostname, port, 1, 0);

⌨️ 快捷键说明

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