Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/pazpar2
[pazpar2-moved-to-github.git] / src / http_command.c
index 32c1dcb..e9d1ff8 100644 (file)
@@ -33,8 +33,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/snprintf.h>
 #include <yaz/yaz-util.h>
 
-#include "util.h"
 #include "eventl.h"
+#include "parameters.h"
 #include "pazpar2.h"
 #include "http.h"
 #include "settings.h"
@@ -207,7 +207,7 @@ static struct http_session *locate_session(struct http_request *rq, struct http_
 // Decode settings parameters and apply to session
 // Syntax: setting[target]=value
 static int process_settings(struct session *se, struct http_request *rq,
-        struct http_response *rs)
+                            struct http_response *rs)
 {
     struct http_argument *a;
 
@@ -242,26 +242,54 @@ static void cmd_exit(struct http_channel *c)
 
 static void cmd_init(struct http_channel *c)
 {
-    unsigned int sesid;
     char buf[1024];
-    const char *clear = http_argbyname(c->request, "clear");
-    const char *service_name = http_argbyname(c->request, "service");
-    struct conf_service *service = locate_service(c->server,
-                                                  service_name);
-    struct http_session *s = http_session_create(service);
+    struct http_request *r = c->request;
+    const char *clear = http_argbyname(r, "clear");
+    const char *content_type = http_lookup_header(r->headers, "Content-Type");
+    unsigned int sesid;
+    struct http_session *s;
     struct http_response *rs = c->response;
-
+    struct conf_service *service = 0; /* no service (yet) */
+    
+    if (r->content_len && content_type && 
+        !yaz_strcmp_del("text/xml", content_type, "; "))
+    {
+        xmlDoc *doc = xmlParseMemory(r->content_buf, r->content_len);
+        xmlNode *root_n;
+        if (!doc)
+        {
+            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
+            return;
+        }
+        root_n = xmlDocGetRootElement(doc);
+        service = service_create(c->server, root_n);
+        xmlFreeDoc(doc);
+        if (!service)
+        {
+            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
+            return;
+        }
+    }
+    
     if (!service)
     {
-        error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "service");
-        return;
+        const char *service_name = http_argbyname(c->request, "service");
+        service = locate_service(c->server, service_name);
+        if (!service)
+        {
+            error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "service");
+            return;
+        }
+        service_incref(service);
     }
-
+    s = http_session_create(service);
+    
     yaz_log(YLOG_DEBUG, "HTTP Session init");
     if (!clear || *clear == '0')
         session_init_databases(s->psession);
     else
         yaz_log(YLOG_LOG, "No databases preloaded");
+    
     sesid = make_sessionid();
     s->session_id = sesid;
     if (process_settings(s->psession, c->request, c->response) < 0)
@@ -272,15 +300,42 @@ static void cmd_init(struct http_channel *c)
     http_send_response(c);
 }
 
+static void apply_local_setting(void *client_data,
+                                struct setting *set)
+{
+    struct session *se =  (struct session *) client_data;
+
+    session_apply_setting(se, nmem_strdup(se->session_nmem, set->target),
+                          nmem_strdup(se->session_nmem, set->name),
+                          nmem_strdup(se->session_nmem, set->value));
+}
+
 static void cmd_settings(struct http_channel *c)
 {
     struct http_response *rs = c->response;
     struct http_request *rq = c->request;
     struct http_session *s = locate_session(rq, rs);
+    const char *content_type = http_lookup_header(rq->headers, "Content-Type");
 
     if (!s)
         return;
 
+    if (rq->content_len && content_type && 
+        !yaz_strcmp_del("text/xml", content_type, "; "))
+    {
+        xmlDoc *doc = xmlParseMemory(rq->content_buf, rq->content_len);
+        xmlNode *root_n;
+        if (!doc)
+        {
+            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
+            return;
+        }
+        root_n = xmlDocGetRootElement(doc);
+
+        settings_read_node_x(root_n, s->psession, apply_local_setting);
+
+        xmlFreeDoc(doc);
+    }
     if (process_settings(s->psession, rq, rs) < 0)
         return;
     rs->payload = "<settings><status>OK</status></settings>";