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/HTTPMessage.cc | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 libs/networking/src/HTTPMessage.cc (limited to 'libs/networking/src/HTTPMessage.cc') diff --git a/libs/networking/src/HTTPMessage.cc b/libs/networking/src/HTTPMessage.cc new file mode 100644 index 0000000..9e1b5ba --- /dev/null +++ b/libs/networking/src/HTTPMessage.cc @@ -0,0 +1,165 @@ +/** + * ======================== legal notice ====================== + * + * File: HTTPMessage.cc + * Created: 3. Juli 2012, 17:40 + * 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 + +static void freeHeaderCallback(void *elem) +{ + free(elem); +} + +cHTTPMessage::cHTTPMessage(HTTPProtocol Proto) + : protocol(Proto) + , timeStamp(0) + , header(freeHeaderCallback) + , auth(NULL) + , contentSize(0) + , contentType(NULL) +{ +} + +cHTTPMessage::~cHTTPMessage() +{ + if (auth) delete auth; + FREE(contentType); +} + +char *cHTTPMessage::FormatTime(time_t timeStamp) +{ + struct tm *t = gmtime(&timeStamp); + char buf[128]; + + strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", t); + + return strdup(buf); +} + +void cHTTPMessage::SetHeader(const char *Name, const char *Value) +{ + header.put(Name, Value ? strdup(Value) : NULL); +} + +const char *cHTTPMessage::GetHeader(const char* Name) const +{ + return (const char *) header.get(Name); +} + +size_t cHTTPMessage::WritePrefix(char *Buffer, size_t BufSize) +///< writes message prefix to existing buffer. Prefix is the message without +///< the content body, so internal and external content will be processed +///< separately. +///< IMPORTANT: content size and content type has to be set before this call! +///< or this information needs to be added by custom call. +{ + cManagedMap::const_iterator it = Headers().begin(); + size_t n = WriteFirstLine(Buffer, BufSize); + + strcpy(Buffer + n, "Date: "); + n += 6; + n += WriteTime(Buffer + n, BufSize - n); + while (it != Headers().end()) { + n += snprintf(Buffer + n, BufSize - n, "%s: %s\r\n", it->first.c_str(), (const char *) it->second); + ++it; + } + if (auth) n += auth->Write(Buffer + n, BufSize - n); + if (ContentSize() > 0) { + n += snprintf(Buffer + n, BufSize - n, "Content-Type: %s\r\n", ContentType()); + n += snprintf(Buffer + n, BufSize - n, "Content-Length: %ld\r\n", ContentSize()); + if (n < BufSize - 3) { + Buffer[n++] = '\n'; // this is the separator between header and content! + Buffer[n] = 0; + } + } + return n; +} + +int cHTTPMessage::WriteTime(char *Buffer, size_t BufSize) +{ + if (!timeStamp) timeStamp = time(NULL); + struct tm *t = gmtime(&timeStamp); + + return strftime(Buffer, BufSize, "%a, %d %b %Y %H:%M:%S GMT\r\n", t); +} + +void cHTTPMessage::Reset() +{ + header.clear(); + contentSize = 0; +} + +size_t cHTTPMessage::ContentSize() const +{ + return contentSize; +} + +void cHTTPMessage::SetContentType(const char* ContentType) +{ + FREE(contentType); + contentType = ContentType ? strdup(ContentType) : NULL; +} + +void cHTTPMessage::SetAuthorization(cAuthorization* Authorization) +{ + if (auth) { + delete auth; + auth = NULL; + } + auth = Authorization; +} + +const char *cHTTPMessage::ProtocolString(void) { + switch (protocol) { + case HTTP_1_0: return "HTTP/1.0"; + case HTTP_1_1: return "HTTP/1.1"; + default: return "Unknown/Unsupported"; + } +} + +void cHTTPMessage::Dump(void ) +{ + cManagedMap::const_iterator it = Headers().begin(); + char buf[1024]; + + WriteFirstLine(buf, sizeof(buf)); + printf("=========== Dump HTTP message ==============\n"); + printf("Protocol: %s\n", ProtocolString()); + printf("first line: %s\n", buf); + printf("header entries:\n"); + while (it != Headers().end()) { + printf("\t[%s] ==> >|%s|<\n", it->first.c_str(), (const char *) it->second); + ++it; + } + if (auth) auth->Dump(); + if (ContentSize()) { + printf("---------- content (%ld Bytes of type %s) -------------\n" + , ContentSize(), ContentType()); + } + else printf(">>> NO Content!\n"); + printf("========== End Dump HTTP message ===========\n"); +} + -- cgit v1.2.3