Fix Metaproxy stops logging after check config failed MP-590
[metaproxy-moved-to-github.git] / src / filter_http_client.cpp
index cba6f48..b8c2015 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of Metaproxy.
-   Copyright (C) 2005-2013 Index Data
+   Copyright (C) Index Data
 
 Metaproxy 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
@@ -50,10 +50,21 @@ namespace metaproxy_1 {
             void proxy(mp::Package &package);
             std::string proxy_host;
             std::string default_host;
+            int max_redirects;
+            bool x_forwarded_for;
+            bool bind_host;
+            Rep();
         };
     }
 }
 
+yf::HTTPClient::Rep::Rep()
+{
+    max_redirects = 0;
+    x_forwarded_for = false;
+    bind_host = false;
+}
+
 yf::HTTPClient::HTTPClient() : m_p(new Rep)
 {
 }
@@ -71,19 +82,48 @@ void yf::HTTPClient::Rep::proxy(mp::Package &package)
         Z_GDU *res_gdu = 0;
         mp::odr o;
         yaz_url_t yaz_url = yaz_url_create();
-        const char *h = strchr(hreq->path, '/');
-        std::string uri;
+        const char *http_proxy =
+            z_HTTP_header_remove(&hreq->headers, "X-Metaproxy-Proxy");
 
-        if (proxy_host.length())
-            yaz_url_set_proxy(yaz_url, proxy_host.c_str());
+        if (!http_proxy)
+            http_proxy = proxy_host.c_str();
 
-        if (h > hreq->path+1 && !memcmp(h-1, "://", 3))
-            uri = hreq->path; /* we have a host already */
-        else
+        if (*http_proxy)
+            yaz_url_set_proxy(yaz_url, http_proxy);
+
+        yaz_url_set_max_redirects(yaz_url, max_redirects);
+
+        if (x_forwarded_for)
+        {
+            std::string peer_name2 = package.origin().get_address();
+            const char *peer_name1 =
+                z_HTTP_header_lookup(hreq->headers, "X-Forwarded-For");
+            std::string pcomb;
+            if (peer_name1)
+            {
+                pcomb.append(peer_name1);
+                pcomb.append(", ");
+            }
+            pcomb.append(peer_name2);
+            z_HTTP_header_set(o, &hreq->headers, "X-Forwarded-For",
+                              pcomb.c_str());
+        }
+        std::string uri;
+        if (hreq->path[0] == '/')
         {
             if (default_host.length())
                 uri = default_host + hreq->path;
         }
+        else
+            uri = hreq->path;
+
+
+        if (bind_host)
+        {
+            std::string host = package.origin().get_bind_address();
+            uri.append(" ");
+            uri.append(host);
+        }
         Z_HTTP_Response *http_response = 0;
         if (uri.length())
             http_response =
@@ -93,11 +133,15 @@ void yf::HTTPClient::Rep::proxy(mp::Package &package)
         if (http_response)
         {
             res_gdu = o.create_HTTP_Response(package.session(), hreq, 200);
+            z_HTTP_header_remove(&http_response->headers, "Transfer-Encoding");
             res_gdu->u.HTTP_Response = http_response;
         }
         else
         {
-            res_gdu = o.create_HTTP_Response(package.session(), hreq, 404);
+            res_gdu = o.create_HTTP_Response_details(
+                package.session(),
+                hreq, 502,
+                yaz_url_get_error(yaz_url));
         }
         package.response() = res_gdu;
         yaz_url_destroy(yaz_url);
@@ -126,6 +170,10 @@ void mp::filter::HTTPClient::configure(const xmlNode * ptr, bool test_only,
         {
             m_p->proxy_host = mp::xml::get_text(ptr);
         }
+        else if (!strcmp((const char *) ptr->name, "max-redirects"))
+        {
+            m_p->max_redirects = mp::xml::get_int(ptr, 0);
+        }
         else if (!strcmp((const char *) ptr->name, "default-host"))
         {
             m_p->default_host = mp::xml::get_text(ptr);
@@ -136,6 +184,14 @@ void mp::filter::HTTPClient::configure(const xmlNode * ptr, bool test_only,
                      " in http_client filter");
             }
         }
+        else if (!strcmp((const char *) ptr->name, "x-forwarded-for"))
+        {
+            m_p->x_forwarded_for = mp::xml::get_bool(ptr, 0);
+        }
+        else if (!strcmp((const char *) ptr->name, "bind_host"))
+        {
+            m_p->bind_host = mp::xml::get_bool(ptr, 0);
+        }
         else
         {
             throw mp::filter::FilterException