📄 config.c
字号:
case HMUX_WEB_APP_UNAVAILABLE: cse_skip(s, hmux_read_len(s)); LOG(("%s:%d:read_config(): web-app unavailable\n", __FILE__, __LINE__)); if (web_app) web_app->has_data = 0; break; case HMUX_DISPATCH_MATCH: if (hmux_read_string(s, buffer, sizeof(buffer)) > 0) { LOG(("%s:%d:read_config(): hmux match %s\n", __FILE__, __LINE__, buffer)); cse_add_match_pattern(pool, web_app, buffer); } break; case HMUX_DISPATCH_IGNORE: if (hmux_read_string(s, buffer, sizeof(buffer)) > 0) { LOG(("%s:%d:read_config(): hmux ignore %s\n", __FILE__, __LINE__, buffer)); cse_add_ignore_pattern(pool, web_app, buffer); } break; case HMUX_DISPATCH_ETAG: hmux_read_string(s, etag, sizeof(etag)); LOG(("%s:%d:read_config(): hmux etag %s\n", __FILE__, __LINE__, etag)); is_valid = 1; break; case HMUX_UNAVAILABLE: cse_skip(s, hmux_read_len(s)); strcpy(host->error_message, "host unavailable/busy"); is_change = 0; is_valid = 0; LOG(("%s:%d:read_config(): host unavailable\n", __FILE__, __LINE__)); if (! host->has_data) { char buf[128]; buf[0] = 0;#ifndef WIN32 ctime_r(&host->last_update, buf);#else strcpy(buf, ctime(&host->last_update));#endif sprintf(host->config_source, "Unavailable (%s)", buf); } break; case HMUX_DISPATCH_NO_CHANGE: cse_skip(s, hmux_read_len(s)); LOG(("%s:%d:read_config(); hmux no-change %s\n", __FILE__, __LINE__, host->etag)); { char buf[128]; buf[0] = 0;#ifndef WIN32 ctime_r(&host->last_update, buf);#else strcpy(buf, ctime(&host->last_update));#endif sprintf(host->config_source, "Resin-ETag (%s)", buf); } is_change = 0; is_valid = 1; break; case HMUX_HEADER: hmux_read_string(s, buffer, sizeof(buffer)); ch = cse_read_byte(s); hmux_read_string(s, value, sizeof(value)); LOG(("%s:%d:read_config(): hmux header %s: %s\n", __FILE__, __LINE__, buffer, value)); if (ch == HMUX_STRING) { if (! strcmp(buffer, "connection-error-page")) { int len = sizeof(host->config->error_page); strncpy(host->config->error_page, value, len); host->config->error_page[len - 1] = 0; } else if (! strcmp(buffer, "live-time")) max_idle_time = resin_atoi(value); else if (! strcmp(buffer, "dead-time")) fail_recover_time = resin_atoi(value); else if (! strcmp(buffer, "read-timeout")) read_timeout = resin_atoi(value); else if (! strcmp(buffer, "last-update")) { int last_update = resin_atoi(value); /* If server started after the file, don't update time. */ if (host && host->config->start_time < last_update) { host->last_update = last_update; } } else handle_config_header(config, buffer, value); } break; case HMUX_CLUSTER: hmux_read_string(s, buffer, sizeof(buffer)); LOG(("%s:%d:read_config(): hmux cluster %s\n", __FILE__, __LINE__, buffer)); break; case HMUX_SRUN: case HMUX_SRUN_BACKUP: { char *p; hmux_read_string(s, buffer, sizeof(buffer)); LOG(("%s:%d:read_config(): hmux srun %s\n", __FILE__, __LINE__, buffer)); p = strchr(buffer, ':'); if (p) { char *host = buffer; int port = 0; cluster_srun_t *srun; *p = 0; for (p++; *p; p++) { if (*p >= '0' && *p <= '9') port = 10 * port + *p - '0'; } if (code == HMUX_SRUN_BACKUP) srun = cse_add_backup(pool, &cluster, host, port); else if (code == HMUX_SRUN_SSL) srun = cse_add_ssl(pool, &cluster, host, port); else srun = cse_add_host(pool, &cluster, host, port); if (! srun || ! srun->srun) { ERR(("srun value for host %s cannot be resolved")); } else { if (max_idle_time > 0) srun->srun->live_time = max_idle_time; if (fail_recover_time > 0) srun->srun->dead_time = fail_recover_time; if (read_timeout > 0) srun->srun->read_timeout = read_timeout; } } } break; case HMUX_EXIT: case HMUX_QUIT: if (! is_valid) { ERR(("%s:%d:read_config(): host %s:%d exit without valid data\n", __FILE__, __LINE__, host->name, host->port, etag)); is_change = 0; *p_is_change = is_change; host->canonical = old_canonical; host->last_update = 0; if (pool) cse_free_pool(pool); return -1; } host->error_message[0] = 0; if (is_change > 0) { mem_pool_t *old_pool = host->pool; g_update_count++; host->applications = web_app; host->pool = pool; memcpy(&host->cluster, &cluster, sizeof(cluster)); if (old_pool) cse_free_pool(old_pool); strncpy(host->etag, etag, sizeof(etag)); host->has_data = 1; ERR(("%s:%d:read_config(): updated host %s:%d etag=%s\n", __FILE__, __LINE__, host->name, host->port, etag)); } else { host->canonical = old_canonical; if (pool) cse_free_pool(pool); ERR(("%s:%d:read_config(): no change for host %s:%d etag=%s\n", __FILE__, __LINE__, host->name, host->port, etag)); } *p_is_change = is_change; return code; default: ERR(("%s:%d:read_config(): hmux unknown %d\n", __FILE__, __LINE__, code)); host->canonical = old_canonical; host->last_update = 0; sprintf(host->error_message, "%s:%d:read_config(): hmux unknown %d\n", __FILE__, __LINE__, code); if (pool) cse_free_pool(pool); is_change = 0; *p_is_change = is_change; return -1; } }}static voidwrite_config(config_t *config){ stream_t s; resin_host_t *host; int fd; char temp[1024]; char buffer[1024]; char *tail; if (! *config->config_path) return; ERR(("%s:%d:write_config(): writing cached config\n", __FILE__, __LINE__)); strncpy(temp, config->config_path, sizeof(temp)); tail = strrchr(temp, '/'); if (! tail) tail = strrchr(temp, '\\'); if (tail) *tail = 0;#ifdef WIN32 tail = tempnam("c:/temp", "resin-"); if (tail) { strcpy(temp, tail); fd = open(tail, O_WRONLY|O_CREAT|O_TRUNC, 0664); } else fd = -1;#else strcat(temp, "/resintmp-XXXXXX"); fd = mkstemp(temp);#endif if (fd < 0) return; memset(&s, 0, sizeof(s)); s.socket = fd; sprintf(buffer, "%d", config->update_interval); hmux_write_string(&s, HMUX_HEADER, "check-interval"); hmux_write_string(&s, HMUX_STRING, buffer); if (*config->session_cookie) { hmux_write_string(&s, HMUX_HEADER, "cookie"); hmux_write_string(&s, HMUX_STRING, config->session_cookie); } if (*config->session_url_prefix) { hmux_write_string(&s, HMUX_HEADER, "session-url-prefix"); hmux_write_string(&s, HMUX_STRING, config->session_url_prefix); } if (*config->alt_session_url_prefix) { hmux_write_string(&s, HMUX_HEADER, "alt-session-url-prefix"); hmux_write_string(&s, HMUX_STRING, config->alt_session_url_prefix); } if (config->disable_sticky_sessions) { hmux_write_string(&s, HMUX_HEADER, "disable-sticky-sessions"); hmux_write_string(&s, HMUX_STRING, "1"); } for (host = config->hosts; host; host = host->next) { web_app_t *web_app; int i; if (host->port) { sprintf(buffer, "%s:%d", host->name, host->port); hmux_write_string(&s, HMUX_DISPATCH_HOST, buffer); } else hmux_write_string(&s, HMUX_DISPATCH_HOST, host->name); sprintf(buffer, "%d", (int) host->last_update); hmux_write_string(&s, HMUX_HEADER, "last-update"); hmux_write_string(&s, HMUX_STRING, buffer); ERR(("%s:%d:write_config(): update %s:%d -> %d\n", __FILE__, __LINE__, host->name, host->port, host->last_update)); if (host->canonical && host->canonical != host) { if (host->canonical->port) { sprintf(buffer, "%s:%d", host->canonical->name, host->canonical->port); hmux_write_string(&s, HMUX_DISPATCH_HOST, buffer); } else hmux_write_string(&s, HMUX_DISPATCH_HOST, host->canonical->name); } for (web_app = host->applications; web_app; web_app = web_app->next) { location_t *loc; hmux_write_string(&s, HMUX_DISPATCH_WEB_APP, web_app->context_path); for (loc = web_app->locations; loc; loc = loc->next) { int code = loc->ignore ? HMUX_DISPATCH_IGNORE : HMUX_DISPATCH_MATCH; if (loc->is_exact) hmux_write_string(&s, code, loc->prefix); else if (loc->suffix) { sprintf(buffer, "*%s", loc->suffix); hmux_write_string(&s, code, buffer); } else if (loc->prefix) { sprintf(buffer, "%s/*", loc->prefix); hmux_write_string(&s, code, buffer); } } } cse_write_string(&s, HMUX_CLUSTER, ""); for (i = 0; i < host->cluster.srun_size; i++) { cluster_srun_t *srun; int code; srun = &host->cluster.srun_list[i]; if (! srun || ! srun->srun || ! srun->srun->hostname) continue; sprintf(buffer, "%d", srun->srun->live_time); hmux_write_string(&s, HMUX_HEADER, "live-time"); hmux_write_string(&s, HMUX_STRING, buffer); sprintf(buffer, "%d", srun->srun->dead_time); hmux_write_string(&s, HMUX_HEADER, "dead-time"); hmux_write_string(&s, HMUX_STRING, buffer); sprintf(buffer, "%d", srun->srun->read_timeout); hmux_write_string(&s, HMUX_HEADER, "read-timeout"); hmux_write_string(&s, HMUX_STRING, buffer); code = srun->is_backup ? HMUX_SRUN_BACKUP : HMUX_SRUN; if (srun->srun->port) { sprintf(buffer, "%s:%d", srun->srun->hostname, srun->srun->port); hmux_write_string(&s, code, buffer); } else { hmux_write_string(&s, code, srun->srun->hostname); } } cse_write_string(&s, HMUX_DISPATCH_ETAG, host->etag); cse_write_byte(&s, HMUX_QUIT); } cse_write_byte(&s, HMUX_EXIT); cse_flush(&s); close(fd);#ifdef WIN32 unlink(temp);#endif rename(temp, config->config_path); unlink(temp);}static intread_all_config_impl(config_t *config){ stream_t s; resin_host_t *host; int fd; char buffer[1024]; char value[1024]; int code; int ch; struct stat st; int mtime = time(0); if (! *config->config_path) return 0; fd = open(config->config_path, O_RDONLY); if (fd < 0) return 0; if (fstat(fd, &st) == 0) { mtime = st.st_mtime; config->last_file_update = mtime; } memset(&s, 0, sizeof(s)); s.socket = fd; while ((code = cse_read_byte(&s)) >= 0) { switch (code) { case HMUX_DISPATCH_HOST: { int p; int port = 0; int ch; int is_change = 0; hmux_read_string(&s, buffer, sizeof(buffer)); LOG(("%s:%d:read_all_config_impl(): 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; } } host = cse_create_host(config, buffer, port); if (read_config(&s, config, host, 0, &is_change) > 0) { char buf[128]; time_t time = host->last_update; buf[0] = 0;#ifndef WIN32 ctime_r(&time, buf);#else strcpy(buf, ctime(&time));#endif sprintf(host->config_source, "Cache File (%s, %s)", config->config_path, buf); } } break; case HMUX_HEADER: hmux_read_string(&s, buffer, sizeof(buffer)); ch = cse_read_byte(&s); hmux_read_string(&s, value, sizeof(value)); if (ch == HMUX_STRING) { LOG(("%s:%d:read_all_config_impl(): hmux header %s: %s\n", __FILE__, __LINE__, buffer, value)); handle_config_header(config, buffer, value); } break; default: hmux_read_string(&s, value, sizeof(value)); LOG(("%s:%d:read_all_config_impl(): hmux value %c: %s\n", __FILE__, __LINE__, code, buffer)); break; } } close(fd); return 1;}static voidread_all_config(config_t *config){ if (! read_all_config_impl(config)) { /* match all to ensure will not show source if can't connect. */ resin_host_t *host = 0; time_t now = 0; host = cse_match_host_impl(config, "", 0, now); }}voidreread_config(config_t *config){ LOG(("%s:%d:reread_config(): forcing read()\n", __FILE__, __LINE__)); read_all_config(config);}static intcse_update_host_from_resin(resin_host_t *host, time_t now){ stream_t s; char *uri = ""; if (cse_open_live_connection(&s, &host->config->config_cluster, now)) { int code; int len; int is_change; time_t prev_update; prev_update = host->last_update; host->last_update = now; hmux_start_channel(&s, 1); hmux_write_int(&s, HMUX_PROTOCOL, HMUX_DISPATCH_PROTOCOL); if (host->etag[0]) hmux_write_string(&s, HMUX_DISPATCH_ETAG, host->etag); hmux_write_string(&s, HMUX_DISPATCH_HOST, host->name); hmux_write_string(&s, HMUX_DISPATCH_QUERY, uri); hmux_write_close(&s); code = cse_read_byte(&s); if (code != HMUX_CHANNEL) { host->last_update = prev_update; cse_close(&s, "protocol"); return 0; } len = hmux_read_len(&s); if (read_config(&s, host->config, host, now, &is_change) == HMUX_QUIT) { cse_recycle(&s, now); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -