From 26e2bf146ed32bc205eb2b76cdc2974c75504c58 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 8 Sep 2009 11:09:50 +0200 Subject: [PATCH] Proxy per-server. Clean various fixed size bufs. --- src/http.c | 71 +++++++++++++++++++++++++++----------------------- src/http.h | 2 +- src/logic.c | 37 ++++++++++++++------------ src/pazpar2_config.c | 19 +++++++------- src/pazpar2_config.h | 3 ++- 5 files changed, 73 insertions(+), 59 deletions(-) diff --git a/src/http.c b/src/http.c index 69533c6..d40bd08 100644 --- a/src/http.c +++ b/src/http.c @@ -75,10 +75,6 @@ static struct http_channel *http_create(const char *addr, struct conf_server *server); static void http_destroy(IOCHAN i); -// If this is set, we proxy normal HTTP requests -static struct sockaddr_in *proxy_addr = 0; -static char proxy_url[256] = ""; -static char myurl[256] = ""; static struct http_buf *http_buf_freelist = 0; static struct http_channel *http_channel_freelist = 0; @@ -666,7 +662,8 @@ static struct http_buf *http_serialize_request(struct http_request *r) static int http_weshouldproxy(struct http_request *rq) { - if (proxy_addr && !strstr(rq->path, "search.pz2")) + struct http_channel *c = rq->channel; + if (c->server->proxy_addr && !strstr(rq->path, "search.pz2")) return 1; return 0; } @@ -734,7 +731,6 @@ static int http_proxy(struct http_request *rq) struct http_proxy *p = c->proxy; struct http_header *hp; struct http_buf *requestbuf; - char server_via[128] = ""; char server_port[16] = ""; struct conf_server *ser = c->server; @@ -756,8 +752,8 @@ static int http_proxy(struct http_request *rq) &one, sizeof(one)) < 0) abort(); enable_nonblock(sock); - if (connect(sock, (struct sockaddr *) proxy_addr, - sizeof(*proxy_addr)) < 0) + if (connect(sock, (struct sockaddr *) c->server->proxy_addr, + sizeof(*c->server->proxy_addr)) < 0) { if (!is_inprogress()) { @@ -786,6 +782,8 @@ static int http_proxy(struct http_request *rq) // Add new header about paraz2 version, host, remote client address, etc. { + char server_via[128]; + hp = rq->headers; hp = http_header_append(c, hp, "X-Pazpar2-Version", PACKAGE_VERSION); @@ -794,9 +792,10 @@ static int http_proxy(struct http_request *rq) sprintf(server_port, "%d", ser->port); hp = http_header_append(c, hp, "X-Pazpar2-Server-Port", server_port); - sprintf(server_via, "1.1 %s:%s (%s/%s)", - ser->host ? ser->host : "@", - server_port, PACKAGE_NAME, PACKAGE_VERSION); + yaz_snprintf(server_via, sizeof(server_via), + "1.1 %s:%s (%s/%s)", + ser->host ? ser->host : "@", + server_port, PACKAGE_NAME, PACKAGE_VERSION); hp = http_header_append(c, hp, "Via" , server_via); hp = http_header_append(c, hp, "X-Forwarded-For", c->addr); } @@ -1150,17 +1149,19 @@ int http_init(const char *addr, struct conf_server *server) pp = strchr(addr, ':'); if (pp) { - int len = pp - addr; - char hostname[128]; + WRBUF w = wrbuf_alloc(); struct hostent *he; - strncpy(hostname, addr, len); - hostname[len] = '\0'; - if (!(he = gethostbyname(hostname))){ - yaz_log(YLOG_FATAL, "Unable to resolve '%s'", hostname); + wrbuf_write(w, addr, pp - addr); + wrbuf_puts(w, ""); + + he = gethostbyname(wrbuf_cstr(w)); + wrbuf_destroy(w); + if (!he) + { + yaz_log(YLOG_FATAL, "Unable to resolve '%s'", addr); return 1; } - memcpy(&myaddr.sin_addr.s_addr, he->h_addr_list[0], he->h_length); port = atoi(pp + 1); } @@ -1213,32 +1214,38 @@ void http_close_server(void) } } -void http_set_proxyaddr(char *host, char *base_url) +void http_set_proxyaddr(const char *host, struct conf_server *server) { - char *p; + const char *p; short port; struct hostent *he; + WRBUF w = wrbuf_alloc(); + + yaz_log(YLOG_LOG, "HTTP backend %s", host); - strcpy(myurl, base_url); - strcpy(proxy_url, host); p = strchr(host, ':'); - yaz_log(YLOG_DEBUG, "Proxying for %s", host); - yaz_log(YLOG_LOG, "HTTP backend %s", proxy_url); - if (p) { + if (p) + { port = atoi(p + 1); - *p = '\0'; + wrbuf_write(w, host, p - host); + wrbuf_puts(w, ""); } else + { port = 80; - if (!(he = gethostbyname(host))) + wrbuf_puts(w, host); + } + if (!(he = gethostbyname(wrbuf_cstr(w)))) { - fprintf(stderr, "Failed to lookup '%s'\n", host); + fprintf(stderr, "Failed to lookup '%s'\n", wrbuf_cstr(w)); exit(1); } - proxy_addr = xmalloc(sizeof(struct sockaddr_in)); - proxy_addr->sin_family = he->h_addrtype; - memcpy(&proxy_addr->sin_addr.s_addr, he->h_addr_list[0], he->h_length); - proxy_addr->sin_port = htons(port); + wrbuf_destroy(w); + + server->proxy_addr = xmalloc(sizeof(struct sockaddr_in)); + server->proxy_addr->sin_family = he->h_addrtype; + memcpy(&server->proxy_addr->sin_addr.s_addr, he->h_addr_list[0], he->h_length); + server->proxy_addr->sin_port = htons(port); } static void http_fire_observers(struct http_channel *c) diff --git a/src/http.h b/src/http.h index df2c3c2..90f40c8 100644 --- a/src/http.h +++ b/src/http.h @@ -100,7 +100,7 @@ struct http_response char *content_type; }; -void http_set_proxyaddr(char *url, char *baseurl); +void http_set_proxyaddr(const char *url, struct conf_server *ser); int http_init(const char *addr, struct conf_server *ser); void http_close_server(void); void http_addheader(struct http_response *r, diff --git a/src/logic.c b/src/logic.c index e2155dd..3ea153f 100644 --- a/src/logic.c +++ b/src/logic.c @@ -874,41 +874,46 @@ int start_http_listener(struct conf_config *conf, struct conf_server *ser; for (ser = conf->servers; ser; ser = ser->next) { - char hp[128]; - *hp = '\0'; + WRBUF w = wrbuf_alloc(); + int r; if (listener_override) { - strcpy(hp, listener_override); + wrbuf_puts(w, listener_override); listener_override = 0; /* only first server is overriden */ } else { - strcpy(hp, ser->host ? ser->host : ""); + if (ser->host) + wrbuf_puts(w, ser->host); if (ser->port) { - if (*hp) - strcat(hp, ":"); - sprintf(hp + strlen(hp), "%d", ser->port); + if (wrbuf_len(w)) + wrbuf_puts(w, ":"); + wrbuf_printf(w, "%d", ser->port); } } - if (http_init(hp, ser)) + r = http_init(wrbuf_cstr(w), ser); + wrbuf_destroy(w); + if (r) return -1; - *hp = '\0'; + w = wrbuf_alloc(); if (proxy_override) - strcpy(hp, proxy_override); + wrbuf_puts(w, proxy_override); else if (ser->proxy_host || ser->proxy_port) { - strcpy(hp, ser->proxy_host ? ser->proxy_host : ""); + if (ser->proxy_host) + wrbuf_puts(w, ser->proxy_host); if (ser->proxy_port) { - if (*hp) - strcat(hp, ":"); - sprintf(hp + strlen(hp), "%d", ser->proxy_port); + if (wrbuf_len(w)) + wrbuf_puts(w, ":"); + wrbuf_printf(w, "%d", ser->proxy_port); } } - if (*hp) - http_set_proxyaddr(hp, ser->myurl ? ser->myurl : ""); + if (wrbuf_len(w)) + http_set_proxyaddr(wrbuf_cstr(w), ser); + wrbuf_destroy(w); } return 0; } diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index 05db1f6..668d907 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "pazpar2_config.h" #include "settings.h" -static char confdir[256] = "."; +static WRBUF confdir = 0; static char *parse_settings(NMEM nmem, xmlNode *node); @@ -453,8 +453,8 @@ static char *parse_settings(NMEM nmem, xmlNode *node) else { r = nmem_malloc(nmem, - strlen(confdir) + strlen((const char *) src) + 2); - sprintf(r, "%s/%s", confdir, src); + wrbuf_len(confdir) + strlen((const char *) src) + 2); + sprintf(r, "%s/%s", wrbuf_cstr(confdir), src); } } else @@ -476,6 +476,7 @@ static struct conf_server *parse_server(NMEM nmem, xmlNode *node) server->proxy_host = 0; server->proxy_port = 0; server->myurl = 0; + server->proxy_addr = 0; server->service = 0; server->next = 0; server->server_settings = 0; @@ -543,7 +544,7 @@ static struct conf_server *parse_server(NMEM nmem, xmlNode *node) } else if (!strcmp((const char *) n->name, "service")) { - const char *service_id = (const char *) + char *service_id = (char *) xmlGetProp(n, (xmlChar *) "id"); struct conf_service **sp = &server->service; @@ -576,6 +577,7 @@ static struct conf_server *parse_server(NMEM nmem, xmlNode *node) *sp = s; } } + xmlFree(service_id); } else { @@ -592,7 +594,7 @@ xsltStylesheet *conf_load_stylesheet(const char *fname) if (yaz_is_abspath(fname)) yaz_snprintf(path, sizeof(path), fname); else - yaz_snprintf(path, sizeof(path), "%s/%s", confdir, fname); + yaz_snprintf(path, sizeof(path), "%s/%s", wrbuf_cstr(confdir), fname); return xsltParseStylesheetFile((xmlChar *) path); } @@ -695,6 +697,7 @@ struct conf_config *read_config(const char *fname) yaz_log(YLOG_FATAL, "Failed to read %s", fname); exit(1); } + confdir = wrbuf_alloc(); if ((p = strrchr(fname, #ifdef WIN32 '\\' @@ -704,11 +707,9 @@ struct conf_config *read_config(const char *fname) ))) { int len = p - fname; - if (len >= sizeof(confdir)) - len = sizeof(confdir)-1; - strncpy(confdir, fname, len); - confdir[len] = '\0'; + wrbuf_write(confdir, fname, len); } + wrbuf_puts(confdir, ""); config = parse_config(xmlDocGetRootElement(doc)); xmlFreeDoc(doc); diff --git a/src/pazpar2_config.h b/src/pazpar2_config.h index 61166d8..d01be5e 100644 --- a/src/pazpar2_config.h +++ b/src/pazpar2_config.h @@ -148,12 +148,13 @@ struct conf_server char *proxy_host; int proxy_port; char *myurl; + struct sockaddr_in *proxy_addr; + char *server_settings; pp2_charset_t relevance_pct; pp2_charset_t sort_pct; pp2_charset_t mergekey_pct; - struct conf_service *service; struct conf_server *next; }; -- 1.7.10.4