Qore HttpServerUtil Module Reference  0.3.11
HttpServerUtil.qm.dox.h
1 // -*- mode: c++; indent-tabs-mode: nil -*-
2 // @file HttpServerUtil.qm HTTP server base code
3 
4 /* HttpServerUtil.qm Copyright (C) 2014 - 2016 David Nichols
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23 */
24 
25 // need mime definitions
26 
27 
28 
71 
76 namespace HttpServer {
78  const HttpServerVersion = "0.3.11";
79 
81  const HttpServerString = sprintf("Qore-HTTP-Server/%s", HttpServerVersion);
82 
84  const DefaultTimeout = 30s; // recvs timeout after 30 seconds
85 
88 
90  const HttpCodes = (
91  // 100s: Informational
92  "100": "Continue",
93  "101": "Switching Protocols",
94 
95  // RFC 2518: WebDAV
96  "102": "Processing",
97 
98  // 200s: Success
99  "200": "OK",
100  "201": "Created",
101  "202": "Accepted",
102  "203": "Non-Authoritative Information",
103  "204": "No Content",
104  "205": "Reset Content",
105  "206": "Partial Content",
106 
107  // RFC 4918: WebDAV: The message body that follows is an XML message and can contain a number of separate response codes, depending on how many sub-requests were made
108  "207": "Multi-Status",
109 
110  // RFC 5842: WebDAV: The members of a DAV binding have already been enumerated in a previous reply to this request, and are not being included again
111  "208": "Already Reported",
112 
113  // RFC 3229
114  "226": "IM Used",
115 
116  // 300s: Redirection
117  "300": "Multiple Choices",
118  "301": "Moved Permanently",
119  "302": "Found",
120  "303": "See Other",
121  "304": "Not Modified",
122  "305": "Use Proxy",
123  //"306": "(Reserved)",
124  "307": "Temporary Redirect",
125 
126  // 400s: Client Errors
127  "400": "Bad Request",
128  "401": "Unauthorized",
129  "402": "Payment Required",
130  "403": "Forbidden",
131  "404": "Not Found",
132  "405": "Method Not Allowed",
133  "406": "Not Acceptable",
134  "407": "Proxy Authentication Required",
135  "408": "Request Timeout",
136  "409": "Conflict",
137  "410": "Gone",
138  "411": "Length Required",
139  "412": "Precondition Failed",
140  "413": "Request Entity Too Large",
141  "414": "Request-URI Too Long",
142  "415": "Unsupported Media Type",
143  "416": "Requested Range Not Satisfiable",
144  "417": "Expectation Failed",
145 
146  // RFC 2324: http://tools.ietf.org/html/rfc2324
147  "418": "I'm a teapot",
148 
149  // Returned by the Twitter Search and Trends API when the client is being rate limited
150  "420": "Enhance Yextern Calm",
151 
152  // RFC 4918: WebDAV: The request was well-formed but was unable to be followed due to semantic errors
153  "422": "Unprocessable Entity",
154 
155  // RFC 4918: WebDAV: The resource that is being accessed is locked
156  "423": "Locked",
157 
158  // RFC 4918: WebDAV: The request failed due to failure of a previous request (e.g. a PROPPATCH)
159  "424": "Failed Dependency",
160 
161  // Internet draft: Defined in drafts of "WebDAV Advanced Collections Protocol", but not present in "Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol"
162  "425": "Unordered Collection",
163 
164  // RFC 2817: The client should switch to a different protocol such as TLS/1.0
165  "426": "Upgrade Required",
166 
167  // RFC 6585: The origin server requires the request to be conditional. Intended to prevent "the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict."
168  "428": "Precondition Required",
169 
170  // RFC 6585: The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes
171  "429": "Too Many Requests",
172 
173  // RFC 6585
174  "431": "Request Header Fields Too Large",
175 
176  // 500s: Server Errors
177  "500": "Internal Server Error",
178  "501": "Not Implemented",
179  "502": "Bad Gateway",
180  "503": "Service Unavailable",
181  "504": "Gateway Timeout",
182  "505": "HTTP Version Not Supported",
183  "509": "Bandwidth Limit Exceeded",
184 
185  // RFC 2774: Further extensions to the request are required for the server to fulfill it
186  "510": "Not Extended",
187 
188  // RFC 6585: The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network (e.g. "captive portals" used to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot)
189  "511": "Network Authentication Required",
190  );
191 
195  const LP_LOGPARAMS = 1 << 16;
197 
201 
203 
206  string http_get_url_from_bind(softstring bind, *string host);
207 
208 
210 
218  hash parse_uri_query(string path);
219 
220 
222  nothing http_set_reply_headers(Socket s, hash cx, reference rv, *string server_string);
223 
224 };
225 
228 
229 public:
231 
233  abstract log(string fmt);
234 
236 
238  abstract logError(string fmt);
239 
241 
243  logArgs(*softlist args);
244 
245 
247 
249  logErrorArgs(*softlist args);
250 
251 };
252 
255 
256 public:
258 
260  abstract addUserThreadContext(hash uctx);
261 
263 
265  abstract any removeUserThreadContext(*string k);
266 };
267 
269 
272 
273 public:
275 
277  bool requiresAuthentication();
278 
279 
281 
283  string getRealm();
284 
285 
287 
293  authenticate(string user, string pass = "");
294 
295 
297 
303  authenticateByIP(string ip, reference user);
304 
305 
306  private hash getAuthHeader();
307 
308 
309  private hash do401(string msg = "Authentication is required to access this server");
310 
311 
313 
322  *hash authenticateRequest(HttpListenerInterface listener, hash hdr, reference cx);
323 
324 };
325 
328 
329 public:
331 
337  *hash authenticateRequest(HttpListenerInterface listener, hash hdr, reference cx);
338 
339 };
340 
342 
351 
352 public:
353 private:
354 
355 public:
356 
357  private :
363  Socket s;
369  any body;
371  timeout timeout_ms = HttpServer::DefaultTimeout;
372 
373 public:
374 
376 
386  constructor(HttpListenerInterface n_listener, AbstractHttpRequestHandler n_handler, Socket n_s, hash n_cx, hash n_hdr, any n_body);
387 
388 
390  hash handleRequest();
391 
392 
394 
399  private hash sendResponse();
400 
401 
403 
412  private hash getResponseHeaderMessage();
413 
414 
416 
418  private nothing recv(hash v);
419 
420 
422  private any send();
423 
424 
425  private logChunk(bool send, int size);
426 
427 
429 
440  private hash getResponseHeaderMessageImpl();
441 
442 
444 
453  private nothing recvImpl(hash v);
454 
455 
457 
460  private any sendImpl();
461 
462 };
463 
465 
473 
474 public:
475  public :
478 
480  bool decompress = True;
481 
483  bool decompress_to_string = True;
484 
486  bool stream;
487 
489  timeout timeout_ms = HttpServer::DefaultTimeout;
490 
492  const NotificationThreadKey = "_AHRH_pc";
493 
495  const PersistenceThreadKey = "_AHRH_p";
496 
497 public:
498 
500 
503  constructor(*AbstractAuthenticator n_auth, softbool n_stream = False);
504 
505 
507  bool isPersistent();
508 
509 
511  setPersistent(bool p = True);
512 
513 
515  notifyClosed(*code c);
516 
517 
519  static staticNotificationCleanup();
520 
522  static staticPersistenceCleanup();
523 
525  nothing persistentClosed();
526 
527 
529  private nothing checkPersistent(hash cx, hash hdr);
530 
531 
533 
557  hash handleRequest(hash cx, hash hdr, *data body);
558 
559 
561  hash handleRequest(HttpListenerInterface listener, Socket s, hash cx, hash hdr, *data body);
562 
563 
565  private AbstractStreamRequest getStreamRequestImpl(HttpListenerInterface listener, Socket s, hash cx, hash hdr, *data body);
566 
567 
569  static data decodeBody(string ce, binary body, *string enc);
570 
572  static binary encodeBody(string ce, data body);
573 
575  *data getMessageBody(Socket s, hash hdr, *data body, bool decode = True);
576 
577 
579 
586  static *string getLogMessage(hash cx, hash api, reference params, *reference args);
587 
589 
591  *hash saveThreadLocalData();
592 
593 
595 
597  restoreThreadLocalData(*hash data);
598 
599 
601  static hash makeResponse(int code, string fmt);
602 
604  static hash makeResponse(hash hdr, int code, string fmt);
605 
607  static hash makeResponse(int code, *data body, *hash hdr);
608 
610  static hash make400(string fmt);
611 
613  static hash make400(hash hdr, string fmt);
614 
616  static hash make501(string fmt);
617 
619  static hash make501(hash hdr, string fmt);
620 
622  static hash redirect(hash cx, hash hdr, string path);
623 };
624 
627 
628 public:
629  public :
631  string url_root;
632 
633 public:
634 
636 
639  constructor(string n_url_root, *AbstractAuthenticator auth) ;
640 
641 
643  string getRelativePath(string path);
644 
645 };
646 
648 
651 
652 public:
653  private :
655  bool stop = False;
656 
659 
662 
664  Mutex m();
665 
666 public:
667 
669 
671  constructor(*AbstractAuthenticator auth) ;
672 
673 
675 
690  start(softstring lid, hash cx, hash hdr, Socket s);
691 
692 
694 
698  stop(softstring lid);
699 
700 
702 
704  stop();
705 
706 
708 
735  abstract hash handleRequest(hash cx, hash hdr, *data b);
736 
738 
753  private abstract startImpl(softstring lid, hash cx, hash hdr, Socket s);
754 
756 
758  private stopImpl(string lid);
759 
760 
762  private stopImpl();
763 
764 };
string sprintf(string fmt,...)
logErrorArgs(*softlist args)
calls logError() with the given args
hash hdr
a hash of request headers
Definition: HttpServerUtil.qm.dox.h:367
const ReadTimeout
read timeout in ms
Definition: HttpServerUtil.qm.dox.h:87
const HttpCodes
map of HTTP result codes and text messages
Definition: HttpServerUtil.qm.dox.h:90
abstract class for streaming HTTP chunked requests/responses
Definition: HttpServerUtil.qm.dox.h:350
const LP_LOGPARAMS
bit for logging argument
Definition: HttpServerUtil.qm.dox.h:196
abstract class that all HTTP request handler objects must inherit from
Definition: HttpServerUtil.qm.dox.h:472
class providing automatic authentication for all requests
Definition: HttpServerUtil.qm.dox.h:327
*AbstractAuthenticator auth
the optional AbstractAuthenticator for requests to this handler
Definition: HttpServerUtil.qm.dox.h:477
abstract log(string fmt)
called to log information to the registered log code
hash lh
hash of listener references; this is to stop all connections associated with a particular listener ...
Definition: HttpServerUtil.qm.dox.h:658
const True
this abstract class defines the public interface of the private HttpListener class defined in the Htt...
Definition: HttpServerUtil.qm.dox.h:254
AbstractHttpRequestHandler handler
the request handler for the request
Definition: HttpServerUtil.qm.dox.h:361
binary binary()
bool stream
if the handler supports streaming requests/responses with chunked data
Definition: HttpServerUtil.qm.dox.h:486
const False
string http_get_url_from_bind(softstring bind, *string host)
returns a complete URL from a bind address
abstract base class for external authentication
Definition: HttpServerUtil.qm.dox.h:271
hash cx
the call context variable
Definition: HttpServerUtil.qm.dox.h:365
Socket s
the Socket object for the response
Definition: HttpServerUtil.qm.dox.h:363
const HttpServerVersion
version of the HttpServer&#39;s implementation
Definition: HttpServerUtil.qm.dox.h:78
hash parse_uri_query(string path)
parses a URI path for a arguments and a method; where the method is the part of the path before the f...
HttpListenerInterface listener
an HttpListenerInterface object for the listener serving the request for logging purposes ...
Definition: HttpServerUtil.qm.dox.h:359
this abstract class defines the interface for classes that provide logging methods ...
Definition: HttpServerUtil.qm.dox.h:227
const DefaultTimeout
default timeout in ms
Definition: HttpServerUtil.qm.dox.h:84
abstract class that all HTTP dedicated socket handler objects must inherit from
Definition: HttpServerUtil.qm.dox.h:650
abstract class for HTTP request handlers anchored at a specific URL
Definition: HttpServerUtil.qm.dox.h:626
const LP_LEVELMASK
mask for the log level
Definition: HttpServerUtil.qm.dox.h:199
const HttpServerString
default HTTP server string
Definition: HttpServerUtil.qm.dox.h:81
the main namespace for the HttpServer and HttpServerUtil modules
Definition: HttpServerUtil.qm.dox.h:76
abstract logError(string fmt)
called to log error information to the registered error log code
logArgs(*softlist args)
calls log() with the given args
nothing http_set_reply_headers(Socket s, hash cx, reference rv, *string server_string)
helper function for setting HTTP response headers
hash hash(object obj)
string url_root
root part of URL for matching requests
Definition: HttpServerUtil.qm.dox.h:631
hash lsh
hash of listener stop flags
Definition: HttpServerUtil.qm.dox.h:661
any body
any message body given in a non-chunked request; could already be deserialized
Definition: HttpServerUtil.qm.dox.h:369