From b09513bb2e56a4e3e32a5afa2e2aabdab30f1e87 Mon Sep 17 00:00:00 2001 From: "roberto@maverick64" Date: Mon, 17 Jan 2011 22:02:13 +0100 Subject: [PATCH] xml,ini and yaml file can taken via http automagically --- ini.c | 42 ++------------ utils.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ uwsgi.c | 2 +- uwsgi.h | 5 ++ xmlconf.c | 8 ++- yaml.c | 49 +++-------------- 6 files changed, 187 insertions(+), 79 deletions(-) diff --git a/ini.c b/ini.c index 34fb723d..d1f46ca2 100644 --- a/ini.c +++ b/ini.c @@ -73,10 +73,8 @@ char *ini_get_line(char *ini, off_t size) { void uwsgi_ini_config(char *file) { - int fd; - ssize_t len; + int len = 0; char *ini; - struct stat sb; char *ini_line; @@ -90,7 +88,7 @@ void uwsgi_ini_config(char *file) { char *section_asked = "uwsgi"; char *colon; - colon = strchr(file, ':'); + colon = uwsgi_get_last_char(file, ':'); if (colon) { colon[0] = 0; if (colon[1] != 0) { @@ -100,36 +98,10 @@ void uwsgi_ini_config(char *file) { uwsgi_log("[uWSGI] getting INI configuration from %s\n", file); - fd = open(file, O_RDONLY); - if (fd < 0) { - uwsgi_error("open()"); - exit(1); - } + ini = uwsgi_open_and_read(file, &len, 1); - if (fstat(fd, &sb)) { - uwsgi_error("fstat()"); - exit(1); - } - - - ini = malloc(sb.st_size+1); - - if (!ini) { - uwsgi_error("malloc()"); - exit(1); - } - - - len = read(fd, ini, sb.st_size); - if (len != sb.st_size) { - uwsgi_error("read()"); - exit(1); - } - - ini[sb.st_size] = 0; - - while(sb.st_size) { - ini_line = ini_get_line(ini, sb.st_size); + while(len) { + ini_line = ini_get_line(ini, len); if (ini_line == NULL) { break; } @@ -174,13 +146,11 @@ void uwsgi_ini_config(char *file) { } - sb.st_size -= (ini_line - ini); + len -= (ini_line - ini); ini += (ini_line - ini); } - close(fd); - } #endif diff --git a/utils.c b/utils.c index 1a28df2d..a6cadb5a 100644 --- a/utils.c +++ b/utils.c @@ -1243,3 +1243,163 @@ char *uwsgi_cheap_string(char *buf, int len) { return buf-1; } + +char *uwsgi_open_and_read(char *url, int *size, int add_zero) { + + int fd; + struct stat sb; + char *buffer = NULL; + char byte; + ssize_t len; + char *uri, *colon; + char *domain ; + char *ip ; + struct hostent *he; + int body = 0; + + // http url ? + if (!strncmp("http://", url, 7)) { + domain = url+7; + uri = strchr(domain, '/'); + if (!uri) { + uwsgi_log("invalid http url\n"); + exit(1); + } + uri[0] = 0; + uwsgi_log("domain: %s\n", domain); + + colon = uwsgi_get_last_char(domain, ':'); + + if (colon) { + colon[0] = 0; + } + + + he = gethostbyname(domain); + if (!he || !*he->h_addr_list || he->h_addrtype != AF_INET) { + uwsgi_log("unable to resolve address %s\n", domain); + exit(1); + } + + ip = inet_ntoa( *( struct in_addr*) he->h_addr_list[0]); + if (!ip) { + uwsgi_log("unable to resolve address %s\n", domain); + exit(1); + } + + if (colon) { + colon[0] = ':'; + ip = uwsgi_concat2(ip, colon); + } + else { + ip = uwsgi_concat2(ip, ":80"); + } + + fd = uwsgi_connect(ip, 0, 0); + + if (fd < 0) { + exit(1); + } + + uri[0] = '/'; + + len = write(fd, "GET ", 4); + len = write(fd, uri, strlen(uri)); + len = write(fd, " HTTP/1.0\r\n", 11 ); + len = write(fd, "Host: ", 6); + + uri[0] = 0; + len = write(fd, domain, strlen(domain)); + uri[0] = '/'; + + len = write(fd, "\r\n\r\n", 4); + + while( read(fd, &byte, 1) == 1) { + if (byte == '\r' && body == 0) { + body = 1; + } + else if (byte == '\n' && body == 1) { + body = 2; + } + else if (byte == '\r' && body == 2) { + body = 3; + } + else if (byte == '\n' && body == 3) { + body = 4; + } + else if (body == 4) { + *size = *size+1; + buffer = realloc(buffer, *size); + if (!buffer) { + uwsgi_error("realloc()"); + exit(1); + } + buffer[*size-1] = byte; + } + else { + body = 0; + } + } + + close(fd); + + if (add_zero) { + *size = *size + 1; + buffer = realloc(buffer, *size); + buffer[*size] = 0; + } + + } + // fallback to file + else { + fd = open(url, O_RDONLY); + if (fd < 0) { + uwsgi_error("open()"); + exit(1); + } + + if (fstat(fd, &sb)) { + uwsgi_error("fstat()"); + exit(1); + } + + + buffer = malloc(sb.st_size+add_zero); + + if (!buffer) { + uwsgi_error("malloc()"); + exit(1); + } + + + len = read(fd, buffer, sb.st_size); + if (len != sb.st_size) { + uwsgi_error("read()"); + exit(1); + } + + close(fd); + + *size = sb.st_size+add_zero; + + if (add_zero) + buffer[sb.st_size] = 0; + } + + return buffer; +} + +char *uwsgi_get_last_char(char *what, char c) { + int i,j=0; + char *ptr = NULL; + + if (!strncmp("http://", what, 7)) j = 7; + + for(i=j;i<(int)strlen(what);i++) { + if (what[i] == c) { + ptr = what+i; + } + } + + return ptr; +} diff --git a/uwsgi.c b/uwsgi.c index 47efe1b2..8f3b9dcd 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -1208,7 +1208,7 @@ int uwsgi_start(void *v_argv) { } - // put listening socket i non-blocking state + // put listening socket in non-blocking state for (i = 0; i < uwsgi.sockets_cnt; i++) { uwsgi.sockets[i].arg = fcntl(uwsgi.sockets[i].fd, F_GETFL, NULL); if (uwsgi.sockets[i].arg < 0) { diff --git a/uwsgi.h b/uwsgi.h index 74951a9c..858a9f23 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -65,6 +65,8 @@ #include #include #include +#include + #include #include #include @@ -1375,3 +1377,6 @@ void log_syslog(char *); struct uwsgi_gateway *register_gateway(char *, void (*)(void)); void gateway_respawn(int); + +char *uwsgi_open_and_read(char *, int *, int); +char *uwsgi_get_last_char(char *, char); diff --git a/xmlconf.c b/xmlconf.c index a2916385..bdb7eae8 100644 --- a/xmlconf.c +++ b/xmlconf.c @@ -24,8 +24,10 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag) { char *xml_id; int i; + char *xml_content; + int xml_size = 0; - colon = strchr(uwsgi.xml_config, ':'); + colon = uwsgi_get_last_char(uwsgi.xml_config, ':'); if (colon) { colon[0] = 0; colon++; @@ -36,7 +38,9 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag) { uwsgi_log( "[uWSGI] using xml uwsgi id: %s\n", colon); } - doc = xmlReadFile(uwsgi.xml_config, NULL, 0); + xml_content = uwsgi_open_and_read(uwsgi.xml_config, &xml_size, 0); + + doc = xmlReadMemory(xml_content, xml_size, uwsgi.xml_config, NULL, 0); if (doc == NULL) { uwsgi_log( "[uWSGI] could not parse file %s.\n", uwsgi.xml_config); exit(1); diff --git a/yaml.c b/yaml.c index 26afb86e..6ac3a344 100644 --- a/yaml.c +++ b/yaml.c @@ -86,10 +86,8 @@ char *yaml_get_line(char *yaml, off_t size) { void uwsgi_yaml_config(char *file) { - int fd; - ssize_t len; + int len = 0; char *yaml; - struct stat sb; int depth; int current_depth = 0; @@ -107,7 +105,7 @@ void uwsgi_yaml_config(char *file) { char *section_asked = "uwsgi"; char *colon; - colon = strchr(file, ':'); + colon = uwsgi_get_last_char(file, ':'); if (colon) { colon[0] = 0; if (colon[1] != 0) { @@ -117,36 +115,10 @@ void uwsgi_yaml_config(char *file) { uwsgi_log("[uWSGI] getting YAML configuration from %s\n", file); - fd = open(file, O_RDONLY); - if (fd < 0) { - uwsgi_error("open()"); - exit(1); - } + yaml = uwsgi_open_and_read(file, &len, 1); - if (fstat(fd, &sb)) { - uwsgi_error("fstat()"); - exit(1); - } - - - yaml = malloc(sb.st_size+1); - - if (!yaml) { - uwsgi_error("malloc()"); - exit(1); - } - - - len = read(fd, yaml, sb.st_size); - if (len != sb.st_size) { - uwsgi_error("read()"); - exit(1); - } - - yaml[sb.st_size] = 0; - - while(sb.st_size) { - yaml_line = yaml_get_line(yaml, sb.st_size); + while(len) { + yaml_line = yaml_get_line(yaml, len); if (yaml_line == NULL) { break; } @@ -158,7 +130,7 @@ void uwsgi_yaml_config(char *file) { if (depth <= current_depth) { current_depth = depth; // end the parsing cycle - if (in_uwsgi_section) goto end; + if (in_uwsgi_section) return; } else if (depth > current_depth && !in_uwsgi_section) { goto next; @@ -170,7 +142,7 @@ void uwsgi_yaml_config(char *file) { // skip list and {} defined dict if (key[0] == '-' || key[0] == '[' || key[0] == '{') { - if (in_uwsgi_section) goto end; + if (in_uwsgi_section) return; goto next; } @@ -188,7 +160,7 @@ void uwsgi_yaml_config(char *file) { if (!val) { val = strstr(key, ":\t"); } - if (!val) goto end; + if (!val) return; // get the right key val[0] = 0; // yeah overengeneering.... @@ -216,14 +188,11 @@ void uwsgi_yaml_config(char *file) { } } next: - sb.st_size -= (yaml_line - yaml); + len -= (yaml_line - yaml); yaml += (yaml_line - yaml); } -end: - - close(fd); }