/* 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 <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)
i++;
for (po = i; i < o->size-1 && !strchr("\r\n", o->buf[i]); i++)
;
-
+
(*headers)->value = (char*) odr_malloc(o, i - po + 1);
memcpy ((*headers)->value, o->buf + po, i - po);
(*headers)->value[i - po] = '\0';
-
+
if (!strcasecmp((*headers)->name, "Transfer-Encoding")
&&
!strcasecmp((*headers)->value, "chunked"))
if (chunked)
{
int off = 0;
-
+
/* we know buffer will be smaller than o->size - i*/
- *content_buf = (char*) odr_malloc(o, o->size - i);
-
+ *content_buf = (char*) odr_malloc(o, o->size - i);
+
while (1)
{
/* chunk length .. */
int chunk_len = 0;
for (; i < o->size-2; i++)
if (yaz_isdigit(o->buf[i]))
- chunk_len = chunk_len * 16 +
+ chunk_len = chunk_len * 16 +
(o->buf[i] - '0');
else if (yaz_isupper(o->buf[i]))
- chunk_len = chunk_len * 16 +
+ chunk_len = chunk_len * 16 +
(o->buf[i] - ('A'-10));
else if (yaz_islower(o->buf[i]))
- chunk_len = chunk_len * 16 +
+ chunk_len = chunk_len * 16 +
(o->buf[i] - ('a'-10));
else
break;
*content_buf = 0;
*content_len = 0;
}
- else
+ else
{
*content_len = o->size - i;
*content_buf = (char*) odr_malloc(o, *content_len + 1);
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)
{
if (code != 200)
{
hres->content_buf = (char*) odr_malloc(o, 400);
- sprintf(hres->content_buf,
+ sprintf(hres->content_buf,
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
" \"http://www.w3.org/TR/html4/strict.dtd\">\n"
"<HTML>\n"
" <TITLE>YAZ " YAZ_VERSION "</TITLE>\n"
" </HEAD>\n"
" <BODY>\n"
- " <P><A HREF=\"http://www.indexdata.com/yaz/\">YAZ</A> "
+ " <P><A HREF=\"http://www.indexdata.com/yaz/\">YAZ</A> "
YAZ_VERSION "</P>\n"
" <P>Error: %d</P>\n"
" <P>Description: %.50s</P>\n"
{
int i, po;
Z_HTTP_Response *hr = (Z_HTTP_Response *) odr_malloc(o, sizeof(*hr));
-
+
*hr_p = hr;
hr->content_buf = 0;
hr->content_len = 0;
-
+
po = i = 5;
while (i < o->size-2 && !strchr(" \r\n", o->buf[i]))
i++;
while (i < o->size-1 && o->buf[i] != '\n')
i++;
return decode_headers_content(o, i, &hr->headers,
- &hr->content_buf, &hr->content_len);
+ &hr->content_buf, &hr->content_len);
}
int yaz_decode_http_request(ODR o, Z_HTTP_Request **hr_p)
{
int i, po;
Z_HTTP_Request *hr = (Z_HTTP_Request *) odr_malloc(o, sizeof(*hr));
-
+
*hr_p = hr;
-
+
/* method .. */
for (i = 0; o->buf[i] != ' '; i++)
if (i >= o->size-5 || i > 30)
}
odr_write(o, (unsigned char *) "\r\n", 2);
if (hr->content_buf)
- odr_write(o, (unsigned char *)
+ odr_write(o, (unsigned char *)
hr->content_buf,
hr->content_len);
if (o->direction == ODR_PRINT)