VirtualBox

source: vbox/trunk/include/iprt/cpp/restclient.h@ 94719

Last change on this file since 94719 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.7 KB
Line 
1/** @file
2 * IPRT - C++ Representational State Transfer (REST) Client Classes.
3 */
4
5/*
6 * Copyright (C) 2008-2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_cpp_restclient_h
27#define IPRT_INCLUDED_cpp_restclient_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/http.h>
33#include <iprt/cpp/restbase.h>
34#include <iprt/cpp/reststringmap.h>
35
36
37/** @defgroup grp_rt_cpp_restclient C++ Representational State Transfer (REST) Client Classes.
38 * @ingroup grp_rt_cpp
39 * @{
40 */
41
42/**
43 * Specialization of RTCRestBinary for use with body parameters in a client.
44 *
45 * This enables registering data callbacks for provinding data to upload.
46 */
47class RT_DECL_CLASS RTCRestBinaryParameter : public RTCRestBinary
48{
49public:
50 /** Default constructor. */
51 RTCRestBinaryParameter() RT_NOEXCEPT;
52
53 /** Safe copy assignment method. */
54 virtual int assignCopy(RTCRestBinaryParameter const &a_rThat) RT_NOEXCEPT;
55 /** Safe copy assignment method.
56 * @note Resets callbacks and ASSUMES that @a a_cbData is the content length. */
57 virtual int assignCopy(RTCRestBinary const &a_rThat) RT_NOEXCEPT RT_OVERRIDE;
58 /** Safe copy assignment method.
59 * @note Resets callbacks and ASSUMES that @a a_cbData is the content length. */
60 virtual int assignCopy(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT RT_OVERRIDE;
61
62 /**
63 * Use the specified data buffer directly.
64 * @note Resets callbacks and ASSUMES that @a a_cbData is the content length. */
65 virtual int assignReadOnly(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT RT_OVERRIDE;
66 /**
67 * Use the specified data buffer directly.
68 * @note This will assert and work like assignReadOnly. */
69 virtual int assignWriteable(void *a_pvBuf, size_t a_cbBuf) RT_NOEXCEPT RT_OVERRIDE;
70
71 /** Make a clone of this object. */
72 inline RTCRestBinaryParameter *clone() const RT_NOEXCEPT { return (RTCRestBinaryParameter *)baseClone(); }
73
74 /* Overridden methods: */
75 virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE;
76 virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE;
77 virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE;
78
79 /** Factory method. */
80 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT;
81
82 /**
83 * Retrieves the callback data.
84 */
85 inline void *getCallbackData() const RT_NOEXCEPT { return m_pvCallbackData; }
86
87 /**
88 * Sets the content-type for an upload.
89 *
90 * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
91 * @param a_pszContentType The content type to set.
92 * If NULL, no content type is set.
93 */
94 int setContentType(const char *a_pszContentType) RT_NOEXCEPT;
95
96 /**
97 * Gets the content type that was set.
98 */
99 inline RTCString const &getContentType() const RT_NOEXCEPT { return m_strContentType; }
100
101 /**
102 * Gets the content-length value (UINT64_MAX if not available).
103 */
104 inline uint64_t getContentLength() const RT_NOEXCEPT { return m_cbContentLength; }
105
106 /**
107 * Callback for producing bytes to upload.
108 *
109 * @returns IPRT status code.
110 * @param a_pThis The related string object.
111 * @param a_pvDst Where to put the bytes.
112 * @param a_cbDst Max number of bytes to produce.
113 * @param a_offContent The byte offset corresponding to the start of @a a_pvDst.
114 * @param a_pcbActual Where to return the number of bytes actually produced.
115 *
116 * @remarks Use getCallbackData to get the user data.
117 *
118 * @note The @a a_offContent parameter does not imply random access or anthing
119 * like that, it is just a convenience provided by the caller. The value
120 * is the sum of the previously returned @a *pcbActual values.
121 */
122 typedef DECLCALLBACKTYPE(int, FNPRODUCER,(RTCRestBinaryParameter *a_pThis, void *a_pvDst, size_t a_cbDst,
123 uint64_t a_offContent, size_t *a_pcbActual)) /*RT_NOEXCEPT*/;
124 /** Pointer to a byte producer callback. */
125 typedef FNPRODUCER *PFNPRODUCER;
126
127 /**
128 * Sets the producer callback.
129 *
130 * @param a_pfnProducer The callback function for producing data.
131 * @param a_pvCallbackData Data the can be retrieved from the callback
132 * using getCallbackData().
133 * @param a_cbContentLength The amount of data that will be uploaded and
134 * to be set as the value of the content-length
135 * header field. Pass UINT64_MAX if not known.
136 *
137 * @note This will drop any buffer previously registered using setUploadData().
138 */
139 void setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData = NULL, uint64_t a_cbContentLength = UINT64_MAX) RT_NOEXCEPT;
140
141 /**
142 * Preprares transmission via the @a a_hHttp client instance.
143 *
144 * @returns IPRT status code.
145 * @param a_hHttp The HTTP client instance.
146 * @internal
147 */
148 virtual int xmitPrepare(RTHTTP a_hHttp) const RT_NOEXCEPT;
149
150 /**
151 * For completing and/or undoing setup from xmitPrepare.
152 *
153 * @param a_hHttp The HTTP client instance.
154 * @internal
155 */
156 virtual void xmitComplete(RTHTTP a_hHttp) const RT_NOEXCEPT;
157
158protected:
159 /** Number of bytes corresponding to content-length.
160 * UINT64_MAX if not known. Used both for unploads and downloads. */
161 uint64_t m_cbContentLength;
162 /** The content type if set (upload only). */
163 RTCString m_strContentType;
164 /** Pointer to user-registered producer callback function (upload only). */
165 PFNPRODUCER m_pfnProducer;
166 /** User argument for both callbacks (both). */
167 void *m_pvCallbackData;
168
169 /** @copydoc FNRTHTTPUPLOADCALLBACK */
170 static DECLCALLBACK(int) xmitHttpCallback(RTHTTP hHttp, void *pvBuf, size_t cbBuf, uint64_t offContent,
171 size_t *pcbActual, void *pvUser) RT_NOEXCEPT;
172
173private:
174 /* No copy constructor or copy assignment: */
175 RTCRestBinaryParameter(RTCRestBinaryParameter const &a_rThat);
176 RTCRestBinaryParameter &operator=(RTCRestBinaryParameter const &a_rThat);
177};
178
179
180/**
181 * Specialization of RTCRestBinary for use with responses in a client.
182 *
183 * This enables registering data callbacks for consuming downloaded data.
184 */
185class RT_DECL_CLASS RTCRestBinaryResponse : public RTCRestBinary
186{
187public:
188 /** Default constructor. */
189 RTCRestBinaryResponse() RT_NOEXCEPT;
190
191 /** Safe copy assignment method. */
192 virtual int assignCopy(RTCRestBinaryResponse const &a_rThat) RT_NOEXCEPT;
193 /** Safe copy assignment method. */
194 virtual int assignCopy(RTCRestBinary const &a_rThat) RT_NOEXCEPT RT_OVERRIDE;
195 /** Safe copy assignment method.
196 * @note This will assert and fail as it makes no sense for a download. */
197 virtual int assignCopy(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT RT_OVERRIDE;
198
199 /**
200 * Use the specified data buffer directly.
201 * @note This will assert and fail as it makes no sense for a download.
202 */
203 virtual int assignReadOnly(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT RT_OVERRIDE;
204 /**
205 * Use the specified data buffer directly.
206 * @note This will drop any previously registered producer callback and user data.
207 */
208 virtual int assignWriteable(void *a_pvBuf, size_t a_cbBuf) RT_NOEXCEPT RT_OVERRIDE;
209
210 /** Make a clone of this object. */
211 inline RTCRestBinaryResponse *clone() const RT_NOEXCEPT { return (RTCRestBinaryResponse *)baseClone(); }
212
213 /* Overridden methods: */
214 virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE;
215 virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE;
216 virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE;
217
218 /** Factory method. */
219 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT;
220
221 /**
222 * Retrieves the callback data.
223 */
224 inline void *getCallbackData() const RT_NOEXCEPT { return m_pvCallbackData; }
225
226 /**
227 * Sets the max size to download to memory.
228 *
229 * This also indicates the intention to download to a memory buffer, so it
230 * will drop any previously registered consumer callback and its user data.
231 *
232 * @param a_cbMaxDownload Maximum number of bytes to download to memory.
233 * If 0, a default is selected (currently 32MiB for
234 * 32-bit hosts and 128MiB for 64-bit).
235 */
236 void setMaxDownloadSize(size_t a_cbMaxDownload) RT_NOEXCEPT;
237
238 /**
239 * Gets the content-length value (UINT64_MAX if not available).
240 */
241 inline uint64_t getContentLength() const RT_NOEXCEPT { return m_cbContentLength; }
242
243 /**
244 * Callback for consuming downloaded bytes.
245 *
246 * @returns IPRT status code.
247 * @param a_pThis The related string object.
248 * @param a_pvSrc Buffer containing the bytes.
249 * @param a_cbSrc The number of bytes in the buffer.
250 * @param a_uHttpStatus The HTTP status code.
251 * @param a_offContent The byte offset corresponding to the start of @a a_pvSrc.
252 * @param a_cbContent The content length field value, UINT64_MAX if not available.
253 *
254 * @remarks Use getCallbackData to get the user data.
255 *
256 * @note The @a a_offContent parameter does not imply random access or anthing
257 * like that, it is just a convenience provided by the caller. The value
258 * is the sum of the previous @a a_cbSrc values.
259 */
260 typedef DECLCALLBACKTYPE(int, FNCONSUMER,(RTCRestBinaryResponse *a_pThis, const void *a_pvSrc, size_t a_cbSrc,
261 uint32_t a_uHttpStatus, uint64_t a_offContent, uint64_t a_cbContent)) /*RT_NOEXCEPT*/;
262 /** Pointer to a byte consumer callback. */
263 typedef FNCONSUMER *PFNCONSUMER;
264
265 /**
266 * Sets the consumer callback.
267 *
268 * @param a_pfnConsumer The callback function for consuming downloaded data.
269 * NULL if data should be stored in m_pbData (the default).
270 * @param a_pvCallbackData Data the can be retrieved from the callback
271 * using getCallbackData().
272 */
273 void setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData = NULL) RT_NOEXCEPT;
274
275 /**
276 * Preprares for receiving via the @a a_hHttp client instance.
277 *
278 * @returns IPRT status code.
279 * @param a_hHttp The HTTP client instance.
280 * @param a_fCallbackFlags The HTTP callback flags (status code spec).
281 * @internal
282 */
283 virtual int receivePrepare(RTHTTP a_hHttp, uint32_t a_fCallbackFlags) RT_NOEXCEPT;
284
285 /**
286 * For completing and/or undoing setup from receivePrepare.
287 *
288 * @param a_hHttp The HTTP client instance.
289 * @internal
290 */
291 virtual void receiveComplete(RTHTTP a_hHttp) RT_NOEXCEPT;
292
293protected:
294 /** Number of bytes corresponding to content-length.
295 * UINT64_MAX if not known. Used both for unploads and downloads. */
296 uint64_t m_cbContentLength;
297 /** Number of bytes downloaded thus far. */
298 uint64_t m_cbDownloaded;
299 /** Pointer to user-registered consumer callback function (download only). */
300 PFNCONSUMER m_pfnConsumer;
301 /** User argument for both callbacks (both). */
302 void *m_pvCallbackData;
303 /** Maximum data to download to memory (download only). */
304 size_t m_cbMaxDownload;
305
306 /** @copydoc FNRTHTTPDOWNLOADCALLBACK */
307 static DECLCALLBACK(int) receiveHttpCallback(RTHTTP hHttp, void const *pvBuf, size_t cbBuf, uint32_t uHttpStatus,
308 uint64_t offContent, uint64_t cbContent, void *pvUser) RT_NOEXCEPT;
309
310private:
311 /* No copy constructor or copy assignment: */
312 RTCRestBinaryResponse(RTCRestBinaryResponse const &a_rThat);
313 RTCRestBinaryResponse &operator=(RTCRestBinaryResponse const &a_rThat);
314};
315
316
317/**
318 * Base class for REST client requests.
319 *
320 * This encapsulates parameters and helps transform them into a HTTP request.
321 *
322 * Parameters can be transfered in a number of places:
323 * - Path part of the URL.
324 * - Query part of the URL.
325 * - HTTP header fields.
326 * - FORM body.
327 * - JSON body.
328 * - XML body.
329 * - ...
330 *
331 * They can be require or optional. The latter may have default values. In
332 * swagger 3 they can also be nullable, which means the null-indicator cannot
333 * be used for tracking optional parameters.
334 */
335class RT_DECL_CLASS RTCRestClientRequestBase
336{
337public:
338 RTCRestClientRequestBase() RT_NOEXCEPT;
339 virtual ~RTCRestClientRequestBase();
340 RTCRestClientRequestBase(RTCRestClientRequestBase const &a_rThat) RT_NOEXCEPT;
341 RTCRestClientRequestBase &operator=(RTCRestClientRequestBase const &a_rThat) RT_NOEXCEPT;
342
343 /**
344 * Reset all members to default values.
345 * @returns IPRT status code.
346 */
347 virtual int resetToDefault() RT_NOEXCEPT = 0;
348
349 /**
350 * Getter for the operation name. Provided by the generated
351 * subclasses so that base class code may use it for more
352 * informative logs.
353 */
354 virtual const char *getOperationName() const RT_NOEXCEPT = 0;
355
356 /**
357 * Prepares the HTTP handle for transmitting this request.
358 *
359 * @returns IPRT status code.
360 * @param a_pStrPath Where to set path parameters. Will be appended to the base path.
361 * @param a_pStrQuery Where to set query parameters.
362 * @param a_hHttp Where to set header parameters and such.
363 * @param a_pStrBody Where to set body parameters.
364 */
365 virtual int xmitPrepare(RTCString *a_pStrPath, RTCString *a_pStrQuery, RTHTTP a_hHttp, RTCString *a_pStrBody) const RT_NOEXCEPT = 0;
366
367 /**
368 * Always called after the request has been transmitted.
369 *
370 * @param a_rcStatus Negative numbers are IPRT errors, positive are HTTP status codes.
371 * @param a_hHttp The HTTP handle the request was performed on.
372 */
373 virtual void xmitComplete(int a_rcStatus, RTHTTP a_hHttp) const RT_NOEXCEPT = 0;
374
375 /**
376 * Checks if there are were any assignment errors.
377 */
378 inline bool hasAssignmentErrors() const RT_NOEXCEPT { return m_fErrorSet != 0; }
379
380protected:
381 /** Set of fields that have been explicitly assigned a value. */
382 uint64_t m_fIsSet;
383 /** Set of fields where value assigning failed. */
384 uint64_t m_fErrorSet;
385
386 /** Path parameter descriptor. */
387 typedef struct
388 {
389 const char *pszName; /**< The name string to replace (including {}). */
390 size_t cchName; /**< Length of pszName. */
391 uint32_t fFlags; /**< The toString flags. */
392 uint8_t iBitNo; /**< The parameter bit number. */
393 } PATHPARAMDESC;
394
395 /** Path parameter state. */
396 typedef struct
397 {
398 RTCRestObjectBase const *pObj; /**< Pointer to the parameter object. */
399 size_t offName; /**< Maintained by worker. */
400 } PATHPARAMSTATE;
401
402 /**
403 * Do path parameters.
404 *
405 * @returns IPRT status code
406 * @param a_pStrPath The destination path.
407 * @param a_pszPathTemplate The path template string.
408 * @param a_cchPathTemplate The length of the path template string.
409 * @param a_paPathParams The path parameter descriptors (static).
410 * @param a_paPathParamStates The path parameter objects and states.
411 * @param a_cPathParams Number of path parameters.
412 */
413 int doPathParameters(RTCString *a_pStrPath, const char *a_pszPathTemplate, size_t a_cchPathTemplate,
414 PATHPARAMDESC const *a_paPathParams, PATHPARAMSTATE *a_paPathParamStates, size_t a_cPathParams) const RT_NOEXCEPT;
415
416 /** Query parameter descriptor. */
417 typedef struct
418 {
419 const char *pszName; /**< The parameter name. */
420 uint32_t fFlags; /**< The toString flags. */
421 bool fRequired; /**< Required or not. */
422 uint8_t iBitNo; /**< The parameter bit number. */
423 } QUERYPARAMDESC;
424
425 /**
426 * Do query parameters.
427 *
428 * @returns IPRT status code
429 * @param a_pStrQuery The destination string.
430 * @param a_paQueryParams The query parameter descriptors.
431 * @param a_papQueryParamObjs The query parameter objects, parallel to @a a_paQueryParams.
432 * @param a_cQueryParams Number of query parameters.
433 */
434 int doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
435 RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const RT_NOEXCEPT;
436
437 /** Header parameter descriptor. */
438 typedef struct
439 {
440 const char *pszName; /**< The parameter name. */
441 uint32_t fFlags; /**< The toString flags. */
442 bool fRequired; /**< Required or not. */
443 uint8_t iBitNo; /**< The parameter bit number. */
444 bool fMapCollection; /**< Collect headers starting with pszName into a map. */
445 } HEADERPARAMDESC;
446
447 /**
448 * Do header parameters.
449 *
450 * @returns IPRT status code
451 * @param a_hHttp Where to set header parameters.
452 * @param a_paHeaderParams The header parameter descriptors.
453 * @param a_papHeaderParamObjs The header parameter objects, parallel to @a a_paHeaderParams.
454 * @param a_cHeaderParams Number of header parameters.
455 */
456 int doHeaderParameters(RTHTTP a_hHttp, HEADERPARAMDESC const *a_paHeaderParams,
457 RTCRestObjectBase const **a_papHeaderParamObjs, size_t a_cHeaderParams) const RT_NOEXCEPT;
458};
459
460
461/**
462 * Base class for REST client responses.
463 */
464class RT_DECL_CLASS RTCRestClientResponseBase
465{
466public:
467 /** Default constructor. */
468 RTCRestClientResponseBase() RT_NOEXCEPT;
469 /** Destructor. */
470 virtual ~RTCRestClientResponseBase();
471 /** Copy constructor. */
472 RTCRestClientResponseBase(RTCRestClientResponseBase const &a_rThat);
473 /** Copy assignment operator. */
474 RTCRestClientResponseBase &operator=(RTCRestClientResponseBase const &a_rThat);
475
476 /**
477 * Resets the object state.
478 */
479 virtual void reset(void) RT_NOEXCEPT;
480
481 /**
482 * Getter for the operation name. Provided by the generated
483 * subclasses so that base class code may use it for more
484 * informative logs.
485 */
486 virtual const char *getOperationName() const RT_NOEXCEPT = 0;
487
488 /**
489 * Prepares the HTTP handle for receiving the response.
490 *
491 * This may install callbacks and such like.
492 *
493 * When overridden, the parent class must always be called.
494 *
495 * @returns IPRT status code.
496 * @param a_hHttp The HTTP handle to prepare for receiving.
497 */
498 virtual int receivePrepare(RTHTTP a_hHttp) RT_NOEXCEPT;
499
500 /**
501 * Called when the HTTP request has been completely received.
502 *
503 * @param a_rcStatus Negative numbers are IPRT errors, positive are HTTP status codes.
504 * @param a_hHttp The HTTP handle the request was performed on.
505 * This can be NIL_RTHTTP should something fail early, in
506 * which case it is possible receivePrepare() wasn't called.
507 *
508 * @note Called before consumeBody() but after consumeHeader().
509 */
510 virtual void receiveComplete(int a_rcStatus, RTHTTP a_hHttp) RT_NOEXCEPT;
511
512 /**
513 * Callback that consumes HTTP body data from the server.
514 *
515 * @param a_pchData Body data.
516 * @param a_cbData Amount of body data.
517 *
518 * @note Called after consumeHeader().
519 */
520 virtual void consumeBody(const char *a_pchData, size_t a_cbData) RT_NOEXCEPT;
521
522 /**
523 * Called after status, headers and body all have been presented.
524 *
525 * @returns IPRT status code.
526 */
527 virtual void receiveFinal() RT_NOEXCEPT;
528
529 /**
530 * Getter for m_rcStatus.
531 * @returns Negative numbers are IPRT errors, positive are HTTP status codes.
532 */
533 inline int getStatus() const RT_NOEXCEPT { return m_rcStatus; }
534
535 /**
536 * Getter for m_rcHttp.
537 * @returns HTTP status code or VERR_NOT_AVAILABLE.
538 */
539 inline int getHttpStatus() const RT_NOEXCEPT { return m_rcHttp; }
540
541 /**
542 * Getter for m_pErrInfo.
543 */
544 inline PCRTERRINFO getErrInfo(void) const RT_NOEXCEPT { return m_pErrInfo; }
545
546 /**
547 * Getter for m_strContentType.
548 */
549 inline RTCString const &getContentType(void) const RT_NOEXCEPT { return m_strContentType; }
550
551
552protected:
553 /** Negative numbers are IPRT errors, positive are HTTP status codes. */
554 int m_rcStatus;
555 /** The HTTP status code, VERR_NOT_AVAILABLE if not set. */
556 int m_rcHttp;
557 /** Error information. */
558 PRTERRINFO m_pErrInfo;
559 /** The value of the Content-Type header field. */
560 RTCString m_strContentType;
561
562 PRTERRINFO getErrInfoInternal(void) RT_NOEXCEPT;
563 void deleteErrInfo(void) RT_NOEXCEPT;
564 void copyErrInfo(PCRTERRINFO pErrInfo) RT_NOEXCEPT;
565
566 /**
567 * Reports an error (or warning if a_rc non-negative).
568 *
569 * @returns a_rc
570 * @param a_rc The status code to report and return. The first
571 * error status is assigned to m_rcStatus, subsequent
572 * ones as well as informational statuses are not
573 * recorded by m_rcStatus.
574 * @param a_pszFormat The message format string.
575 * @param ... Message arguments.
576 */
577 int addError(int a_rc, const char *a_pszFormat, ...) RT_NOEXCEPT;
578
579 /**
580 * Deserializes a header field value.
581 *
582 * @returns IPRT status code.
583 * @param a_pObj The object to deserialize into.
584 * @param a_pchValue Pointer to the value (not zero terminated).
585 * Not necessarily valid UTF-8!
586 * @param a_cchValue The value length.
587 * @param a_fFlags Flags to pass to fromString().
588 * @param a_pszErrorTag The error tag (field name).
589 */
590 int deserializeHeader(RTCRestObjectBase *a_pObj, const char *a_pchValue, size_t a_cchValue,
591 uint32_t a_fFlags, const char *a_pszErrorTag) RT_NOEXCEPT;
592
593 /**
594 * Deserializes a header field value.
595 *
596 * @returns IPRT status code.
597 * @param a_pMap The string map object to deserialize into.
598 * @param a_pchField Pointer to the map field name. (Caller dropped the prefix.)
599 * Not necessarily valid UTF-8!
600 * @param a_cchField Length of field name.
601 * @param a_pchValue Pointer to the value (not zero terminated).
602 * Not necessarily valid UTF-8!
603 * @param a_cchValue The value length.
604 * @param a_fFlags Flags to pass to fromString().
605 * @param a_pszErrorTag The error tag (field name).
606 */
607 int deserializeHeaderIntoMap(RTCRestStringMapBase *a_pMap, const char *a_pchField, size_t a_cchField,
608 const char *a_pchValue, size_t a_cchValue, uint32_t a_fFlags, const char *a_pszErrorTag) RT_NOEXCEPT;
609
610 /**
611 * Helper that does the deserializing of the response body
612 * via deserializeBodyFromJsonCursor().
613 *
614 * @param a_pchData The body blob.
615 * @param a_cbData The size of the body blob.
616 * @param a_pszBodyName The name of the body parameter.
617 */
618 void deserializeBody(const char *a_pchData, size_t a_cbData, const char *a_pszBodyName) RT_NOEXCEPT;
619
620 /**
621 * Called by deserializeBody to do the actual body deserialization.
622 *
623 * @param a_rCursor The JSON cursor.
624 */
625 virtual void deserializeBodyFromJsonCursor(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT;
626
627 /**
628 * Primary json cursor for parsing bodies.
629 */
630 class PrimaryJsonCursorForBody : public RTCRestJsonPrimaryCursor
631 {
632 public:
633 RTCRestClientResponseBase *m_pThat; /**< Pointer to response object. */
634 PrimaryJsonCursorForBody(RTJSONVAL hValue, const char *pszName, RTCRestClientResponseBase *a_pThat) RT_NOEXCEPT;
635 virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...) RT_NOEXCEPT RT_OVERRIDE;
636 virtual int unknownField(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE;
637 };
638
639
640 /**
641 * Consumes a header.
642 *
643 * Child classes can override this to pick up their header fields, but must
644 * always call the parent class.
645 *
646 * @returns IPRT status code.
647 * @param a_uMatchWord Match word constructed by RTHTTP_MAKE_HDR_MATCH_WORD
648 * @param a_pchField The field name (not zero terminated).
649 * Not necessarily valid UTF-8!
650 * @param a_cchField The length of the field.
651 * @param a_pchValue The field value (not zero terminated).
652 * @param a_cchValue The length of the value.
653 */
654 virtual int consumeHeader(uint32_t a_uMatchWord, const char *a_pchField, size_t a_cchField,
655 const char *a_pchValue, size_t a_cchValue) RT_NOEXCEPT;
656
657private:
658 /** Callback for use with RTHttpSetHeaderCallback. */
659 static DECLCALLBACK(int) receiveHttpHeaderCallback(RTHTTP hHttp, uint32_t uMatchWord, const char *pchField, size_t cchField,
660 const char *pchValue, size_t cchValue, void *pvUser) RT_NOEXCEPT;
661};
662
663
664/**
665 * Base class for REST client responses.
666 */
667class RT_DECL_CLASS RTCRestClientApiBase
668{
669public:
670 RTCRestClientApiBase() RT_NOEXCEPT;
671 virtual ~RTCRestClientApiBase();
672
673 /** @name Host and Base path (URL) handling.
674 * @{ */
675 /**
676 * Gets the server URL.
677 */
678 const char *getServerUrl(void) const RT_NOEXCEPT;
679
680 /**
681 * Sets the whole server URL.
682 * @returns IPRT status code.
683 * @param a_pszUrl The new server URL. NULL/empty to reset to default.
684 */
685 int setServerUrl(const char *a_pszUrl) RT_NOEXCEPT;
686
687 /**
688 * Sets the scheme part of the the server URL.
689 * @returns IPRT status code.
690 * @param a_pszScheme The new scheme. Does not accept NULL or empty string.
691 */
692 int setServerScheme(const char *a_pszScheme) RT_NOEXCEPT;
693
694 /**
695 * Sets the authority (hostname + port) part of the the server URL.
696 * @returns IPRT status code.
697 * @param a_pszAuthority The new authority. Does not accept NULL or empty string.
698 */
699 int setServerAuthority(const char *a_pszAuthority) RT_NOEXCEPT;
700
701 /**
702 * Sets the base path part of the the server URL.
703 * @returns IPRT status code.
704 * @param a_pszBasePath The new base path. Does not accept NULL or empty string.
705 */
706 int setServerBasePath(const char *a_pszBasePath) RT_NOEXCEPT;
707
708 /**
709 * Gets the default server URL as specified in the specs.
710 * @returns Server URL.
711 */
712 virtual const char *getDefaultServerUrl() const RT_NOEXCEPT = 0;
713
714 /**
715 * Gets the default server base path as specified in the specs.
716 * @returns Host string (start of URL).
717 */
718 virtual const char *getDefaultServerBasePath() const RT_NOEXCEPT = 0;
719 /** @} */
720
721 /**
722 * Sets the CA file to use for HTTPS.
723 */
724 int setCAFile(const char *pcszCAFile) RT_NOEXCEPT;
725 /** @overload */
726 int setCAFile(const RTCString &strCAFile) RT_NOEXCEPT;
727
728 /** Flags to doCall. */
729 enum
730 {
731 kDoCall_OciReqSignExcludeBody = 1, /**< Exclude the body when doing OCI request signing. */
732 kDoCall_RequireBody = 2 /**< The body is required. */
733 };
734
735protected:
736 /** Handle to the HTTP connection object. */
737 RTHTTP m_hHttp;
738 /** The server URL to use. If empty use the default. */
739 RTCString m_strServerUrl;
740 /** The CA file to use. If empty use the default. */
741 RTCString m_strCAFile;
742
743 /* Make non-copyable (RTCNonCopyable causes warnings): */
744 RTCRestClientApiBase(RTCRestClientApiBase const &);
745 RTCRestClientApiBase *operator=(RTCRestClientApiBase const &);
746
747 /**
748 * Re-initializes the HTTP instance.
749 *
750 * @returns IPRT status code.
751 */
752 virtual int reinitHttpInstance() RT_NOEXCEPT;
753
754 /**
755 * Hook that's called when doCall has fully assembled the request.
756 *
757 * Can be used for request signing and similar final steps.
758 *
759 * @returns IPRT status code.
760 * @param a_hHttp The HTTP client instance.
761 * @param a_rStrFullUrl The full URL.
762 * @param a_enmHttpMethod The HTTP request method.
763 * @param a_rStrXmitBody The body text.
764 * @param a_fFlags kDoCall_XXX.
765 */
766 virtual int xmitReady(RTHTTP a_hHttp, RTCString const &a_rStrFullUrl, RTHTTPMETHOD a_enmHttpMethod,
767 RTCString const &a_rStrXmitBody, uint32_t a_fFlags) RT_NOEXCEPT;
768
769 /**
770 * Implements stuff for making an API call.
771 *
772 * @returns a_pResponse->getStatus()
773 * @param a_rRequest Reference to the request object.
774 * @param a_enmHttpMethod The HTTP request method.
775 * @param a_pResponse Pointer to the response object.
776 * @param a_pszMethod The method name, for logging purposes.
777 * @param a_fFlags kDoCall_XXX.
778 */
779 virtual int doCall(RTCRestClientRequestBase const &a_rRequest, RTHTTPMETHOD a_enmHttpMethod,
780 RTCRestClientResponseBase *a_pResponse, const char *a_pszMethod, uint32_t a_fFlags) RT_NOEXCEPT;
781
782 /**
783 * Implements OCI style request signing.
784 *
785 * @returns IPRT status code.
786 * @param a_hHttp The HTTP client instance.
787 * @param a_rStrFullUrl The full URL.
788 * @param a_enmHttpMethod The HTTP request method.
789 * @param a_rStrXmitBody The body text.
790 * @param a_fFlags kDoCall_XXX.
791 * @param a_hKey The key to use for signing.
792 * @param a_rStrKeyId The key ID.
793 *
794 * @remarks The signing scheme is covered by a series of drafts RFC, the latest being:
795 * https://tools.ietf.org/html/draft-cavage-http-signatures-10
796 */
797 int ociSignRequest(RTHTTP a_hHttp, RTCString const &a_rStrFullUrl, RTHTTPMETHOD a_enmHttpMethod,
798 RTCString const &a_rStrXmitBody, uint32_t a_fFlags, RTCRKEY a_hKey, RTCString const &a_rStrKeyId) RT_NOEXCEPT;
799
800 /**
801 * Worker for the server URL modifiers.
802 *
803 * @returns IPRT status code.
804 * @param a_pszServerUrl The current server URL (for comparing).
805 * @param a_offDst The offset of the component in the current server URL.
806 * @param a_cchDst The current component length.
807 * @param a_pszSrc The new URL component value.
808 * @param a_cchSrc The length of the new component.
809 */
810 int setServerUrlPart(const char *a_pszServerUrl, size_t a_offDst, size_t a_cchDst, const char *a_pszSrc, size_t a_cchSrc) RT_NOEXCEPT;
811};
812
813/** @} */
814
815#endif /* !IPRT_INCLUDED_cpp_restclient_h */
816
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette