Changeset 74126 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 6, 2018 6:29:40 PM (6 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp
r74117 r74126 36 36 37 37 38 /********************************************************************************************************************************* 39 * Defined Constants And Macros * 40 *********************************************************************************************************************************/ 41 /** The default maximum download size. */ 42 #if ARCH_BITS == 32 43 # define RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT _32M 44 #else 45 # define RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT _128M 46 #endif 47 38 48 39 49 /** Default constructor. */ … … 41 51 : RTCRestObjectBase() 42 52 , m_pbData(NULL) 43 , m_cbData(UINT64_MAX) 53 , m_cbAllocated(0) 54 , m_fFreeData(false) 55 , m_cbContentLength(UINT64_MAX) 44 56 , m_pvCallbackData(NULL) 57 , m_strContentType() 58 , m_pfnProducer(NULL) 45 59 , m_pfnConsumer(NULL) 46 , m_pfnProducer(NULL) 47 , m_fFreeData(false) 48 , m_strContentType() 60 , m_cbDownloaded(0) 61 , m_cbMaxDownload(RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT) 49 62 { 50 63 } … … 56 69 RTCRestBinaryString::~RTCRestBinaryString() 57 70 { 58 if (m_pbData) 59 { 60 if (m_fFreeData) 61 RTMemFree(m_pbData); 62 m_pbData = NULL; 63 } 64 m_fFreeData = false; 71 freeData(); 65 72 m_pvCallbackData = NULL; 66 73 m_pfnProducer = NULL; … … 79 86 80 87 88 void RTCRestBinaryString::freeData() 89 { 90 if (m_pbData) 91 { 92 if (m_fFreeData) 93 RTMemFree(m_pbData); 94 m_pbData = NULL; 95 } 96 m_fFreeData = false; 97 m_cbAllocated = 0; 98 m_cbDownloaded = 0; 99 m_cbContentLength = UINT64_MAX; 100 } 101 102 81 103 /********************************************************************************************************************************* 82 104 * Overridden methods * … … 141 163 *********************************************************************************************************************************/ 142 164 165 int RTCRestBinaryString::setContentType(const char *a_pszContentType) 166 { 167 return m_strContentType.assignNoThrow(a_pszContentType); 168 } 169 170 171 int RTCRestBinaryString::setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy /*= true*/) 172 { 173 freeData(); 174 175 if (a_cbData != 0) 176 { 177 if (a_fCopy) 178 { 179 m_pbData = (uint8_t *)RTMemDup(a_pvData, a_cbData); 180 AssertReturn(m_pbData, VERR_NO_MEMORY); 181 m_fFreeData = true; 182 m_cbAllocated = a_cbData; 183 } 184 else 185 { 186 AssertPtrReturn(a_pvData, VERR_INVALID_POINTER); 187 m_pbData = (uint8_t *)a_pvData; 188 } 189 } 190 m_cbContentLength = a_cbData; 191 192 return VINF_SUCCESS; 193 } 194 195 196 void RTCRestBinaryString::setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData /*= NULL*/, 197 uint64_t a_cbContentLength /*= UINT64_MAX*/) 198 { 199 freeData(); 200 201 m_cbContentLength = a_cbContentLength; 202 m_pfnProducer = a_pfnProducer; 203 m_pvCallbackData = a_pvCallbackData; 204 } 205 206 143 207 int RTCRestBinaryString::xmitPrepare(RTHTTP a_hHttp) const 144 208 { 209 AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbContentLength == 0, VERR_INVALID_STATE); 210 211 145 212 /* 146 213 * Set the content type if given. … … 157 224 * Set the content length if given. 158 225 */ 159 if (m_cb Data!= UINT64_MAX)226 if (m_cbContentLength != UINT64_MAX) 160 227 { 161 228 const char *pszContentLength = RTHttpGetHeader(a_hHttp, RT_STR_TUPLE("Content-Length")); 162 AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cb Data,163 ("pszContentLength=%s does not match m_cb Data=%RU64\n", pszContentLength, m_cbData),229 AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cbContentLength, 230 ("pszContentLength=%s does not match m_cbContentLength=%RU64\n", pszContentLength, m_cbContentLength), 164 231 VERR_MISMATCH); 165 232 if (!pszContentLength) 166 233 { 167 234 char szValue[64]; 168 ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cb Data, 10, 0, 0, 0);235 ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbContentLength, 10, 0, 0, 0); 169 236 int rc = RTHttpAddHeader(a_hHttp, "Content-Length", szValue, cchValue, RTHTTPADDHDR_F_BACK); 170 237 AssertRCReturn(rc, rc); … … 175 242 * Register an upload callback. 176 243 */ 177 AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbData == 0, VERR_INVALID_STATE); 178 179 int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, xmitHttpCallback, (RTCRestBinaryString *)this); 244 int rc = RTHttpSetUploadCallback(a_hHttp, m_cbContentLength, xmitHttpCallback, (RTCRestBinaryString *)this); 180 245 AssertRCReturn(rc, rc); 181 246 … … 199 264 * Feed from the memory buffer. 200 265 */ 201 if (offContent < pThis->m_cb Data)202 { 203 uint64_t const cbLeft = pThis->m_cb Data- offContent;266 if (offContent < pThis->m_cbContentLength) 267 { 268 uint64_t const cbLeft = pThis->m_cbContentLength - offContent; 204 269 size_t const cbToCopy = cbLeft >= cbBuf ? cbBuf : (size_t)cbLeft; 205 270 memcpy(pvBuf, &pThis->m_pbData[(size_t)offContent], cbToCopy); … … 217 282 { 218 283 /* Unset the callback. */ 219 int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, NULL, NULL);284 int rc = RTHttpSetUploadCallback(a_hHttp, UINT64_MAX, NULL, NULL); 220 285 AssertRC(rc); 221 286 } 222 287 223 288 289 /********************************************************************************************************************************* 290 * Download related methods * 291 *********************************************************************************************************************************/ 292 293 void RTCRestBinaryString::setMaxDownloadSize(size_t a_cbMaxDownload) 294 { 295 if (a_cbMaxDownload == 0) 296 m_cbMaxDownload = RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT; 297 else 298 m_cbMaxDownload = a_cbMaxDownload; 299 } 300 301 302 void RTCRestBinaryString::setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData /*= NULL*/) 303 { 304 freeData(); 305 306 a_pfnConsumer = a_pfnConsumer; 307 m_pvCallbackData = a_pvCallbackData; 308 } 309 310 311 int RTCRestBinaryString::receivePrepare(RTHTTP a_hHttp, uint32_t a_fCallbackFlags) 312 { 313 /* 314 * Register an download callback. 315 */ 316 int rc = RTHttpSetDownloadCallback(a_hHttp, a_fCallbackFlags, receiveHttpCallback, this); 317 AssertRCReturn(rc, rc); 318 319 return VINF_SUCCESS; 320 } 321 322 323 void RTCRestBinaryString::receiveComplete(RTHTTP a_hHttp) 324 { 325 /* Unset the callback. */ 326 int rc = RTHttpSetDownloadCallback(a_hHttp, RTHTTPDOWNLOAD_F_ANY_STATUS, NULL, NULL); 327 AssertRC(rc); 328 } 329 330 331 /*static*/ DECLCALLBACK(int) 332 RTCRestBinaryString::receiveHttpCallback(RTHTTP hHttp, void const *pvBuf, size_t cbBuf, uint32_t uHttpStatus, 333 uint64_t offContent, uint64_t cbContent, void *pvUser) 334 { 335 RTCRestBinaryString *pThis = (RTCRestBinaryString *)pvUser; 336 Assert(offContent == pThis->m_cbDownloaded); 337 pThis->m_cbContentLength = cbContent; 338 339 /* 340 * Call the user download callback if we've got one. 341 */ 342 if (pThis->m_pfnConsumer) 343 { 344 int rc = pThis->m_pfnConsumer(pThis, pvBuf, cbBuf, uHttpStatus, offContent, cbContent); 345 if (RT_SUCCESS(rc)) 346 pThis->m_cbDownloaded = offContent + cbBuf; 347 return rc; 348 } 349 350 /* 351 * Check download limit before adding more data. 352 */ 353 AssertMsgReturn(offContent + cbBuf <= pThis->m_cbMaxDownload, 354 ("%RU64 + %zu = %RU64; max=%RU64", offContent, cbBuf, offContent + cbBuf, pThis->m_cbMaxDownload), 355 VERR_TOO_MUCH_DATA); 356 if (offContent == 0 && cbContent != UINT64_MAX) 357 AssertMsgReturn(cbContent <= pThis->m_cbMaxDownload, ("cbContent: %RU64; max=%RU64", cbContent, pThis->m_cbMaxDownload), 358 VERR_TOO_MUCH_DATA); 359 360 /* 361 * Make sure we've got buffer space before we copy in the data. 362 */ 363 if (offContent + cbBuf <= pThis->m_cbAllocated) 364 { /* likely, except for the first time. */ } 365 else if (offContent == 0 && cbContent != UINT64_MAX) 366 { 367 void *pvNew = RTMemRealloc(pThis->m_pbData, (size_t)cbContent); 368 if (!pvNew) 369 return VERR_NO_MEMORY; 370 pThis->m_pbData = (uint8_t *)pvNew; 371 pThis->m_cbAllocated = (size_t)cbContent; 372 } 373 else 374 { 375 size_t cbNeeded = offContent + cbBuf; 376 size_t cbNew; 377 if (pThis->m_cbAllocated == 0) 378 cbNew = RT_MAX(_64K, RT_ALIGN_Z(cbNeeded, _64K)); 379 else if (pThis->m_cbAllocated < _64M && cbNeeded <= _64M) 380 { 381 cbNew = pThis->m_cbAllocated * 2; 382 while (cbNew < cbNeeded) 383 cbNew *= 2; 384 } 385 else 386 cbNew = RT_ALIGN_Z(cbNeeded, _32M); 387 388 void *pvNew = RTMemRealloc(pThis->m_pbData, cbNew); 389 if (!pvNew) 390 return VERR_NO_MEMORY; 391 pThis->m_pbData = (uint8_t *)pvNew; 392 pThis->m_cbAllocated = cbNew; 393 } 394 395 /* 396 * Do the copying. 397 */ 398 memcpy(&pThis->m_pbData[(size_t)offContent], pvBuf, cbBuf); 399 pThis->m_cbDownloaded = offContent + cbBuf; 400 401 RT_NOREF(hHttp); 402 return VINF_SUCCESS; 403 } 404 -
trunk/src/VBox/Runtime/generic/http-curl.cpp
r74120 r74126 2906 2906 rtHttpGetDownloadStatusAndLength(pThis); 2907 2907 2908 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS2909 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)2908 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_ANY_STATUS 2909 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus) 2910 2910 { 2911 2911 int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbToAppend, pThis->uDownloadHttpStatus, pThis->offDownloadContent, … … 2990 2990 2991 2991 /* Call the callback if the HTTP status code matches, otherwise let it go to /dev/null. */ 2992 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS2993 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)2992 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_ANY_STATUS 2993 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus) 2994 2994 { 2995 2995 int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbBuf, pThis->uDownloadHttpStatus, pThis->offDownloadContent, … … 3541 3541 PRTHTTPINTERNAL pThis = hHttp; 3542 3542 RTHTTP_VALID_RETURN(pThis); 3543 AssertReturn(!pfnCallback || (fFlags & RTHTTPDOWNLOAD_F_ F_ONLY_STATUS_MASK) != 0, VERR_INVALID_FLAGS);3543 AssertReturn(!pfnCallback || (fFlags & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) != 0, VERR_INVALID_FLAGS); 3544 3544 3545 3545 pThis->pfnDownloadCallback = pfnCallback;
Note:
See TracChangeset
for help on using the changeset viewer.