From 2d48ae784ea6828e8626c32c848f64232d8f35c0 Mon Sep 17 00:00:00 2001 From: geronimo Date: Fri, 13 Jul 2012 04:26:40 +0200 Subject: initial import --- libs/networking/src/HTTPRequest.cc | 171 +++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 libs/networking/src/HTTPRequest.cc (limited to 'libs/networking/src/HTTPRequest.cc') diff --git a/libs/networking/src/HTTPRequest.cc b/libs/networking/src/HTTPRequest.cc new file mode 100644 index 0000000..c17b29c --- /dev/null +++ b/libs/networking/src/HTTPRequest.cc @@ -0,0 +1,171 @@ +/** + * ======================== legal notice ====================== + * + * File: HTTPRequest.cc + * Created: 3. Juli 2012, 17:54 + * Author: Geronimo + * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include +#include +#include +#include +#include +#include +#include + + +cHTTPRequest::cHTTPRequest(const char *MessageBuf) + : method(INVALID) + , url(NULL) +{ + ParseMessage(MessageBuf); +} + +cHTTPRequest::cHTTPRequest(cHTTPRequest::HTTPRequestMethod Method, const char* Url) + : method(Method) + , url(Url) +{ +} + +cHTTPRequest::cHTTPRequest(const cHTTPResponse &res, const char *Url) + : method(cHTTPRequest::GET) + , url(Url) +{ + SetAuthorization(new cAuthorization(*res.Authorization())); + Authorization()->SetUri(Url); +} + + +cHTTPRequest::~cHTTPRequest() +{ +} + +const char *requestMethod2String(cHTTPRequest::HTTPRequestMethod Method) +{ + switch (Method) { + case cHTTPRequest::GET: return "GET"; + case cHTTPRequest::POST: return "POST"; + default: return "unknown/unsupported"; + } +} + +void cHTTPRequest::SetURL(const char *Url) +{ + url.ParseURL(Url); +} + +const char *cHTTPRequest::ClientHost(void ) const +{ + return (const char *) Headers().get("Host"); +} + +const char *cHTTPRequest::UserAgent() const +{ + return (const char *) Headers().get("User-Agent"); +} + +void cHTTPRequest::SetUser(const char *UserID, const char *Password) +{ + char *uri = Url().ToString(); + this->Authorization()->CalculateResponse(uri, UserID, Password); + free(uri); +} + +static const char *fetchLine(char *Buf, int BufSize, const char *Source) +{ + const char *end = strchr(Source, '\r'); + int len = 0; + + if (!end) end = strchr(Source, '\n'); + if (!end) end = Source + strlen(Source); + len = end - Source; + if (len > BufSize) len = BufSize - 1; + + strncpy(Buf, Source, len); + Buf[len] = 0; + end = Source + len; + + return end; +} + +void cHTTPRequest::ParseMessage(const char *RequestBuf) +{ + char scratch[512]; + const char *start = RequestBuf, *end = strchr(start, ' '); + const char *name; + char *value; + + if (strncasecmp("GET", start, end - start)) SetMethod(GET); + else if (strncasecmp("POST", start, end - start)) SetMethod(POST); + start = end; + while (*start == ' ') ++start; + end = strchr(start, ' '); +// printf("request-URI %*.*s\n", (int)(end - start), (int)(end - start), start); + if ((end - start) >= (int)sizeof(scratch)) { + esyslog("URI exhausted buffer - abort request!"); + return; + } + else { + strncpy(scratch, start, end - start); + scratch[end - start] = 0; + SetURL(scratch); + } + start = end; + while (*start == ' ') ++start; + end = strchr(start, '\r'); + if (!end) end = strchr(start, '\n'); +// printf("http-protocol %*.*s\n", (int)(end - start), (int)(end - start), start); + if (!strncmp("HTTP/1.1", start, end - start)) SetProtocol(HTTP_1_1); + else SetProtocol(HTTP_1_0); + + for (start = end; start && *start; start = end) { + if (*start == '\r') ++start; + if (*start == '\n') ++start; + if (!*start) break; + end = fetchLine(scratch, sizeof(scratch), start); +// printf("a line from request (%03d) [%s]\n", strlen(scratch), scratch); + + name = scratch; + value = strchr((char *)name, ':'); + if (value) { + if (value) *value++ = 0; + if (*value == ' ') *value++ = 0; + + SetHeader(name, value); + } + else { +// printf("possibly end of header ...\n"); + continue; + } +// printf("\nresult - name [%s] => |>%s<|\n", name, value); + } +} + +size_t cHTTPRequest::WriteFirstLine(char* Buffer, size_t BufSize) +{ + size_t n = snprintf(Buffer, BufSize, "%s ", requestMethod2String(Method())); + int tmp = url.WriteBuf(Buffer + n, BufSize - n); + + if (tmp > 0) n += tmp; + n += snprintf(Buffer + n, BufSize - n, " %s\n", ProtocolString()); + + return n; +} + -- cgit v1.2.3