VirtualBox

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

Last change on this file was 99739, checked in by vboxsync, 13 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

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

© 2023 Oracle
ContactPrivacy policyTerms of Use