xbmc
NptHttp.h
1 /*****************************************************************
2 |
3 | Neptune - HTTP Protocol
4 |
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
7 |
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.
18 |
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.
29 |
30  ****************************************************************/
31 
32 #ifndef _NPT_HTTP_H_
33 #define _NPT_HTTP_H_
34 
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"
49 
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;
56 
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;
61 
62 const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_CONNECTION_TIMEOUT = NPT_TIMEOUT_INFINITE;
63 const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_IO_TIMEOUT = 60000;
64 
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;
69 
70 const int NPT_HTTP_PROTOCOL_MAX_LINE_LENGTH = 8192;
71 const int NPT_HTTP_PROTOCOL_MAX_HEADER_COUNT = 100;
72 
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"
82 
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"
98 
99 #define NPT_HTTP_TRANSFER_ENCODING_CHUNKED "chunked"
100 
101 
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;
110 
111 #define NPT_HTTP_LINE_TERMINATOR "\r\n"
112 
113 #if !defined(NPT_CONFIG_HTTP_DEFAULT_USER_AGENT)
114 #define NPT_CONFIG_HTTP_DEFAULT_USER_AGENT "Neptune/" NPT_NEPTUNE_VERSION_STRING
115 #endif
116 
117 /*----------------------------------------------------------------------
118 | types
119 +---------------------------------------------------------------------*/
120 typedef unsigned int NPT_HttpStatusCode;
121 typedef NPT_UrlQuery NPT_HttpUrlQuery; // for backward compatibility
122 
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);
136 
137  // methods
138  NPT_String ToString(bool with_fragment = true) const override;
139 };
140 
141 /*----------------------------------------------------------------------
142 | NPT_HttpProtocol
143 +---------------------------------------------------------------------*/
145 {
146 public:
147  // class methods
148  const char* GetStatusCodeString(NPT_HttpStatusCode status_code);
149 };
150 
151 /*----------------------------------------------------------------------
152 | NPT_HttpHeader
153 +---------------------------------------------------------------------*/
155 public:
156  // constructors and destructor
157  NPT_HttpHeader(const char* name, const char* value);
158  ~NPT_HttpHeader();
159 
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);
166 
167 private:
168  // members
169  NPT_String m_Name;
170  NPT_String m_Value;
171 };
172 
173 /*----------------------------------------------------------------------
174 | NPT_HttpHeaders
175 +---------------------------------------------------------------------*/
177 public:
178  // constructors and destructor
179  NPT_HttpHeaders();
180  ~NPT_HttpHeaders();
181 
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);
191 
192 private:
193  // members
194  NPT_List<NPT_HttpHeader*> m_Headers;
195 };
196 
197 /*----------------------------------------------------------------------
198 | NPT_HttpEntity
199 +---------------------------------------------------------------------*/
201 public:
202  // constructors and destructor
203  NPT_HttpEntity();
204  NPT_HttpEntity(const NPT_HttpHeaders& headers);
205  virtual ~NPT_HttpEntity();
206 
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);
216 
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; }
227 
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;
236 };
237 
238 /*----------------------------------------------------------------------
239 | NPT_HttpMessage
240 +---------------------------------------------------------------------*/
242 public:
243  // constructors and destructor
244  virtual ~NPT_HttpMessage();
245 
246  // methods
247  const NPT_String& GetProtocol() const {
248  return m_Protocol;
249  }
250  NPT_Result SetProtocol(const char* protocol) {
251  m_Protocol = protocol;
252  return NPT_SUCCESS;
253  }
254  NPT_HttpHeaders& GetHeaders() {
255  return m_Headers;
256  }
257  const NPT_HttpHeaders& GetHeaders() const {
258  return m_Headers;
259  }
260  NPT_Result SetEntity(NPT_HttpEntity* entity);
261  NPT_HttpEntity* GetEntity() {
262  return m_Entity;
263  }
264  NPT_HttpEntity* GetEntity() const {
265  return m_Entity;
266  }
267  virtual NPT_Result ParseHeaders(NPT_BufferedInputStream& stream);
268 
269 protected:
270  // constructors
271  NPT_HttpMessage(const char* protocol);
272 
273  // members
274  NPT_String m_Protocol;
275  NPT_HttpHeaders m_Headers;
276  NPT_HttpEntity* m_Entity;
277 };
278 
279 /*----------------------------------------------------------------------
280 | NPT_HttpRequest
281 +---------------------------------------------------------------------*/
283 public:
284  // class methods
285  static NPT_Result Parse(NPT_BufferedInputStream& stream,
286  const NPT_SocketAddress* endpoint,
287  NPT_HttpRequest*& request);
288 
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;
297 
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;
305 
306 protected:
307  // members
308  NPT_HttpUrl m_Url;
309  NPT_String m_Method;
310 };
311 
312 /*----------------------------------------------------------------------
313 | NPT_HttpResponse
314 +---------------------------------------------------------------------*/
316 public:
317  // class methods
318  static NPT_Result Parse(NPT_BufferedInputStream& stream,
319  NPT_HttpResponse*& response);
320 
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;
326 
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;
335 
336 protected:
337  // members
338  NPT_HttpStatusCode m_StatusCode;
339  NPT_String m_ReasonPhrase;
340 };
341 
342 /*----------------------------------------------------------------------
343 | NPT_HttpProxyAddress
344 +---------------------------------------------------------------------*/
346 {
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) {}
351 
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; }
356 
357 private:
358  NPT_String m_HostName;
359  NPT_UInt16 m_Port;
360 };
361 
362 /*----------------------------------------------------------------------
363 | NPT_HttpProxySelector
364 +---------------------------------------------------------------------*/
366 {
367 public:
368  // class methods
369  static NPT_HttpProxySelector* GetDefault();
370  static NPT_HttpProxySelector* GetSystemSelector();
371 
372  // methods
373  virtual ~NPT_HttpProxySelector() {};
374  virtual NPT_Result GetProxyForUrl(const NPT_HttpUrl& url, NPT_HttpProxyAddress& proxy) = 0;
375 
376 private:
377  // class members
378  static NPT_HttpProxySelector* m_SystemDefault;
379 };
380 
382 
383 /*----------------------------------------------------------------------
384 | NPT_HttpClient
385 +---------------------------------------------------------------------*/
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;
400  };
401 
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; }
412  };
413 
414  class Connector {
415  public:
416  virtual ~Connector() {}
417 
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;
423 
424  protected:
425  NPT_Result TrackConnection(NPT_HttpClient& client,
426  Connection* connection) { return client.TrackConnection(connection); }
427  Connector() {} // don't instantiate directly
428  };
429 
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);
440 
449  NPT_HttpClient(Connector* connector = NULL, bool transfer_ownership = true);
450 
451  virtual ~NPT_HttpClient();
452 
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);
471 
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);
478 
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;
487 };
488 
489 /*----------------------------------------------------------------------
490 | NPT_HttpConnectionManager
491 +---------------------------------------------------------------------*/
494 {
495 public:
496  // singleton management
497  static NPT_HttpConnectionManager* GetInstance();
498 
500  {
501  public:
504  NPT_InputStreamReference input_stream,
505  NPT_OutputStreamReference output_stream);
506  ~Connection() override;
507 
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(); }
516 
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;
524  };
525 
526  // destructor
527  ~NPT_HttpConnectionManager() override;
528 
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);
534 
535  // class methods
536  static NPT_Result Untrack(NPT_HttpClient::Connection* connection);
537 
538 private:
540 
541  // class members
542  static NPT_HttpConnectionManager* Instance;
543 
544  // constructor
546 
547  // NPT_Thread methods
548  void Run() override;
549 
550  // methods
551  NPT_Result UntrackConnection(NPT_HttpClient::Connection* connection);
552  NPT_Result Cleanup();
553 
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;
561 };
562 
563 /*----------------------------------------------------------------------
564 | NPT_HttpRequestContext
565 +---------------------------------------------------------------------*/
567 {
568 public:
569  // constructor
571  NPT_HttpRequestContext(const NPT_SocketAddress* local_address,
572  const NPT_SocketAddress* remote_address);
573 
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;
579  }
580  void SetRemoteAddress(const NPT_SocketAddress& address) {
581  m_RemoteAddress = address;
582  }
583 
584 private:
585  // members
586  NPT_SocketAddress m_LocalAddress;
587  NPT_SocketAddress m_RemoteAddress;
588 };
589 
590 /*----------------------------------------------------------------------
591 | NPT_HttpRequestHandler
592 +---------------------------------------------------------------------*/
594 {
595 public:
596  NPT_IMPLEMENT_DYNAMIC_CAST(NPT_HttpRequestHandler)
597 
598  // destructor
599  virtual ~NPT_HttpRequestHandler() {}
600 
601  // methods
602  virtual NPT_Result SetupResponse(NPT_HttpRequest& request,
603  const NPT_HttpRequestContext& context,
604  NPT_HttpResponse& response) = 0;
605 
611  virtual NPT_Result SendResponseBody(const NPT_HttpRequestContext& context,
612  NPT_HttpResponse& response,
613  NPT_OutputStream& output);
614 
619  virtual void Completed(NPT_Result /*result*/) {}
620 };
621 
622 /*----------------------------------------------------------------------
623 | NPT_HttpStaticRequestHandler
624 +---------------------------------------------------------------------*/
626 {
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);
636 
637  // NPT_HttpRequestHandler methods
638  NPT_Result SetupResponse(NPT_HttpRequest& request,
639  const NPT_HttpRequestContext& context,
640  NPT_HttpResponse& response) override;
641 
642 private:
643  NPT_String m_MimeType;
644  NPT_DataBuffer m_Buffer;
645 };
646 
647 /*----------------------------------------------------------------------
648 | NPT_HttpFileRequestHandler_DefaultFileTypeMapEntry
649 +---------------------------------------------------------------------*/
651  const char* extension;
652  const char* mime_type;
654 
655 /*----------------------------------------------------------------------
656 | NPT_HttpFileRequestHandler
657 +---------------------------------------------------------------------*/
659 {
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);
666 
667  // NPT_HttpRequestHandler methods
668  NPT_Result SetupResponse(NPT_HttpRequest& request,
669  const NPT_HttpRequestContext& context,
670  NPT_HttpResponse& response) override;
671 
672  // class methods
673  static const char* GetDefaultContentType(const char* extension);
674 
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;
679  }
680  void SetUseDefaultFileTypeMap(bool use_default) {
681  m_UseDefaultFileTypeMap = use_default;
682  }
683 
684  static NPT_Result SetupResponseBody(NPT_HttpResponse& response,
685  NPT_InputStreamReference& stream,
686  const NPT_String* range_spec = NULL);
687 
688 protected:
689  // methods
690  const char* GetContentType(const NPT_String& filename);
691 
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;
700 };
701 
702 /*----------------------------------------------------------------------
703 | NPT_HttpServer
704 +---------------------------------------------------------------------*/
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;
714  };
715 
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();
722 
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,
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();
737 
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);
748 
752  virtual NPT_Result RespondToClient(NPT_InputStreamReference& input,
754  const NPT_HttpRequestContext& context);
755 
756 protected:
757  // types
758  struct HandlerConfig {
760  const char* path,
761  bool include_children,
762  bool transfer_ownership = false);
763  ~HandlerConfig();
764 
765  // methods
766  bool WillHandle(NPT_HttpRequest& request);
767 
768  // members
769  NPT_HttpRequestHandler* m_Handler;
770  NPT_String m_Path;
771  bool m_IncludeChildren;
772  bool m_HandlerIsOwned;
773  };
774 
775  // methods
776  NPT_Result Bind();
777 
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;
785 };
786 
787 /*----------------------------------------------------------------------
788 | NPT_HttpResponder
789 +---------------------------------------------------------------------*/
791 public:
792  // types
793  struct Config {
794  NPT_Timeout m_IoTimeout;
795  };
796 
797  // constructors and destructor
799  NPT_OutputStreamReference& output);
800  virtual ~NPT_HttpResponder();
801 
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);
808 
809 protected:
810  // members
811  Config m_Config;
813  NPT_OutputStreamReference m_Output;
814 };
815 
816 /*----------------------------------------------------------------------
817 | NPT_HttpChunkedInputStream
818 +---------------------------------------------------------------------*/
820 {
821 public:
822  // constructors and destructor
824  ~NPT_HttpChunkedInputStream() override;
825 
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;
834 
835 protected:
836  // members
838  NPT_UInt32 m_CurrentChunkSize;
839  bool m_Eos;
840 };
841 
842 /*----------------------------------------------------------------------
843 | NPT_HttpChunkedOutputStream
844 +---------------------------------------------------------------------*/
846 {
847 public:
848  // constructors and destructor
850  ~NPT_HttpChunkedOutputStream() override;
851 
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(); }
859 
860 protected:
861  // members
862  NPT_OutputStream& m_Stream;
863 };
864 
865 #endif // _NPT_HTTP_H_
866 
Definition: NptThreads.h:234
Definition: NptAutomaticCleaner.h:46
Definition: deflate.c:123
Definition: NptHttp.h:566
NPT_Result SetPort(NPT_UInt16 port)
Sets the port number of the URL.
Definition: NptUri.cpp:709
Definition: NptHttp.h:658
Definition: NptStreams.h:60
Definition: NptHttp.h:200
Definition: NptSockets.h:317
Definition: NptHttp.h:315
Definition: NptHttp.h:126
Definition: NptHttp.h:282
Definition: NptHttp.h:241
Definition: NptHttp.h:593
NPT_UInt16 GetPort() const
Returns the port number of the URL.
Definition: NptUri.h:189
Definition: NptUri.h:128
Definition: NptHttp.h:176
Definition: NptThreads.h:76
Definition: NptTime.h:50
Definition: NptNetwork.h:74
Definition: NptThreads.h:149
virtual void Completed(NPT_Result)
A notification method called by the server upon completing the processing of a request.
Definition: NptHttp.h:619
Definition: NptBufferedStreams.h:52
Definition: NptSockets.h:77
Definition: NptStreams.h:92
Definition: NptHttp.h:345
Definition: NptHttp.h:793
Definition: NptHttp.h:499
Definition: NptHttp.h:625
Definition: NptMap.h:47
Definition: NptSockets.h:115
Definition: NptHttp.h:758
Definition: NptHttp.h:790
Definition: NptDataBuffer.h:44
Definition: NptHttp.h:389
NPT_String ToString(bool with_fragment=true) const override
Return the string representation of the URL.
Definition: NptHttp.cpp:89
Definition: NptHttp.h:144
Definition: NptHttp.h:708
NPT_Result Parse(const char *url, NPT_UInt16 default_port=0)
Parse a URL from its fully encoded form.
Definition: NptUri.cpp:489
Definition: NptUri.h:92
Definition: NptHttp.h:845
Definition: NptHttp.h:492
Definition: NptHttp.h:386
Definition: NptHttp.h:365
Definition: NptHttp.h:154
Definition: NptHttp.h:402
Definition: NptHttp.h:414
Definition: NptStrings.h:57
Definition: NptHttp.h:705
Definition: NptHttp.h:819
Definition: NptList.h:54