Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Platinum / Source / Core / PltHttp.cpp
blob41159bed5b5a033bc52780198ffd3292ac1bd37c
1 /*****************************************************************
3 | Platinum - HTTP Protocol Helper
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
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.
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
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.
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
33 ****************************************************************/
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "PltHttp.h"
39 #include "PltDatagramStream.h"
40 #include "PltVersion.h"
41 #include "PltUtilities.h"
43 NPT_SET_LOCAL_LOGGER("platinum.core.http")
45 /*----------------------------------------------------------------------
46 | external references
47 +---------------------------------------------------------------------*/
48 extern NPT_String HttpServerHeader;
50 /*----------------------------------------------------------------------
51 | NPT_HttpHeaderFinder
52 +---------------------------------------------------------------------*/
53 class NPT_HttpHeaderFinder
55 public:
56 // methods
57 NPT_HttpHeaderFinder(const char* name) : m_Name(name) {}
58 bool operator()(const NPT_HttpHeader* const & header) const {
59 if (header->GetName().Compare(m_Name, true)) {
60 return true;
61 } else {
62 return false;
66 private:
67 // members
68 NPT_String m_Name;
71 /*----------------------------------------------------------------------
72 | NPT_HttpHeaderLogger
73 +---------------------------------------------------------------------*/
74 class NPT_HttpHeaderLogger
76 public:
77 // methods
78 NPT_HttpHeaderLogger(NPT_LoggerReference& logger, int level) :
79 m_Logger(logger), m_Level(level) {}
80 NPT_Result operator()(NPT_HttpHeader*& header) const {
81 NPT_COMPILER_UNUSED(header);
83 NPT_LOG_L2(m_Logger, m_Level, "%s: %s",
84 (const char*)header->GetName(),
85 (const char*)header->GetValue());
86 return NPT_SUCCESS;
89 NPT_LoggerReference& m_Logger;
90 int m_Level;
94 /*----------------------------------------------------------------------
95 | PLT_HttpHelper::GetContentType
96 +---------------------------------------------------------------------*/
97 NPT_Result
98 PLT_HttpHelper::GetContentType(const NPT_HttpMessage& message,
99 NPT_String& type)
101 type = "";
103 const NPT_String* val =
104 message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_CONTENT_TYPE);
105 NPT_CHECK_POINTER(val);
107 type = *val;
108 return NPT_SUCCESS;
111 /*----------------------------------------------------------------------
112 | PLT_HttpHelper::GetContentLength
113 +---------------------------------------------------------------------*/
114 NPT_Result
115 PLT_HttpHelper::GetContentLength(const NPT_HttpMessage& message,
116 NPT_LargeSize& len)
118 len = 0;
120 const NPT_String* val =
121 message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_CONTENT_LENGTH);
122 NPT_CHECK_POINTER(val);
124 return val->ToInteger64(len);
127 /*----------------------------------------------------------------------
128 | PLT_HttpHelper::SetBody
129 +---------------------------------------------------------------------*/
130 NPT_Result
131 PLT_HttpHelper::SetBody(NPT_HttpMessage& message,
132 NPT_String& text,
133 NPT_HttpEntity** entity /* = NULL */)
135 return SetBody(message, (const char*)text, text.GetLength(), entity);
138 /*----------------------------------------------------------------------
139 | PLT_HttpHelper::SetBody
140 +---------------------------------------------------------------------*/
141 NPT_Result
142 PLT_HttpHelper::SetBody(NPT_HttpMessage& message,
143 const char* text,
144 NPT_HttpEntity** entity /* = NULL */)
146 return SetBody(message, (const char*)text, NPT_StringLength(text), entity);
149 /*----------------------------------------------------------------------
150 | NPT_HttpMessage::SetBody
151 +---------------------------------------------------------------------*/
152 NPT_Result
153 PLT_HttpHelper::SetBody(NPT_HttpMessage& message,
154 const void* body,
155 NPT_LargeSize len,
156 NPT_HttpEntity** entity /* = NULL */)
158 if (len == 0) return NPT_SUCCESS;
160 // dump the body in a memory stream
161 NPT_MemoryStreamReference stream(new NPT_MemoryStream);
162 stream->Write(body, (NPT_Size)len);
164 // set content length
165 return SetBody(message, (NPT_InputStreamReference)stream, entity);
168 /*----------------------------------------------------------------------
169 | NPT_HttpMessage::SetBody
170 +---------------------------------------------------------------------*/
171 NPT_Result
172 PLT_HttpHelper::SetBody(NPT_HttpMessage& message,
173 NPT_InputStreamReference stream,
174 NPT_HttpEntity** entity /* = NULL */)
176 // get the entity
177 NPT_HttpEntity* _entity = message.GetEntity();
178 if (_entity == NULL) {
179 // no entity yet, create one
180 message.SetEntity(_entity = new NPT_HttpEntity());
183 if (entity) *entity =_entity;
185 // set the entity body
186 return _entity->SetInputStream(stream, true);
189 /*----------------------------------------------------------------------
190 | PLT_HttpHelper::GetBody
191 +---------------------------------------------------------------------*/
192 NPT_Result
193 PLT_HttpHelper::GetBody(const NPT_HttpMessage& message, NPT_String& body)
195 NPT_Result res;
196 NPT_InputStreamReference stream;
198 // get stream
199 NPT_HttpEntity* entity = message.GetEntity();
200 if (!entity ||
201 NPT_FAILED(entity->GetInputStream(stream)) ||
202 stream.IsNull()) {
203 return NPT_FAILURE;
206 // extract body
207 NPT_StringOutputStream* output_stream = new NPT_StringOutputStream(&body);
208 res = NPT_StreamToStreamCopy(*stream,
209 *output_stream,
211 entity->GetContentLength());
212 delete output_stream;
213 return res;
216 /*----------------------------------------------------------------------
217 | PLT_HttpHelper::ParseBody
218 +---------------------------------------------------------------------*/
219 NPT_Result
220 PLT_HttpHelper::ParseBody(const NPT_HttpMessage& message,
221 NPT_XmlElementNode*& tree)
223 // reset tree
224 tree = NULL;
226 // read body
227 NPT_String body;
228 NPT_CHECK_WARNING(GetBody(message, body));
230 return PLT_XmlHelper::Parse(body, tree);
233 /*----------------------------------------------------------------------
234 | PLT_HttpHelper::IsConnectionKeepAlive
235 +---------------------------------------------------------------------*/
236 bool
237 PLT_HttpHelper::IsConnectionKeepAlive(NPT_HttpMessage& message)
239 const NPT_String* connection =
240 message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_CONNECTION);
242 // the DLNA says that all HTTP 1.0 requests should be closed immediately by the server
243 NPT_String protocol = message.GetProtocol();
244 if (protocol.Compare(NPT_HTTP_PROTOCOL_1_0, true) == 0) return false;
246 // all HTTP 1.1 requests without a Connection header
247 // or with a keep-alive Connection header should be kept alive if possible
248 return (!connection || connection->Compare("keep-alive", true) == 0);
251 /*----------------------------------------------------------------------
252 | PLT_HttpHelper::IsBodyStreamSeekable
253 +---------------------------------------------------------------------*/
254 bool
255 PLT_HttpHelper::IsBodyStreamSeekable(NPT_HttpMessage& message)
257 NPT_HttpEntity* entity = message.GetEntity();
258 NPT_InputStreamReference stream;
260 if (!entity ||
261 NPT_FAILED(entity->GetInputStream(stream)) ||
262 stream.IsNull()) {
263 return true;
266 // try to get current position and seek there
267 NPT_Position position;
268 if (NPT_FAILED(stream->Tell(position)) ||
269 NPT_FAILED(stream->Seek(position))) {
270 return false;
273 return true;
276 /*----------------------------------------------------------------------
277 | PLT_HttpHelper::GetHost
278 +---------------------------------------------------------------------*/
279 NPT_Result
280 PLT_HttpHelper::GetHost(const NPT_HttpRequest& request, NPT_String& value)
282 value = "";
284 const NPT_String* val =
285 request.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_HOST);
286 NPT_CHECK_POINTER(val);
288 value = *val;
289 return NPT_SUCCESS;
292 /*----------------------------------------------------------------------
293 | PLT_HttpHelper::SetHost
294 +---------------------------------------------------------------------*/
295 void
296 PLT_HttpHelper::SetHost(NPT_HttpRequest& request, const char* host)
298 request.GetHeaders().SetHeader(NPT_HTTP_HEADER_HOST, host);
301 /*----------------------------------------------------------------------
302 | PLT_HttpHelper::GetDeviceSignature
303 +---------------------------------------------------------------------*/
304 PLT_DeviceSignature
305 PLT_HttpHelper::GetDeviceSignature(const NPT_HttpRequest& request)
307 const NPT_String* agent = request.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_USER_AGENT);
308 const NPT_String* hdr = request.GetHeaders().GetHeaderValue("X-AV-Client-Info");
309 const NPT_String* server = request.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_SERVER);
310 const NPT_String* dlna_friendly_name = request.GetHeaders().GetHeaderValue("FriendlyName.DLNA.ORG");
311 NPT_LOG_FINEST_2("agent: %s, server: %s", agent?agent->GetChars():"none", server?server->GetChars():"none");
313 if ((agent && (agent->Find("XBox", 0, true) >= 0 || agent->Find("Xenon", 0, true) >= 0)) ||
314 (server && server->Find("Xbox", 0, true) >= 0)) {
315 return PLT_DEVICE_XBOX_360;
316 } else if(dlna_friendly_name && (dlna_friendly_name->Find("XBOX-ONE", 0, true) >= 0)) {
317 return PLT_DEVICE_XBOX_ONE;
318 } else if (agent && (agent->Find("Windows Media Player", 0, true) >= 0 || agent->Find("Windows-Media-Player", 0, true) >= 0 || agent->Find("Mozilla/4.0", 0, true) >= 0 || agent->Find("WMFSDK", 0, true) >= 0)) {
319 return PLT_DEVICE_WMP;
320 } else if (agent && (agent->Find("Sonos", 0, true) >= 0)) {
321 return PLT_DEVICE_SONOS;
322 } else if ((agent && agent->Find("PLAYSTATION 3", 0, true) >= 0) ||
323 (hdr && hdr->Find("PLAYSTATION 3", 0, true) >= 0)) {
324 return PLT_DEVICE_PS3;
325 } else if (agent && agent->Find("Windows", 0, true) >= 0) {
326 return PLT_DEVICE_WINDOWS;
327 } else if (agent && (agent->Find("Mac", 0, true) >= 0 || agent->Find("OS X", 0, true) >= 0 || agent->Find("OSX", 0, true) >= 0)) {
328 return PLT_DEVICE_MAC;
329 } else if (agent && (agent->Find("VLC", 0, true) >= 0 || agent->Find("VideoLan", 0, true) >= 0)) {
330 return PLT_DEVICE_VLC;
331 } else {
332 NPT_LOG_FINER_2("Unknown device signature (ua=%s, server=%s)", agent?agent->GetChars():"none", server?server->GetChars():"none");
335 return PLT_DEVICE_UNKNOWN;
338 /*----------------------------------------------------------------------
339 | PLT_HttpHelper::SetBasicAuthorization
340 +---------------------------------------------------------------------*/
341 void
342 PLT_HttpHelper::SetBasicAuthorization(NPT_HttpRequest& request,
343 const char* username,
344 const char* password)
346 NPT_String encoded;
347 NPT_String cred = NPT_String(username) + ":" + password;
349 NPT_Base64::Encode((const NPT_Byte *)cred.GetChars(), cred.GetLength(), encoded);
350 request.GetHeaders().SetHeader(NPT_HTTP_HEADER_AUTHORIZATION, NPT_String("Basic " + encoded));