Merge branch 'master' into sru_2_0
[yaz-moved-to-github.git] / src / http.c
index e4eecb9..683336a 100644 (file)
@@ -219,6 +219,21 @@ void z_HTTP_header_set(ODR o, Z_HTTP_Header **hp, const char *n,
     (*hp)->next = 0;
 }
 
+const char *z_HTTP_header_remove(Z_HTTP_Header **hp, const char *n)
+{
+    while (*hp)
+    {
+        if (!yaz_strcasecmp((*hp)->name, n))
+        {
+            const char *v = (*hp)->value;
+            *hp = (*hp)->next;
+            return v;
+        }
+        hp = &(*hp)->next;
+    }
+    return 0;
+}
+
 const char *z_HTTP_header_lookup(const Z_HTTP_Header *hp, const char *n)
 {
     for (; hp; hp = hp->next)
@@ -323,7 +338,7 @@ Z_GDU *z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args,
     return p;
 }
 
-Z_GDU *z_get_HTTP_Response(ODR o, int code)
+Z_GDU *z_get_HTTP_Response_details(ODR o, int code, const char *details)
 {
     Z_GDU *p = (Z_GDU *) odr_malloc(o, sizeof(*p));
     Z_HTTP_Response *hres;
@@ -340,7 +355,10 @@ Z_GDU *z_get_HTTP_Response(ODR o, int code)
                       "YAZ/" YAZ_VERSION);
     if (code != 200)
     {
-        hres->content_buf = (char*) odr_malloc(o, 400);
+        const char *http_err = z_HTTP_errmsg(code);
+        size_t sz = 400 + strlen(http_err) + (details ?
+                                              strlen(details) : 0);
+        hres->content_buf = (char*) odr_malloc(o, sz);
         sprintf(hres->content_buf,
                 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
                 " \"http://www.w3.org/TR/html4/strict.dtd\">\n"
@@ -352,16 +370,26 @@ Z_GDU *z_get_HTTP_Response(ODR o, int code)
                 "  <P><A HREF=\"http://www.indexdata.com/yaz/\">YAZ</A> "
                 YAZ_VERSION "</P>\n"
                 "  <P>Error: %d</P>\n"
-                "  <P>Description: %.50s</P>\n"
+                "  <P>Description: %s</P>\n", code, http_err);
+        if (details)
+        {
+            sprintf(hres->content_buf + strlen(hres->content_buf),
+                    "<P>Details: %s</P>\n", details);
+        }
+        sprintf(hres->content_buf + strlen(hres->content_buf),
                 " </BODY>\n"
-                "</HTML>\n",
-                code, z_HTTP_errmsg(code));
+                "</HTML>\n");
         hres->content_len = strlen(hres->content_buf);
         z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html");
     }
     return p;
 }
 
+Z_GDU *z_get_HTTP_Response(ODR o, int code)
+{
+    return z_get_HTTP_Response_details(o, code, 0);
+}
+
 const char *z_HTTP_errmsg(int code)
 {
     switch (code)
@@ -567,24 +595,24 @@ int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr)
     sprintf(sbuf, "HTTP/%s %d %s\r\n", hr->version,
             hr->code,
             z_HTTP_errmsg(hr->code));
-    odr_write2(o, sbuf, strlen(sbuf));
+    odr_write(o, sbuf, strlen(sbuf));
     /* use content_len for Content-Length */
     sprintf(sbuf, "Content-Length: %d\r\n", hr->content_len);
-    odr_write2(o, sbuf, strlen(sbuf));
+    odr_write(o, sbuf, strlen(sbuf));
     for (h = hr->headers; h; h = h->next)
     {
         if (yaz_strcasecmp(h->name, "Content-Length")
             && yaz_strcasecmp(h->name, "Transfer-Encoding"))
         {   /* skip Content-Length if given. content_len rules */
-            odr_write2(o, h->name, strlen(h->name));
-            odr_write2(o, ": ", 2);
-            odr_write2(o, h->value, strlen(h->value));
-            odr_write2(o, "\r\n", 2);
+            odr_write(o, h->name, strlen(h->name));
+            odr_write(o, ": ", 2);
+            odr_write(o, h->value, strlen(h->value));
+            odr_write(o, "\r\n", 2);
         }
     }
-    odr_write(o, (unsigned char *) "\r\n", 2);
+    odr_write(o, "\r\n", 2);
     if (hr->content_buf)
-        odr_write2(o, hr->content_buf, hr->content_len);
+        odr_write(o, hr->content_buf, hr->content_len);
     if (o->direction == ODR_PRINT)
     {
         odr_printf(o, "-- HTTP response:\n");
@@ -599,12 +627,12 @@ int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr)
     Z_HTTP_Header *h;
     int top0 = o->top;
 
-    odr_write2(o, hr->method, strlen(hr->method));
-    odr_write2(o, " ", 1);
-    odr_write2(o, hr->path, strlen(hr->path));
-    odr_write2(o, " HTTP/", 6);
-    odr_write2(o, hr->version, strlen(hr->version));
-    odr_write2(o, "\r\n", 2);
+    odr_write(o, hr->method, strlen(hr->method));
+    odr_write(o, " ", 1);
+    odr_write(o, hr->path, strlen(hr->path));
+    odr_write(o, " HTTP/", 6);
+    odr_write(o, hr->version, strlen(hr->version));
+    odr_write(o, "\r\n", 2);
     if (hr->content_len &&
         !z_HTTP_header_lookup(hr->headers,
                               "Content-Length"))
@@ -612,18 +640,18 @@ int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr)
         char lstr[60];
         sprintf(lstr, "Content-Length: %d\r\n",
                 hr->content_len);
-        odr_write2(o, lstr, strlen(lstr));
+        odr_write(o, lstr, strlen(lstr));
     }
     for (h = hr->headers; h; h = h->next)
     {
-        odr_write2(o, h->name, strlen(h->name));
-        odr_write2(o, ": ", 2);
-        odr_write2(o, h->value, strlen(h->value));
-        odr_write2(o, "\r\n", 2);
+        odr_write(o, h->name, strlen(h->name));
+        odr_write(o, ": ", 2);
+        odr_write(o, h->value, strlen(h->value));
+        odr_write(o, "\r\n", 2);
     }
-    odr_write2(o, "\r\n", 2);
+    odr_write(o, "\r\n", 2);
     if (hr->content_buf)
-        odr_write2(o, hr->content_buf, hr->content_len);
+        odr_write(o, hr->content_buf, hr->content_len);
     if (o->direction == ODR_PRINT)
     {
         odr_printf(o, "-- HTTP request:\n");