VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/rest/RTCRestClientResponseBase.cpp@ 73922

Last change on this file since 73922 was 73922, checked in by vboxsync, 7 years ago

iprt/rest: Added error info, copy of http status, and content type to RTCRestClientResponseBase. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: RTCRestClientResponseBase.cpp 73922 2018-08-28 07:30:28Z vboxsync $ */
2/** @file
3 * IPRT - C++ REST, RTCRestClientResponseBase 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#include <iprt/cpp/restbase.h>
32
33#include <iprt/ctype.h>
34#include <iprt/err.h>
35
36
37/**
38 * Default constructor.
39 */
40RTCRestClientResponseBase::RTCRestClientResponseBase()
41 : m_rcStatus(VERR_WRONG_ORDER)
42 , m_rcHttp(VERR_NOT_AVAILABLE)
43 , m_pErrInfo(NULL)
44{
45}
46
47
48/**
49 * Destructor.
50 */
51RTCRestClientResponseBase::~RTCRestClientResponseBase()
52{
53 deleteErrInfo();
54}
55
56
57/**
58 * Copy constructor.
59 */
60RTCRestClientResponseBase::RTCRestClientResponseBase(RTCRestClientResponseBase const &a_rThat)
61 : m_rcStatus(a_rThat.m_rcStatus)
62 , m_rcHttp(a_rThat.m_rcHttp)
63 , m_strContentType(a_rThat.m_strContentType)
64 , m_pErrInfo(NULL)
65{
66 if (m_pErrInfo)
67 copyErrInfo(m_pErrInfo);
68}
69
70
71/**
72 * Copy assignment operator.
73 */
74RTCRestClientResponseBase &RTCRestClientResponseBase::operator=(RTCRestClientResponseBase const &a_rThat)
75{
76 m_rcStatus = a_rThat.m_rcStatus;
77 m_rcHttp = a_rThat.m_rcHttp;
78 m_strContentType = a_rThat.m_strContentType;
79 if (a_rThat.m_pErrInfo)
80 copyErrInfo(a_rThat.m_pErrInfo);
81 else if (m_pErrInfo)
82 deleteErrInfo();
83
84 return *this;
85}
86
87
88int RTCRestClientResponseBase::receivePrepare(RTHTTP a_hHttp, void ***a_pppvHdr, void ***a_pppvBody)
89{
90 RT_NOREF(a_hHttp, a_pppvHdr, a_pppvBody);
91 return VINF_SUCCESS;
92}
93
94
95void RTCRestClientResponseBase::receiveComplete(int a_rcStatus, RTHTTP a_hHttp)
96{
97 RT_NOREF_PV(a_hHttp);
98 m_rcStatus = a_rcStatus;
99 if (a_rcStatus >= 0)
100 m_rcHttp = a_rcStatus;
101}
102
103
104void RTCRestClientResponseBase::consumeHeaders(const char *a_pchData, size_t a_cbData)
105{
106 /*
107 * Get the the content type.
108 */
109 int rc = extractHeaderFromBlob(RT_STR_TUPLE("Content-Type"), a_pchData, a_cbData, &m_strContentType);
110 if (rc == VERR_NOT_FOUND)
111 rc = VINF_SUCCESS;
112 AssertRCReturnVoidStmt(rc, m_rcStatus = rc);
113}
114
115
116void RTCRestClientResponseBase::consumeBody(const char *a_pchData, size_t a_cbData)
117{
118 RT_NOREF(a_pchData, a_cbData);
119}
120
121
122void RTCRestClientResponseBase::receiveFinal()
123{
124}
125
126
127PRTERRINFO RTCRestClientResponseBase::allocErrInfo(void)
128{
129 size_t cbMsg = _4K;
130 m_pErrInfo = (PRTERRINFO)RTMemAllocZ(sizeof(*m_pErrInfo) + cbMsg);
131 if (m_pErrInfo)
132 return RTErrInfoInit(m_pErrInfo, (char *)(m_pErrInfo + 1), cbMsg);
133 return NULL;
134}
135
136
137void RTCRestClientResponseBase::deleteErrInfo(void)
138{
139 if (m_pErrInfo)
140 {
141 RTMemFree(m_pErrInfo);
142 m_pErrInfo = NULL;
143 }
144}
145
146
147void RTCRestClientResponseBase::copyErrInfo(PCRTERRINFO pErrInfo)
148{
149 deleteErrInfo();
150 m_pErrInfo = (PRTERRINFO)RTMemDup(pErrInfo, pErrInfo->cbMsg + sizeof(*pErrInfo));
151 if (m_pErrInfo)
152 {
153 m_pErrInfo->pszMsg = (char *)(m_pErrInfo + 1);
154 m_pErrInfo->apvReserved[0] = NULL;
155 m_pErrInfo->apvReserved[1] = NULL;
156 }
157}
158
159
160int RTCRestClientResponseBase::extractHeaderFromBlob(const char *a_pszField, size_t a_cchField,
161 const char *a_pchData, size_t a_cbData,
162 RTCString *a_pStrDst)
163{
164 char const chUpper0 = RT_C_TO_UPPER(a_pszField[0]);
165 char const chLower0 = RT_C_TO_LOWER(a_pszField[0]);
166 Assert(!RT_C_IS_SPACE(chUpper0));
167
168 while (a_cbData > a_cchField)
169 {
170 /* Determine length of the header name:value combo.
171 Note! Multi-line field values are not currently supported. */
172 const char *pchEol = (const char *)memchr(a_pchData, '\n', a_cbData);
173 while (pchEol && (pchEol == a_pchData || pchEol[-1] != '\r'))
174 pchEol = (const char *)memchr(pchEol, '\n', a_cbData - (pchEol - a_pchData));
175
176 size_t cchField = pchEol ? pchEol - a_pchData + 1 : a_cbData;
177
178 /* Try match */
179 if ( a_pchData[a_cchField] == ':'
180 && ( a_pchData[0] == chUpper0
181 || a_pchData[0] == chLower0)
182 && RTStrNICmpAscii(a_pchData, a_pszField, a_cchField) == 0)
183 {
184 /* Drop CRLF. */
185 if (pchEol)
186 cchField -= 2;
187
188 /* Drop the field name and optional whitespace. */
189 cchField -= a_cchField + 1;
190 a_pchData += a_cchField + 1;
191 if (cchField > 0 && RT_C_IS_BLANK(*a_pchData))
192 {
193 a_pchData++;
194 cchField--;
195 }
196
197 /* Return the value. */
198 int rc = a_pStrDst->assignNoThrow(a_pchData, cchField);
199 if (RT_SUCCESS(rc))
200 RTStrPurgeEncoding(a_pStrDst->mutableRaw());
201 return rc;
202 }
203
204 /* Advance to the next field. */
205 a_pchData += cchField;
206 a_cbData -= cchField;
207 }
208
209 return VERR_NOT_FOUND;
210}
211
Note: See TracBrowser for help on using the repository browser.

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