Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Neptune / Source / Core / NptHttp.h
blob3d2a0d2f3c230951d870b47a4679e049fb1585ee
1 /*****************************************************************
3 | Neptune - HTTP Protocol
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
32 #ifndef _NPT_HTTP_H_
33 #define _NPT_HTTP_H_
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "NptUri.h"
39 #include "NptTypes.h"
40 #include "NptList.h"
41 #include "NptBufferedStreams.h"
42 #include "NptSockets.h"
43 #include "NptMap.h"
44 #include "NptDynamicCast.h"
45 #include "NptVersion.h"
46 #include "NptTime.h"
47 #include "NptThreads.h"
48 #include "NptAutomaticCleaner.h"
50 /*----------------------------------------------------------------------
51 | constants
52 +---------------------------------------------------------------------*/
53 const unsigned int NPT_HTTP_DEFAULT_PORT = 80;
54 const unsigned int NPT_HTTPS_DEFAULT_PORT = 443;
55 const unsigned int NPT_HTTP_INVALID_PORT = 0;
57 const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_CONNECTION_TIMEOUT = 30000;
58 const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_IO_TIMEOUT = 30000;
59 const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_NAME_RESOLVER_TIMEOUT = 60000;
60 const unsigned int NPT_HTTP_CLIENT_DEFAULT_MAX_REDIRECTS = 20;
62 const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_CONNECTION_TIMEOUT = NPT_TIMEOUT_INFINITE;
63 const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_IO_TIMEOUT = 60000;
65 const unsigned int NPT_HTTP_CONNECTION_MANAGER_MAX_CONNECTION_POOL_SIZE = 5;
66 const unsigned int NPT_HTTP_CONNECTION_MANAGER_MAX_CONNECTION_AGE = 30; // seconds
67 const unsigned int NPT_HTTP_MAX_RECONNECTS = 10;
68 const unsigned int NPT_HTTP_MAX_100_RESPONSES = 10;
70 const int NPT_HTTP_PROTOCOL_MAX_LINE_LENGTH = 8192;
71 const int NPT_HTTP_PROTOCOL_MAX_HEADER_COUNT = 100;
73 #define NPT_HTTP_PROTOCOL_1_0 "HTTP/1.0"
74 #define NPT_HTTP_PROTOCOL_1_1 "HTTP/1.1"
75 #define NPT_HTTP_METHOD_GET "GET"
76 #define NPT_HTTP_METHOD_HEAD "HEAD"
77 #define NPT_HTTP_METHOD_POST "POST"
78 #define NPT_HTTP_METHOD_PUT "PUT"
79 #define NPT_HTTP_METHOD_OPTIONS "OPTIONS"
80 #define NPT_HTTP_METHOD_DELETE "DELETE"
81 #define NPT_HTTP_METHOD_TRACE "TRACE"
83 #define NPT_HTTP_HEADER_HOST "Host"
84 #define NPT_HTTP_HEADER_CONNECTION "Connection"
85 #define NPT_HTTP_HEADER_USER_AGENT "User-Agent"
86 #define NPT_HTTP_HEADER_SERVER "Server"
87 #define NPT_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
88 #define NPT_HTTP_HEADER_CONTENT_TYPE "Content-Type"
89 #define NPT_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
90 #define NPT_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
91 #define NPT_HTTP_HEADER_LOCATION "Location"
92 #define NPT_HTTP_HEADER_RANGE "Range"
93 #define NPT_HTTP_HEADER_CONTENT_RANGE "Content-Range"
94 #define NPT_HTTP_HEADER_COOKIE "Cookie"
95 #define NPT_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
96 #define NPT_HTTP_HEADER_CONTENT_RANGE "Content-Range"
97 #define NPT_HTTP_HEADER_AUTHORIZATION "Authorization"
99 #define NPT_HTTP_TRANSFER_ENCODING_CHUNKED "chunked"
102 const int NPT_ERROR_HTTP_INVALID_RESPONSE_LINE = NPT_ERROR_BASE_HTTP - 0;
103 const int NPT_ERROR_HTTP_INVALID_REQUEST_LINE = NPT_ERROR_BASE_HTTP - 1;
104 const int NPT_ERROR_HTTP_NO_PROXY = NPT_ERROR_BASE_HTTP - 2;
105 const int NPT_ERROR_HTTP_INVALID_REQUEST = NPT_ERROR_BASE_HTTP - 3;
106 const int NPT_ERROR_HTTP_METHOD_NOT_SUPPORTED = NPT_ERROR_BASE_HTTP - 4;
107 const int NPT_ERROR_HTTP_TOO_MANY_REDIRECTS = NPT_ERROR_BASE_HTTP - 5;
108 const int NPT_ERROR_HTTP_TOO_MANY_RECONNECTS = NPT_ERROR_BASE_HTTP - 6;
109 const int NPT_ERROR_HTTP_CANNOT_RESEND_BODY = NPT_ERROR_BASE_HTTP - 7;
111 #define NPT_HTTP_LINE_TERMINATOR "\r\n"
113 #if !defined(NPT_CONFIG_HTTP_DEFAULT_USER_AGENT)
114 #define NPT_CONFIG_HTTP_DEFAULT_USER_AGENT "Neptune/" NPT_NEPTUNE_VERSION_STRING
115 #endif
117 /*----------------------------------------------------------------------
118 | types
119 +---------------------------------------------------------------------*/
120 typedef unsigned int NPT_HttpStatusCode;
121 typedef NPT_UrlQuery NPT_HttpUrlQuery; // for backward compatibility
123 /*----------------------------------------------------------------------
124 | NPT_HttpUrl
125 +---------------------------------------------------------------------*/
126 class NPT_HttpUrl : public NPT_Url {
127 public:
128 // constructors
129 NPT_HttpUrl() {}
130 NPT_HttpUrl(const char* host,
131 NPT_UInt16 port,
132 const char* path,
133 const char* query = NULL,
134 const char* fragment = NULL);
135 NPT_HttpUrl(const char* url, bool ignore_scheme = false);
137 // methods
138 NPT_String ToString(bool with_fragment = true) const override;
141 /*----------------------------------------------------------------------
142 | NPT_HttpProtocol
143 +---------------------------------------------------------------------*/
144 class NPT_HttpProtocol
146 public:
147 // class methods
148 const char* GetStatusCodeString(NPT_HttpStatusCode status_code);
151 /*----------------------------------------------------------------------
152 | NPT_HttpHeader
153 +---------------------------------------------------------------------*/
154 class NPT_HttpHeader {
155 public:
156 // constructors and destructor
157 NPT_HttpHeader(const char* name, const char* value);
158 ~NPT_HttpHeader();
160 // methods
161 NPT_Result Emit(NPT_OutputStream& stream) const;
162 const NPT_String& GetName() const { return m_Name; }
163 const NPT_String& GetValue() const { return m_Value; }
164 NPT_Result SetName(const char* name);
165 NPT_Result SetValue(const char* value);
167 private:
168 // members
169 NPT_String m_Name;
170 NPT_String m_Value;
173 /*----------------------------------------------------------------------
174 | NPT_HttpHeaders
175 +---------------------------------------------------------------------*/
176 class NPT_HttpHeaders {
177 public:
178 // constructors and destructor
179 NPT_HttpHeaders();
180 ~NPT_HttpHeaders();
182 // methods
183 NPT_Result Parse(NPT_BufferedInputStream& stream);
184 NPT_Result Emit(NPT_OutputStream& stream) const;
185 const NPT_List<NPT_HttpHeader*>& GetHeaders() const { return m_Headers; }
186 NPT_HttpHeader* GetHeader(const char* name) const;
187 const NPT_String* GetHeaderValue(const char* name) const;
188 NPT_Result SetHeader(const char* name, const char* value, bool replace=true);
189 NPT_Result AddHeader(const char* name, const char* value);
190 NPT_Result RemoveHeader(const char* name);
192 private:
193 // members
194 NPT_List<NPT_HttpHeader*> m_Headers;
197 /*----------------------------------------------------------------------
198 | NPT_HttpEntity
199 +---------------------------------------------------------------------*/
200 class NPT_HttpEntity {
201 public:
202 // constructors and destructor
203 NPT_HttpEntity();
204 NPT_HttpEntity(const NPT_HttpHeaders& headers);
205 virtual ~NPT_HttpEntity();
207 // methods
208 NPT_Result SetInputStream(const NPT_InputStreamReference& stream,
209 bool update_content_length = false);
210 NPT_Result SetInputStream(const void* data, NPT_Size size);
211 NPT_Result SetInputStream(const NPT_String& string);
212 NPT_Result SetInputStream(const char* string);
213 NPT_Result GetInputStream(NPT_InputStreamReference& stream);
214 NPT_Result Load(NPT_DataBuffer& buffer);
215 NPT_Result SetHeaders(const NPT_HttpHeaders& headers);
217 // field access
218 NPT_Result SetContentLength(NPT_LargeSize length);
219 NPT_Result SetContentType(const char* type);
220 NPT_Result SetContentEncoding(const char* encoding);
221 NPT_Result SetTransferEncoding(const char* encoding);
222 NPT_LargeSize GetContentLength() { return m_ContentLength; }
223 const NPT_String& GetContentType() { return m_ContentType; }
224 const NPT_String& GetContentEncoding() { return m_ContentEncoding; }
225 const NPT_String& GetTransferEncoding() { return m_TransferEncoding;}
226 bool ContentLengthIsKnown() { return m_ContentLengthIsKnown; }
228 private:
229 // members
230 NPT_InputStreamReference m_InputStream;
231 NPT_LargeSize m_ContentLength;
232 NPT_String m_ContentType;
233 NPT_String m_ContentEncoding;
234 NPT_String m_TransferEncoding;
235 bool m_ContentLengthIsKnown;
238 /*----------------------------------------------------------------------
239 | NPT_HttpMessage
240 +---------------------------------------------------------------------*/
241 class NPT_HttpMessage {
242 public:
243 // constructors and destructor
244 virtual ~NPT_HttpMessage();
246 // methods
247 const NPT_String& GetProtocol() const {
248 return m_Protocol;
250 NPT_Result SetProtocol(const char* protocol) {
251 m_Protocol = protocol;
252 return NPT_SUCCESS;
254 NPT_HttpHeaders& GetHeaders() {
255 return m_Headers;
257 const NPT_HttpHeaders& GetHeaders() const {
258 return m_Headers;
260 NPT_Result SetEntity(NPT_HttpEntity* entity);
261 NPT_HttpEntity* GetEntity() {
262 return m_Entity;
264 NPT_HttpEntity* GetEntity() const {
265 return m_Entity;
267 virtual NPT_Result ParseHeaders(NPT_BufferedInputStream& stream);
269 protected:
270 // constructors
271 NPT_HttpMessage(const char* protocol);
273 // members
274 NPT_String m_Protocol;
275 NPT_HttpHeaders m_Headers;
276 NPT_HttpEntity* m_Entity;
279 /*----------------------------------------------------------------------
280 | NPT_HttpRequest
281 +---------------------------------------------------------------------*/
282 class NPT_HttpRequest : public NPT_HttpMessage {
283 public:
284 // class methods
285 static NPT_Result Parse(NPT_BufferedInputStream& stream,
286 const NPT_SocketAddress* endpoint,
287 NPT_HttpRequest*& request);
289 // constructors and destructor
290 NPT_HttpRequest(const NPT_HttpUrl& url,
291 const char* method,
292 const char* protocol = NPT_HTTP_PROTOCOL_1_0);
293 NPT_HttpRequest(const char* url,
294 const char* method,
295 const char* protocol = NPT_HTTP_PROTOCOL_1_0);
296 ~NPT_HttpRequest() override;
298 // methods
299 const NPT_HttpUrl& GetUrl() const { return m_Url; }
300 NPT_HttpUrl& GetUrl() { return m_Url; }
301 NPT_Result SetUrl(const char* url);
302 NPT_Result SetUrl(const NPT_HttpUrl& url);
303 const NPT_String& GetMethod() const { return m_Method; }
304 virtual NPT_Result Emit(NPT_OutputStream& stream, bool use_proxy=false) const;
306 protected:
307 // members
308 NPT_HttpUrl m_Url;
309 NPT_String m_Method;
312 /*----------------------------------------------------------------------
313 | NPT_HttpResponse
314 +---------------------------------------------------------------------*/
315 class NPT_HttpResponse : public NPT_HttpMessage {
316 public:
317 // class methods
318 static NPT_Result Parse(NPT_BufferedInputStream& stream,
319 NPT_HttpResponse*& response);
321 // constructors and destructor
322 NPT_HttpResponse(NPT_HttpStatusCode status_code,
323 const char* reason_phrase,
324 const char* protocol = NPT_HTTP_PROTOCOL_1_0);
325 ~NPT_HttpResponse() override;
327 // methods
328 NPT_Result SetStatus(NPT_HttpStatusCode status_code,
329 const char* reason_phrase,
330 const char* protocol = NULL);
331 NPT_Result SetProtocol(const char* protocol);
332 NPT_HttpStatusCode GetStatusCode() const { return m_StatusCode; }
333 const NPT_String& GetReasonPhrase() const { return m_ReasonPhrase; }
334 virtual NPT_Result Emit(NPT_OutputStream& stream) const;
336 protected:
337 // members
338 NPT_HttpStatusCode m_StatusCode;
339 NPT_String m_ReasonPhrase;
342 /*----------------------------------------------------------------------
343 | NPT_HttpProxyAddress
344 +---------------------------------------------------------------------*/
345 class NPT_HttpProxyAddress
347 public:
348 NPT_HttpProxyAddress() : m_Port(NPT_HTTP_INVALID_PORT) {}
349 NPT_HttpProxyAddress(const char* hostname, NPT_UInt16 port) :
350 m_HostName(hostname), m_Port(port) {}
352 const NPT_String& GetHostName() const { return m_HostName; }
353 void SetHostName(const char* hostname) { m_HostName = hostname; }
354 NPT_UInt16 GetPort() const { return m_Port; }
355 void SetPort(NPT_UInt16 port) { m_Port = port; }
357 private:
358 NPT_String m_HostName;
359 NPT_UInt16 m_Port;
362 /*----------------------------------------------------------------------
363 | NPT_HttpProxySelector
364 +---------------------------------------------------------------------*/
365 class NPT_HttpProxySelector
367 public:
368 // class methods
369 static NPT_HttpProxySelector* GetDefault();
370 static NPT_HttpProxySelector* GetSystemSelector();
372 // methods
373 virtual ~NPT_HttpProxySelector() {};
374 virtual NPT_Result GetProxyForUrl(const NPT_HttpUrl& url, NPT_HttpProxyAddress& proxy) = 0;
376 private:
377 // class members
378 static NPT_HttpProxySelector* m_SystemDefault;
381 class NPT_HttpRequestContext;
383 /*----------------------------------------------------------------------
384 | NPT_HttpClient
385 +---------------------------------------------------------------------*/
386 class NPT_HttpClient {
387 public:
388 // types
389 struct Config {
390 Config() : m_ConnectionTimeout( NPT_HTTP_CLIENT_DEFAULT_CONNECTION_TIMEOUT),
391 m_IoTimeout( NPT_HTTP_CLIENT_DEFAULT_CONNECTION_TIMEOUT),
392 m_NameResolverTimeout(NPT_HTTP_CLIENT_DEFAULT_NAME_RESOLVER_TIMEOUT),
393 m_MaxRedirects( NPT_HTTP_CLIENT_DEFAULT_MAX_REDIRECTS),
394 m_UserAgent( NPT_CONFIG_HTTP_DEFAULT_USER_AGENT) {}
395 NPT_Timeout m_ConnectionTimeout;
396 NPT_Timeout m_IoTimeout;
397 NPT_Timeout m_NameResolverTimeout;
398 NPT_Cardinal m_MaxRedirects;
399 NPT_String m_UserAgent;
402 class Connection {
403 public:
404 virtual ~Connection() {}
405 virtual NPT_InputStreamReference& GetInputStream() = 0;
406 virtual NPT_OutputStreamReference& GetOutputStream() = 0;
407 virtual NPT_Result GetInfo(NPT_SocketInfo& info) = 0;
408 virtual bool SupportsPersistence() { return false; }
409 virtual bool IsRecycled() { return false; }
410 virtual NPT_Result Recycle() { delete this; return NPT_SUCCESS; }
411 virtual NPT_Result Abort() { return NPT_ERROR_NOT_IMPLEMENTED; }
414 class Connector {
415 public:
416 virtual ~Connector() {}
418 virtual NPT_Result Connect(const NPT_HttpUrl& url,
419 NPT_HttpClient& client,
420 const NPT_HttpProxyAddress* proxy,
421 bool reuse, // whether we can reuse a connection or not
422 Connection*& connection) = 0;
424 protected:
425 NPT_Result TrackConnection(NPT_HttpClient& client,
426 Connection* connection) { return client.TrackConnection(connection); }
427 Connector() {} // don't instantiate directly
430 // class methods
431 static NPT_Result WriteRequest(NPT_OutputStream& output_stream,
432 NPT_HttpRequest& request,
433 bool should_persist,
434 bool use_proxy = false);
435 static NPT_Result ReadResponse(NPT_InputStreamReference& input_stream,
436 bool should_persist,
437 bool expect_entity,
438 NPT_HttpResponse*& response,
439 NPT_Reference<Connection>* cref = NULL);
442 * @param connector Pointer to a connector instance, or NULL to use
443 * the default (TCP) connector.
444 * @param transfer_ownership Boolean flag. If true, the NPT_HttpClient object
445 * becomes the owner of the passed Connector and will delete it when it is
446 * itself deleted. If false, the caller keeps the ownership of the connector.
447 * This flag is ignored if the connector parameter is NULL.
449 NPT_HttpClient(Connector* connector = NULL, bool transfer_ownership = true);
451 virtual ~NPT_HttpClient();
453 // methods
454 NPT_Result SendRequest(NPT_HttpRequest& request,
455 NPT_HttpResponse*& response,
456 NPT_HttpRequestContext* context = NULL);
457 NPT_Result Abort();
458 const Config& GetConfig() const { return m_Config; }
459 NPT_Result SetConfig(const Config& config);
460 NPT_Result SetProxy(const char* http_proxy_hostname,
461 NPT_UInt16 http_proxy_port,
462 const char* https_proxy_hostname = NULL,
463 NPT_UInt16 https_proxy_port = 0);
464 NPT_Result SetProxySelector(NPT_HttpProxySelector* selector);
465 NPT_Result SetConnector(Connector* connector);
466 NPT_Result SetTimeouts(NPT_Timeout connection_timeout,
467 NPT_Timeout io_timeout,
468 NPT_Timeout name_resolver_timeout);
469 NPT_Result SetUserAgent(const char* user_agent);
470 NPT_Result SetOptions(NPT_Flags options, bool on);
472 protected:
473 // methods
474 NPT_Result TrackConnection(Connection* connection);
475 NPT_Result SendRequestOnce(NPT_HttpRequest& request,
476 NPT_HttpResponse*& response,
477 NPT_HttpRequestContext* context = NULL);
479 // members
480 Config m_Config;
481 NPT_HttpProxySelector* m_ProxySelector;
482 bool m_ProxySelectorIsOwned;
483 Connector* m_Connector;
484 bool m_ConnectorIsOwned;
485 NPT_Mutex m_AbortLock;
486 bool m_Aborted;
489 /*----------------------------------------------------------------------
490 | NPT_HttpConnectionManager
491 +---------------------------------------------------------------------*/
492 class NPT_HttpConnectionManager : public NPT_Thread,
493 public NPT_AutomaticCleaner::Singleton
495 public:
496 // singleton management
497 static NPT_HttpConnectionManager* GetInstance();
499 class Connection : public NPT_HttpClient::Connection
501 public:
502 Connection(NPT_HttpConnectionManager& manager,
503 NPT_SocketReference& socket,
504 NPT_InputStreamReference input_stream,
505 NPT_OutputStreamReference output_stream);
506 ~Connection() override;
508 // NPT_HttpClient::Connection methods
509 NPT_InputStreamReference& GetInputStream() override { return m_InputStream; }
510 NPT_OutputStreamReference& GetOutputStream() override { return m_OutputStream; }
511 NPT_Result GetInfo(NPT_SocketInfo& info) override { return m_Socket->GetInfo(info); }
512 bool SupportsPersistence() override { return true; }
513 bool IsRecycled() override { return m_IsRecycled; }
514 NPT_Result Recycle() override;
515 NPT_Result Abort() override { return m_Socket->Cancel(); }
517 // members
518 NPT_HttpConnectionManager& m_Manager;
519 bool m_IsRecycled;
520 NPT_TimeStamp m_TimeStamp;
521 NPT_SocketReference m_Socket;
522 NPT_InputStreamReference m_InputStream;
523 NPT_OutputStreamReference m_OutputStream;
526 // destructor
527 ~NPT_HttpConnectionManager() override;
529 // methods
530 Connection* FindConnection(NPT_SocketAddress& address);
531 NPT_Result Recycle(Connection* connection);
532 NPT_Result Track(NPT_HttpClient* client, NPT_HttpClient::Connection* connection);
533 NPT_Result AbortConnections(NPT_HttpClient* client);
535 // class methods
536 static NPT_Result Untrack(NPT_HttpClient::Connection* connection);
538 private:
539 typedef NPT_List<NPT_HttpClient::Connection*> ConnectionList;
541 // class members
542 static NPT_HttpConnectionManager* Instance;
544 // constructor
545 NPT_HttpConnectionManager();
547 // NPT_Thread methods
548 void Run() override;
550 // methods
551 NPT_Result UntrackConnection(NPT_HttpClient::Connection* connection);
552 NPT_Result Cleanup();
554 // members
555 NPT_Mutex m_Lock;
556 NPT_Cardinal m_MaxConnections;
557 NPT_Cardinal m_MaxConnectionAge;
558 NPT_SharedVariable m_Aborted;
559 NPT_List<Connection*> m_Connections;
560 NPT_Map<NPT_HttpClient*, ConnectionList> m_ClientConnections;
563 /*----------------------------------------------------------------------
564 | NPT_HttpRequestContext
565 +---------------------------------------------------------------------*/
566 class NPT_HttpRequestContext
568 public:
569 // constructor
570 NPT_HttpRequestContext() {}
571 NPT_HttpRequestContext(const NPT_SocketAddress* local_address,
572 const NPT_SocketAddress* remote_address);
574 // methods
575 const NPT_SocketAddress& GetLocalAddress() const { return m_LocalAddress; }
576 const NPT_SocketAddress& GetRemoteAddress() const { return m_RemoteAddress; }
577 void SetLocalAddress(const NPT_SocketAddress& address) {
578 m_LocalAddress = address;
580 void SetRemoteAddress(const NPT_SocketAddress& address) {
581 m_RemoteAddress = address;
584 private:
585 // members
586 NPT_SocketAddress m_LocalAddress;
587 NPT_SocketAddress m_RemoteAddress;
590 /*----------------------------------------------------------------------
591 | NPT_HttpRequestHandler
592 +---------------------------------------------------------------------*/
593 class NPT_HttpRequestHandler
595 public:
596 NPT_IMPLEMENT_DYNAMIC_CAST(NPT_HttpRequestHandler)
598 // destructor
599 virtual ~NPT_HttpRequestHandler() {}
601 // methods
602 virtual NPT_Result SetupResponse(NPT_HttpRequest& request,
603 const NPT_HttpRequestContext& context,
604 NPT_HttpResponse& response) = 0;
607 * Override this method if you want to write the body yourself.
608 * The default implementation will simply write out the entity's
609 * input stream.
611 virtual NPT_Result SendResponseBody(const NPT_HttpRequestContext& context,
612 NPT_HttpResponse& response,
613 NPT_OutputStream& output);
616 * A notification method called by the server upon completing the
617 * processing of a request.
619 virtual void Completed(NPT_Result /*result*/) {}
622 /*----------------------------------------------------------------------
623 | NPT_HttpStaticRequestHandler
624 +---------------------------------------------------------------------*/
625 class NPT_HttpStaticRequestHandler : public NPT_HttpRequestHandler
627 public:
628 // constructors
629 NPT_HttpStaticRequestHandler(const char* document,
630 const char* mime_type = "text/html",
631 bool copy = true);
632 NPT_HttpStaticRequestHandler(const void* data,
633 NPT_Size size,
634 const char* mime_type = "text/html",
635 bool copy = true);
637 // NPT_HttpRequestHandler methods
638 NPT_Result SetupResponse(NPT_HttpRequest& request,
639 const NPT_HttpRequestContext& context,
640 NPT_HttpResponse& response) override;
642 private:
643 NPT_String m_MimeType;
644 NPT_DataBuffer m_Buffer;
647 /*----------------------------------------------------------------------
648 | NPT_HttpFileRequestHandler_DefaultFileTypeMapEntry
649 +---------------------------------------------------------------------*/
650 typedef struct NPT_HttpFileRequestHandler_DefaultFileTypeMapEntry {
651 const char* extension;
652 const char* mime_type;
653 } NPT_HttpFileRequestHandler_FileTypeMapEntry;
655 /*----------------------------------------------------------------------
656 | NPT_HttpFileRequestHandler
657 +---------------------------------------------------------------------*/
658 class NPT_HttpFileRequestHandler : public NPT_HttpRequestHandler
660 public:
661 // constructors
662 NPT_HttpFileRequestHandler(const char* url_root,
663 const char* file_root,
664 bool auto_dir = false,
665 const char* auto_index = NULL);
667 // NPT_HttpRequestHandler methods
668 NPT_Result SetupResponse(NPT_HttpRequest& request,
669 const NPT_HttpRequestContext& context,
670 NPT_HttpResponse& response) override;
672 // class methods
673 static const char* GetDefaultContentType(const char* extension);
675 // accessors
676 NPT_Map<NPT_String,NPT_String>& GetFileTypeMap() { return m_FileTypeMap; }
677 void SetDefaultMimeType(const char* mime_type) {
678 m_DefaultMimeType = mime_type;
680 void SetUseDefaultFileTypeMap(bool use_default) {
681 m_UseDefaultFileTypeMap = use_default;
684 static NPT_Result SetupResponseBody(NPT_HttpResponse& response,
685 NPT_InputStreamReference& stream,
686 const NPT_String* range_spec = NULL);
688 protected:
689 // methods
690 const char* GetContentType(const NPT_String& filename);
692 private:
693 NPT_String m_UrlRoot;
694 NPT_String m_FileRoot;
695 NPT_Map<NPT_String, NPT_String> m_FileTypeMap;
696 NPT_String m_DefaultMimeType;
697 bool m_UseDefaultFileTypeMap;
698 bool m_AutoDir;
699 NPT_String m_AutoIndex;
702 /*----------------------------------------------------------------------
703 | NPT_HttpServer
704 +---------------------------------------------------------------------*/
705 class NPT_HttpServer {
706 public:
707 // types
708 struct Config {
709 NPT_Timeout m_ConnectionTimeout;
710 NPT_Timeout m_IoTimeout;
711 NPT_IpAddress m_ListenAddress;
712 NPT_UInt16 m_ListenPort;
713 bool m_ReuseAddress;
716 // constructors and destructor
717 NPT_HttpServer(NPT_UInt16 listen_port = NPT_HTTP_DEFAULT_PORT, bool cancellable = false);
718 NPT_HttpServer(NPT_IpAddress listen_address,
719 NPT_UInt16 listen_port = NPT_HTTP_DEFAULT_PORT,
720 bool cancellable = false);
721 virtual ~NPT_HttpServer();
723 // methods
724 NPT_Result SetConfig(const Config& config);
725 const Config& GetConfig() const { return m_Config; }
726 NPT_Result SetListenPort(NPT_UInt16 port, bool reuse_address = true);
727 NPT_Result SetTimeouts(NPT_Timeout connection_timeout, NPT_Timeout io_timeout);
728 NPT_Result SetServerHeader(const char* server_header);
729 NPT_Result Abort();
730 NPT_Result WaitForNewClient(NPT_InputStreamReference& input,
731 NPT_OutputStreamReference& output,
732 NPT_HttpRequestContext* context,
733 NPT_Flags socket_flags = 0);
734 NPT_Result Loop(bool cancellable_sockets=true);
735 NPT_UInt16 GetPort() { return m_BoundPort; }
736 void Terminate();
739 * Add a request handler. By default the ownership of the handler is NOT transfered to this object,
740 * so the caller is responsible for the lifetime management of the handler object.
742 virtual NPT_Result AddRequestHandler(NPT_HttpRequestHandler* handler,
743 const char* path,
744 bool include_children = false,
745 bool transfer_ownership = false);
746 virtual NPT_HttpRequestHandler* FindRequestHandler(NPT_HttpRequest& request);
747 virtual NPT_List<NPT_HttpRequestHandler*> FindRequestHandlers(NPT_HttpRequest& request);
750 * Parse the request from a new client, form a response, and send it back.
752 virtual NPT_Result RespondToClient(NPT_InputStreamReference& input,
753 NPT_OutputStreamReference& output,
754 const NPT_HttpRequestContext& context);
756 protected:
757 // types
758 struct HandlerConfig {
759 HandlerConfig(NPT_HttpRequestHandler* handler,
760 const char* path,
761 bool include_children,
762 bool transfer_ownership = false);
763 ~HandlerConfig();
765 // methods
766 bool WillHandle(NPT_HttpRequest& request);
768 // members
769 NPT_HttpRequestHandler* m_Handler;
770 NPT_String m_Path;
771 bool m_IncludeChildren;
772 bool m_HandlerIsOwned;
775 // methods
776 NPT_Result Bind();
778 // members
779 NPT_TcpServerSocket m_Socket;
780 NPT_UInt16 m_BoundPort;
781 Config m_Config;
782 NPT_List<HandlerConfig*> m_RequestHandlers;
783 NPT_String m_ServerHeader;
784 bool m_Run;
787 /*----------------------------------------------------------------------
788 | NPT_HttpResponder
789 +---------------------------------------------------------------------*/
790 class NPT_HttpResponder {
791 public:
792 // types
793 struct Config {
794 NPT_Timeout m_IoTimeout;
797 // constructors and destructor
798 NPT_HttpResponder(NPT_InputStreamReference& input,
799 NPT_OutputStreamReference& output);
800 virtual ~NPT_HttpResponder();
802 // methods
803 NPT_Result SetConfig(const Config& config);
804 NPT_Result SetTimeout(NPT_Timeout io_timeout);
805 NPT_Result ParseRequest(NPT_HttpRequest*& request,
806 const NPT_SocketAddress* local_address = NULL);
807 NPT_Result SendResponseHeaders(NPT_HttpResponse& response);
809 protected:
810 // members
811 Config m_Config;
812 NPT_BufferedInputStreamReference m_Input;
813 NPT_OutputStreamReference m_Output;
816 /*----------------------------------------------------------------------
817 | NPT_HttpChunkedInputStream
818 +---------------------------------------------------------------------*/
819 class NPT_HttpChunkedInputStream : public NPT_InputStream
821 public:
822 // constructors and destructor
823 NPT_HttpChunkedInputStream(NPT_BufferedInputStreamReference& stream);
824 ~NPT_HttpChunkedInputStream() override;
826 // NPT_InputStream methods
827 NPT_Result Read(void* buffer,
828 NPT_Size bytes_to_read,
829 NPT_Size* bytes_read = NULL) override;
830 NPT_Result Seek(NPT_Position offset) override;
831 NPT_Result Tell(NPT_Position& offset) override;
832 NPT_Result GetSize(NPT_LargeSize& size) override;
833 NPT_Result GetAvailable(NPT_LargeSize& available) override;
835 protected:
836 // members
837 NPT_BufferedInputStreamReference m_Source;
838 NPT_UInt32 m_CurrentChunkSize;
839 bool m_Eos;
842 /*----------------------------------------------------------------------
843 | NPT_HttpChunkedOutputStream
844 +---------------------------------------------------------------------*/
845 class NPT_HttpChunkedOutputStream : public NPT_OutputStream
847 public:
848 // constructors and destructor
849 NPT_HttpChunkedOutputStream(NPT_OutputStream& stream);
850 ~NPT_HttpChunkedOutputStream() override;
852 // NPT_OutputStream methods
853 NPT_Result Write(const void* buffer,
854 NPT_Size bytes_to_write,
855 NPT_Size* bytes_written = NULL) override;
856 NPT_Result Seek(NPT_Position /*offset*/) override { return NPT_ERROR_NOT_SUPPORTED;}
857 NPT_Result Tell(NPT_Position& offset) override { return m_Stream.Tell(offset); }
858 NPT_Result Flush() override { return m_Stream.Flush(); }
860 protected:
861 // members
862 NPT_OutputStream& m_Stream;
865 #endif // _NPT_HTTP_H_