New service setting: ccldirective
[pazpar2-moved-to-github.git] / src / http_command.c
index 27edb18..c92c7c3 100644 (file)
@@ -93,6 +93,16 @@ struct http_sessions {
 static YAZ_MUTEX g_http_session_mutex = 0;
 static int g_http_sessions = 0;
 
+int get_version(struct http_request *rq) {
+    const char *version = http_argbyname(rq, "version");
+    int version_no = 0;
+    if (version && strcmp(version, "")) {
+        version_no = atoi(version);
+    }
+    return version_no;
+}
+
+
 int http_session_use(int delta)
 {
     int sessions;
@@ -460,6 +470,8 @@ static void cmd_init(struct http_channel *c)
     wrbuf_puts(c->wrbuf, "</session>"
                "<protocol>" PAZPAR2_PROTOCOL_VERSION "</protocol>");
     
+    wrbuf_printf(c->wrbuf, "<keepAlive>%d</keepAlive>\n", 1000 * ((s->psession->service->session_timeout >= 20) ?
+                                                                  (s->psession->service->session_timeout - 10) : 50));
     response_close(c, "init");
 }
 
@@ -488,6 +500,7 @@ static void cmd_settings(struct http_channel *c)
     {
         xmlDoc *doc = xmlParseMemory(rq->content_buf, rq->content_len);
         xmlNode *root_n;
+        int ret;
         if (!doc)
         {
             error(rs, PAZPAR2_MALFORMED_SETTING, 0);
@@ -495,10 +508,14 @@ static void cmd_settings(struct http_channel *c)
             return;
         }
         root_n = xmlDocGetRootElement(doc);
-
-        settings_read_node_x(root_n, s->psession, apply_local_setting);
-
+        ret = settings_read_node_x(root_n, s->psession, apply_local_setting);
         xmlFreeDoc(doc);
+        if (ret)
+        {
+            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
+            release_session(c,s);
+            return;
+        }            
     }
     if (process_settings(s->psession, rq, rs) < 0)
     {
@@ -513,8 +530,9 @@ static void cmd_settings(struct http_channel *c)
 static void termlist_response(struct http_channel *c, struct http_session *s, const char *cmd_status)
 {
     struct http_request *rq = c->request;
-    const char *name = http_argbyname(rq, "name");
-    const char *nums = http_argbyname(rq, "num");
+    const char *name    = http_argbyname(rq, "name");
+    const char *nums    = http_argbyname(rq, "num");
+    int version = get_version(rq);
     int num = 15;
     int status;
 
@@ -530,7 +548,7 @@ static void termlist_response(struct http_channel *c, struct http_session *s, co
     }
     wrbuf_printf(c->wrbuf, "<activeclients>%d</activeclients>\n", status);
 
-    perform_termlist(c, s->psession, name, num);
+    perform_termlist(c, s->psession, name, num, version);
 
     response_close(c, "termlist");
 }
@@ -676,11 +694,7 @@ static void bytarget_response(struct http_channel *c, struct http_session *s, co
     struct hitsbytarget *ht;
     struct http_request *rq = c->request;
     const char *settings = http_argbyname(rq, "settings");
-    const char *protocol_version = http_argbyname(rq, "version");
-    int version = 0;
-    if (protocol_version && strcmp(protocol_version,"")) {
-        version = atoi(protocol_version);
-    }
+    int version = get_version(rq);
     ht = get_hitsbytarget(s->psession, &count, c->nmem);
     if (!cmd_status)
         /* Old protocol, always ok */
@@ -719,8 +733,10 @@ static void bytarget_response(struct http_channel *c, struct http_session *s, co
         }
 
         wrbuf_printf(c->wrbuf, "<records>%d</records>\n", ht[i].records - ht[i].filtered);
-        if (version >= 2)
-            wrbuf_printf(c->wrbuf, "<filtered>%d</filtered>\n");
+        if (version >= 2) {
+            wrbuf_printf(c->wrbuf, "<filtered>%d</filtered>\n", ht[i].filtered);
+            wrbuf_printf(c->wrbuf, "<approximation>" ODR_INT_PRINTF "</approximation>\n", ht[i].approximation);
+        }
         wrbuf_puts(c->wrbuf, "<state>");
         wrbuf_xmlputs(c->wrbuf, ht[i].state);
         wrbuf_puts(c->wrbuf, "</state>\n");
@@ -1048,10 +1064,13 @@ static void show_records(struct http_channel *c, struct http_session *s, int act
     const char *start = http_argbyname(rq, "start");
     const char *num = http_argbyname(rq, "num");
     const char *sort = http_argbyname(rq, "sort");
+    int version = get_version(rq);
+
     int startn = 0;
     int numn = 20;
     int total;
     Odr_int total_hits;
+    Odr_int approx_hits;
     int i;
 
     if (!s)
@@ -1074,12 +1093,15 @@ static void show_records(struct http_channel *c, struct http_session *s, int act
 
     }
     
-    rl = show_range_start(s->psession, sp, startn, &numn, &total, &total_hits);
+    rl = show_range_start(s->psession, sp, startn, &numn, &total, &total_hits, &approx_hits);
 
     response_open(c, "show");
     wrbuf_printf(c->wrbuf, "\n<activeclients>%d</activeclients>\n", active);
     wrbuf_printf(c->wrbuf, "<merged>%d</merged>\n", total);
     wrbuf_printf(c->wrbuf, "<total>" ODR_INT_PRINTF "</total>\n", total_hits);
+    if (version >= 2) {
+        wrbuf_printf(c->wrbuf, "<approximation>" ODR_INT_PRINTF "</approximation>\n", approx_hits);
+    }
     wrbuf_printf(c->wrbuf, "<start>%d</start>\n", startn);
     wrbuf_printf(c->wrbuf, "<num>%d</num>\n", numn);
 
@@ -1132,6 +1154,7 @@ static void cmd_show(struct http_channel *c)
     const char *block = http_argbyname(rq, "block");
     const char *sort = http_argbyname(rq, "sort");
     const char *block_error = http_argbyname(rq, "report");
+
     struct reclist_sortparms *sp;
     int status;
     int report_error = 0;
@@ -1150,7 +1173,8 @@ static void cmd_show(struct http_channel *c)
         release_session(c, s);
         return;
     }
-    session_sort(s->psession, sp->name, sp->increasing);
+    session_sort(s->psession, sp->name, sp->increasing,
+                 sp->type == Metadata_sortkey_position);
 
     status = session_active_clients(s->psession);