📄 config.c
字号:
/* * Copyright (c) 1999-2008 Caucho Technology. All rights reserved. * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA *//* * 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>#include <fcntl.h>#else#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <dirent.h>#include <fcntl.h>#include <unistd.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#include <sys/stat.h>#include <errno.h>#include "cse.h"#define CACHE_SIZE 16384#define AUTO_WRITE_TIME (15 * 60)#define HMUX_DISPATCH_QUERY 'q'#define HMUX_DISPATCH_QUERY_CLUSTER 's'#define HMUX_DISPATCH_HOST 'h'#define HMUX_DISPATCH_WEB_APP 'a'#define HMUX_DISPATCH_MATCH 'm'#define HMUX_DISPATCH_IGNORE 'i'#define HMUX_DISPATCH_ETAG 'e'#define HMUX_DISPATCH_NO_CHANGE 'n'#define HMUX_DISPATCH_SRUN 's'typedef struct hash_t { char *host; int port; char *uri; resin_host_t *match_host; volatile int count; volatile int update_count;} hash_t;static int g_update_count;static hash_t g_url_cache[CACHE_SIZE];static resin_host_t *cse_match_host_impl(config_t *config, const char *host_name, int port, time_t now);static intresin_atoi(char *s){ int sign = 1; int value = 0; if (*s == '-') { sign = -1; s++; } else if (*s == '+') { s++; } for (; *s && '0' <= *s && *s <= '9'; s++) { value = 10 * value + *s - '0'; if (value < 0 || value > 0x3fffffff) return sign * 0x3fffffff; } return sign * value;}static location_t *cse_add_unique_location(mem_pool_t *pool, web_app_t *app, char *prefix, char *suffix, int is_exact, int ignore){ location_t *loc; for (loc = app->locations; loc; loc = loc->next) { 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; } loc = (location_t *) cse_alloc(pool, sizeof(location_t)); memset(loc, 0, sizeof(location_t)); loc->next = app->locations; app->locations = loc; loc->application = app; loc->prefix = prefix; loc->suffix = suffix; loc->is_exact = is_exact; loc->ignore = ignore; LOG(("%s:%d:cse_add_unique_location(): loc %s %s %x %s\n", __FILE__, __LINE__, loc->prefix ? loc->prefix : "(null)", loc->suffix ? loc->suffix : "(null)", loc->next, loc->ignore ? "ignore" : "")); return loc;}static web_app_t *cse_add_web_app(mem_pool_t *pool, resin_host_t *host, web_app_t *applications, char *context_path){ web_app_t *app; if (! context_path) context_path = ""; else if (! strcmp(context_path, "/")) context_path = ""; for (app = applications; app; app = app->next) { if (strcmp(context_path, app->context_path)) continue; return app; } app = (web_app_t *) cse_alloc(pool, sizeof(web_app_t)); memset(app, 0, sizeof(web_app_t)); app->next = applications; applications = app; app->host = host; /* defaults to having data. Set false if web-app is unavailable */ app->has_data = 1; app->context_path = cse_strdup(pool, context_path); LOG(("%s:%d:cse_add_web_app(): new web-app host:%s path:%s\n", __FILE__, __LINE__, host->name, app->context_path)); return applications;}/** * Add an application pattern to the list of recognized locations * * @param config the configuration * @param host the host for the pattern * @param prefix the web-app prefix * * @return the new application */static web_app_t *cse_add_application(mem_pool_t *pool, resin_host_t *host, web_app_t *applications, char *prefix){ char loc_prefix[8192]; int i, j; i = 0; if (prefix && *prefix && *prefix != '/') loc_prefix[i++] = '/'; #ifdef WIN32 if (prefix) { for (j = 0; prefix[j]; j++) loc_prefix[i++] = tolower(prefix[j]); }#else if (prefix) { for (j = 0; prefix[j]; j++) loc_prefix[i++] = prefix[j]; }#endif loc_prefix[i] = 0; return cse_add_web_app(pool, host, applications, loc_prefix);}/** * Add a location pattern to the list of recognized locations * * @param app the containing application * @param pattern the url-pattern to match * * @return the new location */static voidcse_add_location(mem_pool_t *pool, web_app_t *app, char *pattern, char *servlet_name){ char cleanPrefix[4096]; int prefixLength; int cleanLength; char *loc_prefix = 0; char *loc_suffix = 0; int loc_is_exact = 0; int ignore = 0; #ifdef WIN32 if (pattern) { int i; pattern = cse_strdup(pool, pattern); for (i = 0; pattern[i]; i++) pattern[i] = tolower(pattern[i]); }#endif /* WIN32 */ cleanPrefix[0] = 0; if (pattern[0] && pattern[0] != '/' && pattern[0] != '*') strcpy(cleanPrefix, "/"); prefixLength = strlen(cleanPrefix); if (prefixLength > 0 && cleanPrefix[prefixLength - 1] == '/') cleanPrefix[prefixLength - 1] = 0; if (! pattern[0]) { loc_prefix = cse_strdup(pool, cleanPrefix); loc_suffix = 0; } else if (pattern[0] == '*') { loc_prefix = cse_strdup(pool, cleanPrefix); loc_suffix = cse_strdup(pool, 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] == '/') cleanPrefix[cleanLength - 2] = 0; else if (cleanLength > 1) cleanPrefix[cleanLength - 1] = 0; loc_prefix = cse_strdup(pool, cleanPrefix); loc_suffix = 0; } if (servlet_name && ! strcmp(servlet_name, "plugin_ignore")) ignore = 1; cse_add_unique_location(pool, app, loc_prefix, loc_suffix, loc_is_exact, ignore);}/** * Add a url-pattern to the list of matching locations. * * @param app the containing application * @param pattern the url-pattern to match * * @return the new location */static voidcse_add_match_pattern(mem_pool_t *pool, web_app_t *app, char *pattern){ cse_add_location(pool, app, pattern, "plugin_match");}/** * Add a url-pattern to the list of matching locations. * * @param app the containing application * @param pattern the url-pattern to match * * @return the new location */static voidcse_add_ignore_pattern(mem_pool_t *pool, web_app_t *app, char *pattern){ cse_add_location(pool, app, pattern, "plugin_ignore");}/** * Adds a new backup to the configuration */cluster_srun_t *cse_add_host(mem_pool_t *pool, cluster_t *cluster, const char *hostname, int port){ return cse_add_cluster_server(pool, cluster, hostname, port, "", -1, 0, 0);}/** * Adds a new backup to the configuration */cluster_srun_t *cse_add_ssl(mem_pool_t *pool, cluster_t *cluster, const char *hostname, int port){ return cse_add_cluster_server(pool, cluster, hostname, port, "", -1, 0, 1);}/** * Adds a new backup to the configuration */cluster_srun_t *cse_add_backup(mem_pool_t *pool, cluster_t *cluster, const char *hostname, int port){ return cse_add_cluster_server(pool, cluster, hostname, port, "", -1, 1, 0);}/** * Logging for the configuration file. */voidcse_log_config(config_t *config){ resin_host_t *host; if (! config) return; host = config->hosts; for (; host; host = host->next) { web_app_t *app = host->applications; if (host != host->canonical) continue; for (; app; app = app->next) { location_t *loc = app->locations; for (; loc; loc = loc->next) { LOG(("%s:%d:cse_log_config(): cfg host:%s%s prefix:%s suffix:%s next:%x\n", __FILE__, __LINE__, host->name, app->context_path ? app->context_path : "/", loc->prefix ? loc->prefix : "null", loc->suffix ? loc->suffix : "null", loc->next)); } } }}/** * Matches the host information in the config */static resin_host_t *cse_create_host(config_t *config, const char *host_name, int port){ resin_host_t *host; mem_pool_t *pool = 0; for (host = config->hosts; host; host = host->next) { if (! strcmp(host_name, host->name) && host->port == port) return host; } host = (resin_host_t *) cse_alloc(config->p, sizeof(resin_host_t)); memset(host, 0, sizeof(resin_host_t)); host->config = config; host->canonical = host; host->name = cse_strdup(config->p, host_name); host->port = port; host->next = config->hosts; host->cluster.config = config; config->hosts = host; sprintf(host->config_source, "unconfigured"); pool = cse_create_pool(config); host->pool = pool; if (*host_name) { /* Initial configuration is an alias to the default host */ host->canonical = cse_create_host(config, "", 0); } return host;}static inthandle_config_header(config_t *config, char *header, char *value){ if (! strcmp(header, "check-interval")) { config->update_interval = resin_atoi(value); if (config->update_interval < 5) config->update_interval = 5; } else if (! strcmp(header, "cookie")) { int len = sizeof(config->session_cookie); strncpy(config->session_cookie, value, len); config->session_cookie[len - 1] = 0; } else if (! strcmp(header, "session-url-prefix")) { int len = sizeof(config->session_url_prefix); strncpy(config->session_url_prefix, value, len); config->session_url_prefix[len - 1] = 0; } else if (! strcmp(header, "alt-session-url-prefix")) { int len = sizeof(config->alt_session_url_prefix); strncpy(config->alt_session_url_prefix, value, len); config->alt_session_url_prefix[len - 1] = 0; } else if (! strcmp(header, "disable-sticky-sessions")) { int len = sizeof(config->session_cookie); strncpy(config->session_cookie, value, len); config->disable_sticky_sessions = strcmp(value, "0"); } return 1;}static intread_config(stream_t *s, config_t *config, resin_host_t *host, time_t now, int *p_is_change){ web_app_t *web_app = 0; int code; int ch; char buffer[1024]; char value[1024]; int is_change = 1; mem_pool_t *pool = 0; cluster_t cluster; int max_idle_time = -1; int fail_recover_time = -1; int read_timeout = -1; char error_page[1024]; char etag[sizeof(host->etag)]; int is_valid = 0; /* true if the request completed */ resin_host_t *old_canonical = host->canonical; memset(&cluster, 0, sizeof(cluster)); cluster.config = config; cluster.round_robin_index = -1; pool = cse_create_pool(config); strncpy(etag, host->etag, sizeof(etag)); etag[sizeof(etag) - 1] = 0; error_page[0] = 0; host->canonical = host; strcpy(host->error_message, "incomplete configuration"); LOG(("%s:%d:read_config(): hmux config %s:%d\n", __FILE__, __LINE__, host->name, host->port)); while (1) { code = cse_read_byte(s); switch (code) { case HMUX_DISPATCH_HOST: if (hmux_read_string(s, buffer, sizeof(buffer)) >= 0) { int p; int port = 0; int ch; LOG(("%s:%d:read_config(): hmux host %s\n", __FILE__, __LINE__, buffer)); for (p = 0; (ch = buffer[p]); p++) { if (ch == ':') { port = atoi(buffer + p + 1); buffer[p] = 0; break; } } if (strcmp(buffer, host->name) || host->port != port) { resin_host_t *canonical; canonical = cse_create_host(config, buffer, port); host->canonical = canonical; LOG(("%s:%d:read_config(); hmux set canonical %s:%d -> %s:%d\n", __FILE__, __LINE__, host->name, host->port, buffer, port)); } } break; case HMUX_DISPATCH_WEB_APP: if (hmux_read_string(s, buffer, sizeof(buffer)) >= 0) { LOG(("%s:%d:read_config(): hmux web-app %s\n", __FILE__, __LINE__, buffer)); web_app = cse_add_application(pool, host, web_app, buffer); cse_add_match_pattern(pool, web_app, "/WEB-INF/*"); cse_add_match_pattern(pool, web_app, "/META-INF/*"); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -