1 /***************************************************************** 2 | 3 | Platinum - HTTP Helper 4 | 5 | Copyright (c) 2004-2010, Plutinosoft, LLC. 6 | All rights reserved. 7 | http://www.plutinosoft.com 8 | 9 | This program is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU General Public License 11 | as published by the Free Software Foundation; either version 2 12 | of the License, or (at your option) any later version. 13 | 14 | OEMs, ISVs, VARs and other distributors that combine and 15 | distribute commercially licensed software with Platinum software 16 | and do not wish to distribute the source code for the commercially 17 | licensed software under version 2, or (at your option) any later 18 | version, of the GNU General Public License (the "GPL") must enter 19 | into a commercial license agreement with Plutinosoft, LLC. 20 | licensing@plutinosoft.com 21 | 22 | This program is distributed in the hope that it will be useful, 23 | but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | GNU General Public License for more details. 26 | 27 | You should have received a copy of the GNU General Public License 28 | along with this program; see the file LICENSE.txt. If not, write to 29 | the Free Software Foundation, Inc., 30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 31 | http://www.gnu.org/licenses/gpl-2.0.html 32 | 33 ****************************************************************/ 34 35 /** @file 36 HTTP utilities 37 */ 38 39 #ifndef _PLT_HTTP_H_ 40 #define _PLT_HTTP_H_ 41 42 /*---------------------------------------------------------------------- 43 | includes 44 +---------------------------------------------------------------------*/ 45 #include "Neptune.h" 46 #include "PltVersion.h" 47 48 /*---------------------------------------------------------------------- 49 | constants 50 +---------------------------------------------------------------------*/ 51 #if !defined(PLT_HTTP_DEFAULT_USER_AGENT) 52 #define PLT_HTTP_DEFAULT_USER_AGENT "UPnP/1.0 DLNADOC/1.50 Platinum/" PLT_PLATINUM_SDK_VERSION_STRING 53 #endif 54 55 #if !defined(PLT_HTTP_DEFAULT_SERVER) 56 #define PLT_HTTP_DEFAULT_SERVER "UPnP/1.0 DLNADOC/1.50 Platinum/" PLT_PLATINUM_SDK_VERSION_STRING 57 #endif 58 59 /*---------------------------------------------------------------------- 60 | types 61 +---------------------------------------------------------------------*/ 62 typedef enum { 63 PLT_DEVICE_UNKNOWN, 64 PLT_DEVICE_XBOX_360, 65 PLT_DEVICE_XBOX_ONE, 66 PLT_DEVICE_PS3, 67 PLT_DEVICE_WMP, 68 PLT_DEVICE_SONOS, 69 PLT_DEVICE_MAC, 70 PLT_DEVICE_WINDOWS, 71 PLT_DEVICE_VLC 72 } PLT_DeviceSignature; 73 74 /*---------------------------------------------------------------------- 75 | PLT_HttpHelper 76 +---------------------------------------------------------------------*/ 77 /** 78 The PLT_HttpHelper class is a set of utility functions for manipulating 79 HTTP headers, entities and messages. 80 */ 81 class PLT_HttpHelper { 82 public: 83 static bool IsConnectionKeepAlive(NPT_HttpMessage& message); 84 static bool IsBodyStreamSeekable(NPT_HttpMessage& message); 85 86 static NPT_Result GetContentType(const NPT_HttpMessage& message, NPT_String& type); 87 static NPT_Result GetContentLength(const NPT_HttpMessage& message, NPT_LargeSize& len); 88 89 static NPT_Result GetHost(const NPT_HttpRequest& request, NPT_String& value); 90 static void SetHost(NPT_HttpRequest& request, const char* host); 91 static PLT_DeviceSignature GetDeviceSignature(const NPT_HttpRequest& request); 92 93 static NPT_Result SetBody(NPT_HttpMessage& message, NPT_String& text, NPT_HttpEntity** entity = NULL); 94 static NPT_Result SetBody(NPT_HttpMessage& message, const char* text, NPT_HttpEntity** entity = NULL); 95 static NPT_Result SetBody(NPT_HttpMessage& message, const void* body, NPT_LargeSize len, NPT_HttpEntity** entity = NULL); 96 static NPT_Result SetBody(NPT_HttpMessage& message, NPT_InputStreamReference stream, NPT_HttpEntity** entity = NULL); 97 static NPT_Result GetBody(const NPT_HttpMessage& message, NPT_String& body); 98 static NPT_Result ParseBody(const NPT_HttpMessage& message, NPT_XmlElementNode*& xml); 99 100 static void SetBasicAuthorization(NPT_HttpRequest& request, const char* username, const char* password); 101 }; 102 103 /*---------------------------------------------------------------------- 104 | PLT_HttpRequestContext 105 +---------------------------------------------------------------------*/ 106 /** 107 The PLT_HttpRequestContext class holds information about the request sent, the 108 local & remote ip addresses and ports associated with a connection. It is used 109 mostly when processing a HTTP response. 110 */ 111 class PLT_HttpRequestContext : public NPT_HttpRequestContext { 112 public: 113 // constructors and destructor PLT_HttpRequestContext(const NPT_HttpRequest & request)114 PLT_HttpRequestContext(const NPT_HttpRequest& request) : 115 m_Request(request) {} PLT_HttpRequestContext(const NPT_HttpRequest & request,const NPT_HttpRequestContext & context)116 PLT_HttpRequestContext(const NPT_HttpRequest& request, const NPT_HttpRequestContext& context) : 117 NPT_HttpRequestContext(&context.GetLocalAddress(), &context.GetRemoteAddress()), 118 m_Request(request) {} ~PLT_HttpRequestContext()119 virtual ~PLT_HttpRequestContext() {} 120 GetRequest()121 const NPT_HttpRequest& GetRequest() const { return m_Request; } GetDeviceSignature()122 PLT_DeviceSignature GetDeviceSignature() { return PLT_HttpHelper::GetDeviceSignature(m_Request); } 123 124 private: 125 const NPT_HttpRequest& m_Request; 126 }; 127 128 /*---------------------------------------------------------------------- 129 | NPT_HttpHeaderPrinter 130 +---------------------------------------------------------------------*/ 131 class NPT_HttpHeaderPrinter 132 { 133 public: 134 // methods NPT_HttpHeaderPrinter(NPT_OutputStreamReference & stream)135 NPT_HttpHeaderPrinter(NPT_OutputStreamReference& stream) : 136 m_Stream(stream) {} operator()137 NPT_Result operator()(NPT_HttpHeader*& header) const { 138 m_Stream->WriteString(header->GetName()); 139 m_Stream->Write(": ", 2); 140 m_Stream->WriteString(header->GetValue()); 141 m_Stream->Write("\r\n", 2, NULL); 142 return NPT_SUCCESS; 143 } 144 145 private: 146 // members 147 NPT_OutputStreamReference& m_Stream; 148 }; 149 150 /*---------------------------------------------------------------------- 151 | macros 152 +---------------------------------------------------------------------*/ 153 #if defined(NPT_CONFIG_ENABLE_LOGGING) 154 #define PLT_LOG_HTTP_REQUEST_L(_logger, _level, _prefix, _request) \ 155 do { \ 156 if (!_request) break; \ 157 NPT_LOG_GET_LOGGER((_logger)) \ 158 if ((_logger).logger && (_level) >= (_logger).logger->GetLevel()) { \ 159 NPT_StringOutputStreamReference stream(new NPT_StringOutputStream); \ 160 NPT_OutputStreamReference output = stream; \ 161 _request->GetHeaders().GetHeaders().Apply(NPT_HttpHeaderPrinter(output)); \ 162 NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"%s\n%s %s %s\n%s", (const char*)_prefix, (const char*)_request->GetMethod(), (const char*)_request->GetUrl().ToRequestString(true), (const char*)_request->GetProtocol(), (const char*)stream->GetString())); \ 163 } \ 164 } while (0) 165 166 #define PLT_LOG_HTTP_RESPONSE_L(_logger, _level, _prefix, _response) \ 167 do { \ 168 if (!_response) break; \ 169 NPT_LOG_GET_LOGGER((_logger)) \ 170 if ((_logger).logger && (_level) >= (_logger).logger->GetLevel()) { \ 171 NPT_StringOutputStreamReference stream(new NPT_StringOutputStream); \ 172 NPT_OutputStreamReference output = stream; \ 173 _response->GetHeaders().GetHeaders().Apply(NPT_HttpHeaderPrinter(output)); \ 174 NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"%s\n%s %d %s\n%s", (const char*)_prefix, (const char*)_response->GetProtocol(), _response->GetStatusCode(), (const char*)_response->GetReasonPhrase(), (const char*)stream->GetString())); \ 175 } \ 176 } while (0) 177 178 #define PLT_LOG_HTTP_REQUEST(_level,_prefix,_request) PLT_LOG_HTTP_REQUEST_L(_NPT_LocalLogger,(_level),(_prefix),(_request)) 179 180 #define PLT_LOG_HTTP_RESPONSE(_level,_prefix,_response) PLT_LOG_HTTP_RESPONSE_L(_NPT_LocalLogger,(_level),(_prefix),(_response)) 181 182 #else /* NPT_CONFIG_ENABLE_LOGGING */ 183 #define PLT_LOG_HTTP_REQUEST_L(_logger, _level, _prefix, _request) 184 #define PLT_LOG_HTTP_RESPONSE_L(_logger, _level, _prefix, _response) 185 #define PLT_LOG_HTTP_REQUEST(_level,_prefix,_request) 186 #define PLT_LOG_HTTP_RESPONSE(_level,_prefix,_response) 187 #endif /* NPT_CONFIG_ENABLE_LOGGING */ 188 189 /*---------------------------------------------------------------------- 190 | PLT_HttpRequestHandler 191 +---------------------------------------------------------------------*/ 192 /** 193 The PLT_HttpRequestHandler class delegates the handling of the response of a 194 received HTTP request by a HTTP Server. 195 */ 196 class PLT_HttpRequestHandler : public NPT_HttpRequestHandler 197 { 198 public: PLT_HttpRequestHandler(NPT_HttpRequestHandler * delegate)199 PLT_HttpRequestHandler(NPT_HttpRequestHandler* delegate) : 200 m_Delegate(delegate) {} ~PLT_HttpRequestHandler()201 virtual ~PLT_HttpRequestHandler() {} 202 203 // NPT_HttpRequestHandler methods SetupResponse(NPT_HttpRequest & request,const NPT_HttpRequestContext & context,NPT_HttpResponse & response)204 NPT_Result SetupResponse(NPT_HttpRequest& request, 205 const NPT_HttpRequestContext& context, 206 NPT_HttpResponse& response) { 207 return m_Delegate->SetupResponse(request, context, response); 208 } 209 210 private: 211 NPT_HttpRequestHandler* m_Delegate; 212 }; 213 214 #endif /* _PLT_HTTP_H_ */ 215