Happy new year
[yaz-moved-to-github.git] / src / http.c
index 7546047..6539f7a 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2011 Index Data
+ * Copyright (C) 1995-2012 Index Data
  * See the file LICENSE for details.
  */
 /**
 #include <config.h>
 #endif
 
-#include <ctype.h>
 #include <yaz/odr.h>
 #include <yaz/yaz-version.h>
 #include <yaz/yaz-iconv.h>
 #include <yaz/matchstr.h>
 #include <yaz/zgdu.h>
+#include <yaz/base64.h>
 
 #ifdef WIN32
 #define strncasecmp _strnicmp
 #define strcasecmp _stricmp
 #endif
  
-
-/*
- * This function's counterpart, yaz_base64decode(), is in srwutil.c.
- * I feel bad that they're not together, but each function is only
- * needed in one place, and those places are not together.  Maybe one
- * day we'll move them into a new httputil.c, and declare them in a
- * corresponding httputil.h
- */
-static void yaz_base64encode(const char *in, char *out)
-{
-    static char encoding[] =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    unsigned char buf[3];
-    long n;
-
-    while (*in != 0) {
-       char *pad = 0;
-        buf[0] = in[0];
-       buf[1] = in[1];
-       if (in[1] == 0) {
-           buf[2] = 0;
-           pad = "==";
-       } else {
-           buf[2] = in[2];
-           if (in[2] == 0)
-               pad = "=";
-       }
-
-       /* Treat three eight-bit numbers as on 24-bit number */
-       n = (buf[0] << 16) + (buf[1] << 8) + buf[2];
-
-       /* Write the six-bit chunks out as four encoded characters */
-       *out++ = encoding[(n >> 18) & 63];
-       *out++ = encoding[(n >> 12) & 63];
-       if (in[1] != 0)
-           *out++ = encoding[(n >> 6) & 63];
-       if (in[1] != 0 && in[2] != 0)
-           *out++ = encoding[n & 63];
-
-       if (pad != 0) {
-           while (*pad != 0)
-               *out++ = *pad++;
-           break;
-       }
-       in += 3;
-    }
-
-    *out++ = 0;
-}
-
-
 static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
                                   char **content_buf, int *content_len)
 {
@@ -143,13 +92,13 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
             /* chunk length .. */
             int chunk_len = 0;
             for (; i  < o->size-2; i++)
-                if (isdigit(o->buf[i]))
+                if (yaz_isdigit(o->buf[i]))
                     chunk_len = chunk_len * 16 + 
                         (o->buf[i] - '0');
-                else if (isupper(o->buf[i]))
+                else if (yaz_isupper(o->buf[i]))
                     chunk_len = chunk_len * 16 + 
                         (o->buf[i] - ('A'-10));
-                else if (islower(o->buf[i]))
+                else if (yaz_islower(o->buf[i]))
                     chunk_len = chunk_len * 16 + 
                         (o->buf[i] - ('a'-10));
                 else
@@ -233,6 +182,8 @@ void z_HTTP_header_add_basic_auth(ODR o, Z_HTTP_Header **hp,
 
     if (username == 0)
         return;
+    if (password == 0)
+        password = "";
 
     len = strlen(username) + strlen(password);
     tmp = (char *) odr_malloc(o, len+2);
@@ -316,6 +267,48 @@ Z_GDU *z_get_HTTP_Request_host_path(ODR odr,
     return p;
 }
 
+Z_GDU *z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args,
+                              int use_full_uri)
+{
+    Z_GDU *p = z_get_HTTP_Request(odr);
+    const char *cp0 = strstr(uri, "://");
+    const char *cp1 = 0;
+    if (cp0)
+        cp0 = cp0+3;
+    else
+        cp0 = uri;
+    
+    cp1 = strchr(cp0, '/');
+    if (!cp1)
+        cp1 = cp0+strlen(cp0);
+    
+    if (cp0 && cp1)
+    {
+        char *h = (char*) odr_malloc(odr, cp1 - cp0 + 1);
+        memcpy (h, cp0, cp1 - cp0);
+        h[cp1-cp0] = '\0';
+        z_HTTP_header_add(odr, &p->u.HTTP_Request->headers,
+                          "Host", h);
+    }
+
+    if (!args)
+    {
+        if (*cp1)
+            args = cp1 + 1;
+        else
+            args = "";
+    }
+    p->u.HTTP_Request->path = odr_malloc(odr, cp1 - uri + strlen(args) + 2);
+    if (use_full_uri)
+    {
+        memcpy(p->u.HTTP_Request->path, uri, cp1 - uri);
+        strcpy(p->u.HTTP_Request->path + (cp1 - uri), "/");
+    }
+    else
+        strcpy(p->u.HTTP_Request->path, "/");
+    strcat(p->u.HTTP_Request->path, args);
+    return p;
+}
 
 Z_GDU *z_get_HTTP_Response(ODR o, int code)
 {