VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/rest/RTCRestClientApiBase.cpp@ 74095

Last change on this file since 74095 was 74052, checked in by vboxsync, 6 years ago

IPRT/rest: Started implementing http-signatures for oci. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: RTCRestClientApiBase.cpp 74052 2018-09-03 20:09:45Z vboxsync $ */
2/** @file
3 * IPRT - C++ REST, RTCRestClientApiBase implementation.
4 */
5
6/*
7 * Copyright (C) 2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_REST
32#include <iprt/cpp/restclient.h>
33
34#include <iprt/err.h>
35#include <iprt/http.h>
36#include <iprt/log.h>
37
38
39/**
40 * The destructor.
41 */
42RTCRestClientApiBase::~RTCRestClientApiBase()
43{
44 if (m_hHttp != NIL_RTHTTP)
45 {
46 int rc = RTHttpDestroy(m_hHttp);
47 AssertRC(rc);
48 m_hHttp = NIL_RTHTTP;
49 }
50}
51
52
53int RTCRestClientApiBase::reinitHttpInstance()
54{
55 if (m_hHttp != NIL_RTHTTP)
56 return RTHttpReset(m_hHttp);
57
58 int rc = RTHttpCreate(&m_hHttp);
59 if (RT_FAILURE(rc))
60 m_hHttp = NIL_RTHTTP;
61 return rc;
62}
63
64
65int RTCRestClientApiBase::xmitReady(RTHTTP a_hHttp, RTCString const &a_rStrFullUrl, RTHTTPMETHOD a_enmHttpMethod,
66 RTCString const &a_rStrXmitBody, uint32_t a_fFlags)
67{
68 RT_NOREF(a_hHttp, a_rStrFullUrl, a_enmHttpMethod, a_rStrXmitBody, a_fFlags);
69 return VINF_SUCCESS;
70}
71
72
73int RTCRestClientApiBase::doCall(RTCRestClientRequestBase const &a_rRequest, RTHTTPMETHOD a_enmHttpMethod,
74 RTCRestClientResponseBase *a_pResponse, const char *a_pszMethod, uint32_t a_fFlags)
75{
76 LogFlow(("doCall: %s %s\n", a_pszMethod, RTHttpMethodName(a_enmHttpMethod)));
77
78
79 /*
80 * Reset the response object (allowing reuse of such) and check the request
81 * object for assignment errors.
82 */
83 int rc;
84 RTHTTP hHttp = NIL_RTHTTP;
85
86 a_pResponse->reset();
87 if (!a_rRequest.hasAssignmentErrors())
88 {
89 /*
90 * Initialize the HTTP instance.
91 */
92 rc = reinitHttpInstance();
93 if (RT_SUCCESS(rc))
94 {
95 hHttp = m_hHttp;
96 Assert(hHttp != NIL_RTHTTP);
97
98 /*
99 * Prepare the response side. This may install output callbacks and
100 * indicate this by clearing the ppvBody/ppvHdr variables.
101 */
102 size_t cbHdrs = 0;
103 void *pvHdrs = NULL;
104 void **ppvHdrs = &pvHdrs;
105
106 size_t cbBody = 0;
107 void *pvBody = NULL;
108 void **ppvBody = &pvBody;
109
110 rc = a_pResponse->receivePrepare(hHttp, &ppvBody, &ppvHdrs);
111 if (RT_SUCCESS(rc))
112 {
113 /*
114 * Prepare the request for the transmission.
115 */
116 RTCString strExtraPath;
117 RTCString strQuery;
118 RTCString strXmitBody;
119 rc = a_rRequest.xmitPrepare(&strExtraPath, &strQuery, hHttp, &strXmitBody);
120 if (RT_SUCCESS(rc))
121 {
122 /*
123 * Construct the full URL.
124 */
125 RTCString strFullUrl;
126 rc = strFullUrl.assignNoThrow(m_strBasePath);
127 if (strExtraPath.isNotEmpty())
128 {
129 if (!strExtraPath.startsWith("/") && !strFullUrl.endsWith("/") && RT_SUCCESS(rc))
130 rc = strFullUrl.appendNoThrow('/');
131 if (RT_SUCCESS(rc))
132 rc = strFullUrl.appendNoThrow(strExtraPath);
133 strExtraPath.setNull();
134 }
135 if (strQuery.isNotEmpty())
136 {
137 Assert(strQuery.startsWith("?"));
138 rc = strFullUrl.appendNoThrow(strQuery);
139 strQuery.setNull();
140 }
141 if (RT_SUCCESS(rc))
142 {
143 rc = xmitReady(hHttp, strFullUrl, a_enmHttpMethod, strXmitBody, a_fFlags);
144 if (RT_SUCCESS(rc))
145 {
146 /*
147 * Perform HTTP request.
148 */
149 uint32_t uHttpStatus = 0;
150 rc = RTHttpPerform(hHttp, strFullUrl.c_str(), a_enmHttpMethod,
151 strXmitBody.c_str(), strXmitBody.length(),
152 &uHttpStatus, ppvHdrs, &cbHdrs, ppvBody, &cbBody);
153 if (RT_SUCCESS(rc))
154 {
155 a_rRequest.xmitComplete(uHttpStatus, hHttp);
156
157 /*
158 * Do response processing.
159 */
160 a_pResponse->receiveComplete(uHttpStatus, hHttp);
161 if (pvHdrs)
162 {
163 a_pResponse->consumeHeaders((const char *)pvHdrs, cbHdrs);
164 RTHttpFreeResponse(pvHdrs);
165 }
166 if (pvBody)
167 {
168 a_pResponse->consumeBody((const char *)pvBody, cbBody);
169 RTHttpFreeResponse(pvBody);
170 }
171 a_pResponse->receiveFinal();
172
173 return a_pResponse->getStatus();
174 }
175 }
176 }
177 }
178 a_rRequest.xmitComplete(rc, hHttp);
179 }
180 }
181 }
182 else
183 rc = VERR_NO_MEMORY;
184
185 a_pResponse->receiveComplete(rc, hHttp);
186 RT_NOREF_PV(a_pszMethod);
187
188 return a_pResponse->getStatus();
189}
190
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