Qore RestClient Module Reference 1.9.3
Loading...
Searching...
No Matches
RestClient.qm.dox.h
1// -*- mode: c++; indent-tabs-mode: nil -*-
3
4/* RestClient.qm Copyright (C) 2013 - 2023 Qore Technologies, s.r.o.
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// minimum qore version
26
27// require type definitions everywhere
28
29// enable all warnings
30
31// don't use "$" for vars, members, and methods, assume local variable scope
32
33
34
35
36
37
38}
39
40/* Version History - see below in docs
41*/
42
208namespace RestClient {
211
212public:
214 const DataSerializationSupport = {
215%ifndef NoJson
216 "json": MimeTypeJson,
217%endif
218%ifndef NoYaml
219 "yaml": MimeTypeYaml,
220%endif
221%ifndef NoXml
222 "xml": MimeTypeXml,
223 "rawxml": MimeTypeXmlApp,
224%endif
225 "url": MimeTypeFormUrlEncoded,
226 "text": MimeTypeText,
227 "bin": MimeTypeOctetStream,
228 };
229
230 const DeserializeYaml = {
231 "code": "yaml",
232 "in": \parse_yaml(),
233 };
234 const DeserializeXml = {
235 "code": "xml",
236 "arg": True,
237 "in": hash<auto> sub (string xml, reference<string> type) {
238 try {
239 on_success type = "xml";
240 return parse_xmlrpc_value(xml);
241 } catch (hash<ExceptionInfo> ex) {
242 try {
243 on_success type = "rawxml";
244 return parse_xml(xml);
245 } catch () {
246 rethrow;
247 }
248 }
249 },
250 };
251
253 const AcceptList = ...;
254
255
257 const Accept = AcceptList.join(",");
258
260 const AcceptMap = map {$1: True}, AcceptList;
261
263 const Version = "1.7";
264
266 const VersionString = sprintf("Qore-RestClient/%s", RestClient::Version);
267
269 const DefaultHeaders = {
270 "Accept": Accept,
271 "User-Agent": RestClient::VersionString,
272 };
273
275
285 const DataSerializationOptions = {
286 "auto": True,
287%ifndef NoJson
288 "json": True,
289%endif
290%ifndef NoYaml
291 "yaml": True,
292%endif
293%ifndef NoXml
294 "rawxml": True,
295 "xml": True,
296%endif
297 "url": True,
298 "text": True,
299 "bin": True,
300 };
301
303
309 const EncodingSupport = {
310 "gzip": {
311 "ce": "gzip",
312 "func": \gzip(),
313 },
314 "bzip2": {
315 "ce": "bzip2",
316 "func": \bzip2(),
317 },
318 "deflate": {
319 "ce": "deflate",
320 "func": \compress(),
321 },
322 "identity": {
323 "ce": NOTHING,
324 },
325 };
326
328 const CompressionThreshold = 1024;
329
330protected:
331 // headers to send with every request
332 hash<auto> headers;
333 // data serialization code
334 string ds;
335 // serialization content type
336 string sct;
337 // send content encoding hash
338 *hash<auto> seh;
339 // REST schema validator
341 // no_charset option
342 *bool noCharset;
343
344public:
345
347
408 constructor(*hash<auto> opts, *softbool do_not_connect)
409 ;
410
411
413
416
417
419
430 setSerialization(string data = 'auto');
431
432
434
449 setSendEncoding(string enc = 'auto');
450
451
453
468 setContentEncoding(string enc = 'auto');
469
470
472
486 addDefaultHeaders(hash<auto> h);
487
488
490
503 hash<auto> getDefaultHeaders();
504
505
507
521
522
524
534
535
537
578 hash<auto> get(string path, auto body, *reference<hash<auto>> info, *hash<auto> hdr);
579
580
582
622 hash<auto> put(string path, auto body, *reference<hash<auto>> info, *hash<auto> hdr);
623
624
626
666 hash<auto> patch(string path, auto body, *reference<hash<auto>> info, *hash<auto> hdr);
667
668
670
721 hash<auto> post(string path, auto body, *reference<hash<auto>> info, *hash<auto> hdr);
722
723
725
776 hash<auto> del(string path, auto body, *reference<hash<auto>> info, *hash<auto> hdr);
777
778
780
785
786
788 private nothing prepareMsg(string method, string path, reference<auto> body, reference<hash<auto>> hdr,
789 string ct = "Content-Type") {
790 // use {} + ... here to ensure that hdr stays "hash<auto>"
791 hdr = {} + headers + hdr;
792
793 // must get the path from the HTTPClient object if not given in the request
794 if (!path.val() && (*string p = getConnectionPath()))
795 path = p;
796
797 hash<RestRequestClientInfo> req = validator.processRequest(method, path, body, hdr, sct);
798
799 if (exists body);
800
801 }
802
804protected:
805 nothing preparePath(reference<string> path);
806public:
807
808
810
870 hash<auto> doRequest(string m, string path, auto body, *reference<hash<auto>> info, softbool decode_errors = True,
871 *hash<auto> hdr) {
872 prepareMsg(m, path, \body, \hdr);
873
874 on_exit if (exists body);
875
876
877 // prepare path
878 preparePath(\path);
879
880 on_error rethrow $1.err, sprintf("%s (REST URL %y)", $1.desc, getSafeURL());
881
882 return sendAndDecodeResponse(body, m, path, hdr, \info, decode_errors);
883 }
884
886
888 hash<auto> doValidatedRequest(string m, string path, auto body, *reference<hash<auto>> info,
889 softbool decode_errors = True, *hash<auto> hdr) {
890 // use {} + ... here to ensure that hdr stays "hash<auto>"
891 hdr = {} + headers + hdr;
892
893 on_exit if (exists body);
894
895
896 return sendAndDecodeResponse(body, m, path, hdr, \info, decode_errors);
897 }
898
900 private hash<auto> sendAndDecodeResponse(*data body, string m, string path, hash<auto> hdr,
901 *reference<hash<auto>> info, *softbool decode_errors) {
902 hash<auto> h;
903 try {
904 h = send(body, m, path, hdr, False, \info);
905 info."response-code" = h.status_code;
906 } catch (hash<ExceptionInfo> ex) {
907 info."response-code" = info."response-headers".status_code;
908 if (ex.arg) {
909 if (decode_errors && ex.arg.body) {
910 decodeError(ex.arg, \info);
911 ex.arg.deserialized_body = info."response-body";
912 }
913 }
914
915 rethrow ex.err, ex.desc, ex.arg;
916 }
917
918 on_error {
919 if (exists h.body && !exists info."response-body") {
920 info."response-body" = h.body;
921 }
922 }
923
924 return processRestResponse(h, m, path, \info);
925 }
926
928
935protected:
936 hash<auto> processRestResponse(hash<auto> resp, string method, string path, *reference<hash<auto>> info);
937public:
938
939
941protected:
942 static decodeError(hash<auto> h, *reference<hash<auto>> info);
943public:
944
945
947private:
948 static tryDecodeErrorResponse(reference<hash<auto>> h, *reference<hash<auto>> info);
949public:
950
951
952}; // class RestClient
953
955
996
997public:
999 hash<auto> real_opts;
1000
1002 const ConnectionScheme = <ConnectionSchemeInfo>{
1003 "cls": Class::forName("RestConnection"),
1004 "options": HttpConnection::ConnectionScheme.options + {
1005 "content_encoding": <ConnectionOptionInfo>{
1006 "type": "string",
1007 "desc": "this sets the send encoding (if the `send_encoding` option is not set) and the "
1008 "response encoding to request",
1009 "allowed_values": (
1010 <AllowedValueInfo>{
1011 "value": "gzip",
1012 "desc": "use GNU zip encoding ([RFC 1952](https://tools.ietf.org/html/rfc1952))",
1013 }, <AllowedValueInfo>{
1014 "value": "bzip2",
1015 "desc": "use bzip2 encoding",
1016 }, <AllowedValueInfo>{
1017 "value": "deflate",
1018 "desc": "use the deflate algorithm ([RFC 1951](https://tools.ietf.org/html/rfc1951))",
1019 }, <AllowedValueInfo>{
1020 "value": "identity",
1021 "desc": "use no content encoding",
1022 },
1023 ),
1024 },
1025 "data": <ConnectionOptionInfo>{
1026 "type": "string",
1027 "desc": "data serialization options",
1028 "allowed_values": (
1029 <AllowedValueInfo>{
1030 "value": "auto",
1031 "desc": "prefers in this order: `json`, `yaml`, `rawxml`, `xml`, `url`, and `text`",
1032 }, <AllowedValueInfo>{
1033 "value": "bin",
1034 "desc": "for binary message bodies without data serialization",
1035 }, <AllowedValueInfo>{
1036 "value": "json",
1037 "desc": "use JSON serialization",
1038 }, <AllowedValueInfo>{
1039 "value": "rawxml",
1040 "desc": "use raw XML serialization",
1041 }, <AllowedValueInfo>{
1042 "value": "text",
1043 "desc": "use only plain text; no serialization is used",
1044 }, <AllowedValueInfo>{
1045 "value": "url",
1046 "desc": "for URL-encoded message bodies",
1047 }, <AllowedValueInfo>{
1048 "value": "xml",
1049 "desc": "use only XML-RPC serialization",
1050 }, <AllowedValueInfo>{
1051 "value": "yaml",
1052 "desc": "use only YAML serialization",
1053 },
1054 ),
1055 "default_value": "auto",
1056 },
1057 "headers": <ConnectionOptionInfo>{
1058 "type": "hash",
1059 "desc": "an optional hash of headers to send with every request, these can also be "
1060 "overridden in request method calls",
1061 },
1062 "ping_method": <ConnectionOptionInfo>{
1063 "type": "string",
1064 "desc": "The HTTP method to use for an advanced ping; this and `ping_path` must be set to make an "
1065 "HTTP request as a part of the socket polling ping operation; must be a valid HTTP method name",
1066 },
1067 "ping_path": <ConnectionOptionInfo>{
1068 "type": "string",
1069 "desc": "The URI path to use for an advanced ping; this and `ping_method` must be made to make an "
1070 "HTTP request as a part of the socket polling ping operation",
1071 },
1072 "ping_headers": <ConnectionOptionInfo>{
1073 "type": "hash",
1074 "desc": "Any HTTP headers to send when performing an advanced ping operation; ignored if either "
1075 "one of `ping_method` and `ping_path` are not set",
1076 },
1077 "ping_body": <ConnectionOptionInfo>{
1078 "type": "auto",
1079 "desc": "Any message body to send when performing an advanced ping operation; ignored if either "
1080 "one of `ping_method` and `ping_path` are not set or if `ping_method` is `GET`",
1081 },
1082 "send_encoding": <ConnectionOptionInfo>{
1083 "type": "string",
1084 "desc": "this sets the send encoding",
1085 "allowed_values": (
1086 <AllowedValueInfo>{
1087 "value": "gzip",
1088 "desc": "use GNU zip encoding ([RFC 1952](https://tools.ietf.org/html/rfc1952))",
1089 }, <AllowedValueInfo>{
1090 "value": "bzip2",
1091 "desc": "use bzip2 encoding",
1092 }, <AllowedValueInfo>{
1093 "value": "deflate",
1094 "desc": "use the deflate algorithm ([RFC 1951](https://tools.ietf.org/html/rfc1951))",
1095 }, <AllowedValueInfo>{
1096 "value": "identity",
1097 "desc": "use no content encoding",
1098 },
1099 ),
1100 },
1101 "swagger": <ConnectionOptionInfo>{
1102 "type": "file-as-string",
1103 "desc": "the location of a Swagger schema to use for message validation; processed with "
1104 "`FileLocationHandler::getTextFileFromLocation()` "
1105 "(ex: `file:///path/to/swagger-schema.json`); conflicts with `validator`",
1106 "freeform": True,
1107 },
1108 "swagger_base_path": <ConnectionOptionInfo>{
1109 "type": "string",
1110 "desc": "in case a REST validator is used, the base path in the schema can be overridden "
1111 "with this option (applies to any REST validator; not just Swagger validators)",
1112 },
1113 "validator": <ConnectionOptionInfo>{
1114 "type": "any",
1115 "desc": "an `AbstractRestSchemaValidator` object for REST message validation; conflicts with "
1116 "`swagger`",
1117 },
1118 },
1119 };
1120
1122 const Options = map {$1: True}, keys ConnectionScheme.options;
1123
1125 const DefaultOptions = ...;
1126
1127
1129 const OptionList = keys ConnectionScheme.options;
1130
1132
1145 constructor(string name, string description, string url, hash<auto> attributes = {}, hash<auto> options = {})
1146 ;
1147
1148
1150
1158protected:
1159 RestClient getImpl(bool connect = True, *hash<auto> rtopts);
1160public:
1161
1162
1164
1168 object getPollImpl();
1169
1170
1172
1203 hash<auto> getOptions();
1204
1205
1207 *hash<auto> getDefaultOptions();
1208
1209
1211 string getType();
1212
1213
1215
1222
1223
1225
1230
1231
1233
1239
1240
1242
1244 static hash<auto> processOptions(*hash<auto> opts);
1245
1247
1249protected:
1251public:
1252
1253
1255protected:
1257public:
1258
1259
1261protected:
1262 hash<ConnectionSchemeInfo> getConnectionSchemeInfoImpl();
1263public:
1264
1265};
1266
1268
1271
1272public:
1273protected:
1275 AbstractPollOperation poller;
1276
1278 bool goal_reached = False;
1279
1281 Mutex m();
1282
1283public:
1284
1286 constructor(AbstractPollOperation poller);
1287
1288
1290
1292 string getGoal();
1293
1294
1296
1298 string getState();
1299
1300
1302
1305
1306
1308 *hash<SocketPollInfo> continuePoll();
1309
1310};
1311};
hash< auto > patch(string path, auto body, *reference< hash< auto > > info, *hash< auto > hdr)
sends an HTTP PATCH request to the REST server and returns the response
static tryDecodeErrorResponse(reference< hash< auto > > h, *reference< hash< auto > > info)
tries to decode an error response
const VersionString
RestClient Version String.
Definition: RestClient.qm.dox.h:266
constructor(*hash< auto > opts, *softbool do_not_connect)
calls the base class HTTPClient constructor and optionally connects to the REST server
hash< auto > post(string path, auto body, *reference< hash< auto > > info, *hash< auto > hdr)
sends an HTTP POST request to the REST server and returns the response
hash< auto > get(string path, auto body, *reference< hash< auto > > info, *hash< auto > hdr)
sends an HTTP GET request to the REST server and returns the response
setContentEncoding(string enc='auto')
sets the request and desired response encoding for the object; see EncodingSupport for valid options
nothing preparePath(reference< string > path)
sets up the path for the HTTP request URI
hash< auto > getDefaultHeaders()
returns the hash of default headers to sent in all requests
hash< auto > del(string path, auto body, *reference< hash< auto > > info, *hash< auto > hdr)
sends an HTTP DELETE request to the REST server and returns the response
hash< auto > doValidatedRequest(string m, string path, auto body, *reference< hash< auto > > info, softbool decode_errors=True, *hash< auto > hdr)
The same as doRequest() except no schema validation is performed on the request.
Definition: RestClient.qm.dox.h:888
hash< auto > put(string path, auto body, *reference< hash< auto > > info, *hash< auto > hdr)
sends an HTTP PUT request to the REST server and returns the response
RestSchemaValidator::AbstractRestSchemaValidator getValidator()
returns the current validator object
setSerialization(string data='auto')
change the serialization option for the object; see DataSerializationOptions for valid options
clearConnectionPath()
Clears the connection path when a validator is present that manages the URI path.
setSendEncoding(string enc='auto')
change the data content encoding (compression) option for the object; see EncodingSupport for valid o...
static decodeError(hash< auto > h, *reference< hash< auto > > info)
decode any REST errors returned if possible
hash< auto > processRestResponse(hash< auto > resp, string method, string path, *reference< hash< auto > > info)
Process the raw REST response received.
hash< auto > doRequest(string m, string path, auto body, *reference< hash< auto > > info, softbool decode_errors=True, *hash< auto > hdr)
sends an HTTP request to the REST server and returns the response
Definition: RestClient.qm.dox.h:870
addDefaultHeaders(hash< auto > h)
adds default headers to each request; these headers will be sent in all requests but can be overridde...
private nothing prepareMsg(string method, string path, reference< auto > body, reference< hash< auto > > hdr, string ct="Content-Type")
sets up the Content-Type header and encodes any body for sending
Definition: RestClient.qm.dox.h:788
string getSerialization()
returns the current data serialization format currently in effect for the object (see DataSerializati...
*string getSendEncoding()
returns the current data content encoding (compression) object or NOTHING if no encoding option is se...
const Version
RestClient Version.
Definition: RestClient.qm.dox.h:263
private hash< auto > sendAndDecodeResponse(*data body, string m, string path, hash< auto > hdr, *reference< hash< auto > > info, *softbool decode_errors)
sends the outgoing HTTP message and recodes the response to data
Definition: RestClient.qm.dox.h:900
class for REST HTTP connections; returns RestClient::RestClient objects
Definition: RestClient.qm.dox.h:995
bool hasDataProvider()
returns True, as this connection always returns a data provider with the getDataProvider() method
*hash< auto > getDefaultOptions()
returns default options
pingImpl()
performs the internal ping
const OptionList
object connection option list
Definition: RestClient.qm.dox.h:1129
constructor(string name, string description, string url, hash< auto > attributes={}, hash< auto > options={})
creates the RestConnection connection object
hash< auto > real_opts
real options used when creating an object
Definition: RestClient.qm.dox.h:999
const Options
object connection options
Definition: RestClient.qm.dox.h:1122
const DefaultOptions
default options
Definition: RestClient.qm.dox.h:1125
hash< ConnectionSchemeInfo > getConnectionSchemeInfoImpl()
Returns the ConnectionSchemeInfo hash for this object.
Qore::AbstractPollOperation startPollConnect()
Called to start a non-blocking polling ping operation on the remote REST server.
object getPollImpl()
Returns an unconnected object for a non-blocking poll operation.
setChildCapabilities()
Sets child data provider capabilities.
RestClient getImpl(bool connect=True, *hash< auto > rtopts)
returns a RestClient object
static hash< auto > processOptions(*hash< auto > opts)
processes options for the constructor
hash< auto > getOptions()
gets options
const ConnectionScheme
Connection entry info.
Definition: RestClient.qm.dox.h:1002
string getType()
returns "rest"
DataProvider::AbstractDataProvider getDataProvider()
returns a data provider object for this connection
REST ping polling class.
Definition: RestClient.qm.dox.h:1270
constructor(AbstractPollOperation poller)
Creates the object with the send/receive poller.
*hash< SocketPollInfo > continuePoll()
Returns a hash to be used for I/O polling or NOTHING in case the poll operation is complete.
string getGoal()
Returns the goal.
bool goalReached()
Returns True when the goal as been reached.
AbstractPollOperation poller
The polling object.
Definition: RestClient.qm.dox.h:1275
bool goal_reached
Goal reached flag.
Definition: RestClient.qm.dox.h:1278
string getState()
Returns the current state.
Mutex m()
Lock for atomicity.
hash< RestRequestClientInfo > processRequest(string method, string path, auto body, *hash< auto > headers, *softlist< string > content_types)
string type(auto arg)
the RestClient namespace contains all the objects in the RestClient module
Definition: RestClient.qm.dox.h:208