X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fhttp.c;h=4362c757a85d305bdf8ac67406a36808d2259572;hp=42b32ed8927a69f3ca02fdbbc77987c56c3b0c5b;hb=f15418ee295542935d616a2163377b71e40ce04f;hpb=fe507b6b15788a3a8e58063d9dae52532a5229a5 diff --git a/src/http.c b/src/http.c index 42b32ed..4362c75 100644 --- a/src/http.c +++ b/src/http.c @@ -1,8 +1,6 @@ -/* - * Copyright (C) 1995-2007, Index Data ApS +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2010 Index Data * See the file LICENSE for details. - * - * $Id: http.c,v 1.2 2007-05-06 20:12:20 adam Exp $ */ /** @@ -14,6 +12,7 @@ #include #include #include +#include #include #ifdef WIN32 @@ -21,6 +20,57 @@ #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) { @@ -169,6 +219,29 @@ void z_HTTP_header_add_content_type(ODR o, Z_HTTP_Header **hp, } +/* + * HTTP Basic authentication is described at: + * http://tools.ietf.org/html/rfc1945#section-11.1 + */ +void z_HTTP_header_add_basic_auth(ODR o, Z_HTTP_Header **hp, + const char *username, const char *password) +{ + char *tmp, *buf; + int len; + + if (username == 0) + return; + + len = strlen(username) + strlen(password); + tmp = (char *) odr_malloc(o, len+2); + sprintf(tmp, "%s:%s", username, password); + buf = (char *) odr_malloc(o, (len+1) * 8/6 + 12); + strcpy(buf, "Basic "); + yaz_base64encode(tmp, &buf[strlen(buf)]); + z_HTTP_header_add(o, hp, "Authorization", buf); +} + + void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n, const char *v) { @@ -260,20 +333,21 @@ 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, - "\n" - "\n" - " \n" - " YAZ " YAZ_VERSION "\n" - " \n" - " \n" - "

YAZ " - YAZ_VERSION "

\n" - "

Error: %d

\n" - "

Description: %.50s

\n" - " \n" - "\n", - code, z_HTTP_errmsg(code)); + sprintf(hres->content_buf, + "\n" + "\n" + " \n" + " YAZ " YAZ_VERSION "\n" + " \n" + " \n" + "

YAZ " + YAZ_VERSION "

\n" + "

Error: %d

\n" + "

Description: %.50s

\n" + " \n" + "\n", + code, z_HTTP_errmsg(code)); hres->content_len = strlen(hres->content_buf); z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html"); } @@ -471,6 +545,7 @@ int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr) /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab