- Timestamp:
- Sep 5, 2018 5:41:03 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/http-curl.cpp
r74077 r74090 216 216 int rcOutput; 217 217 218 /** @name Upload callback 219 * @{ */ 220 /** Pointer to the download callback function, if anyn. */ 221 PFNRTHTTPUPLOADCALLBACK pfnUploadCallback; 222 /** The user argument for the upload callback function. */ 223 void *pvUploadCallbackUser; 224 /** The expected upload size, UINT64_MAX if not known. */ 225 uint64_t cbUploadContent; 226 /** The current upload offset. */ 227 uint64_t offUploadContent; 228 /** @} */ 229 230 /** @name Download callback 231 * @{ */ 232 /** Pointer to the download callback function, if anyn. */ 233 PFNRTHTTPDOWNLOADCALLBACK pfnDownloadCallback; 234 /** The user argument for the download callback function. */ 235 void *pvDownloadCallbackUser; 236 /** The flags for the download callback function. */ 237 uint32_t fDownloadCallback; 238 /** HTTP status for passing to the download callback, UINT32_MAX if not known. */ 239 uint32_t uDownloadHttpStatus; 240 /** The download content length, or UINT64_MAX. */ 241 uint64_t cbDownloadContent; 242 /** The current download offset. */ 243 uint64_t offDownloadContent; 244 /** @} */ 245 246 /** @name Download progress callback. 247 * @{ */ 218 248 /** Download size hint set by the progress callback. */ 219 uint64_t cbDownloadHint;249 uint64_t cbDownloadHint; 220 250 /** Callback called during download. */ 221 PFNRTHTTPDOWNLDPROGRCALLBACK pfnDownloadProgress;251 PFNRTHTTPDOWNLDPROGRCALLBACK pfnDownloadProgress; 222 252 /** User pointer parameter for pfnDownloadProgress. */ 223 void *pvDownloadProgressUser; 253 void *pvDownloadProgressUser; 254 /** @} */ 224 255 } RTHTTPINTERNAL; 225 256 /** Pointer to an internal HTTP client instance. */ … … 345 376 pThis->BodyOutput.pHttp = pThis; 346 377 pThis->HeadersOutput.pHttp = pThis; 378 pThis->uDownloadHttpStatus = UINT32_MAX; 379 pThis->cbDownloadContent = UINT64_MAX; 380 pThis->offDownloadContent = 0; 381 pThis->cbUploadContent = UINT64_MAX; 382 pThis->offUploadContent = 0; 347 383 348 384 … … 370 406 371 407 AssertReturn(!pThis->fBusy, VERR_WRONG_ORDER); 408 409 pThis->uDownloadHttpStatus = UINT32_MAX; 410 pThis->cbDownloadContent = UINT64_MAX; 411 pThis->offDownloadContent = 0; 412 pThis->cbUploadContent = UINT64_MAX; 413 pThis->offUploadContent = 0; 414 pThis->rcOutput = VINF_SUCCESS; 372 415 373 416 /* This resets options, but keeps open connections, cookies, etc. */ … … 2803 2846 static void rtHttpResetState(PRTHTTPINTERNAL pThis) 2804 2847 { 2805 pThis->fAbort = false; 2806 pThis->rcOutput = VINF_SUCCESS; 2807 pThis->cbDownloadHint = 0; 2848 pThis->fAbort = false; 2849 pThis->rcOutput = VINF_SUCCESS; 2850 pThis->uDownloadHttpStatus = UINT32_MAX; 2851 pThis->cbDownloadContent = UINT64_MAX; 2852 pThis->offDownloadContent = 0; 2853 pThis->offUploadContent = 0; 2854 pThis->rcOutput = VINF_SUCCESS; 2855 pThis->cbDownloadHint = 0; 2808 2856 Assert(pThis->BodyOutput.pHttp == pThis); 2809 2857 Assert(pThis->HeadersOutput.pHttp == pThis); … … 2811 2859 2812 2860 2861 static void rtHttpGetDownloadStatusAndLength(PRTHTTPINTERNAL pThis) 2862 { 2863 long lHttpStatus = 0; 2864 curl_easy_getinfo(pThis->pCurl, CURLINFO_RESPONSE_CODE, &lHttpStatus); 2865 pThis->uDownloadHttpStatus = (uint32_t)lHttpStatus; 2866 2867 curl_off_t cbContent = -1; 2868 curl_easy_getinfo(pThis->pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cbContent); 2869 if (cbContent >= 0) 2870 pThis->cbDownloadContent = (uint64_t)cbContent; 2871 } 2872 2813 2873 2814 2874 /** 2815 2875 * cURL callback for writing data. 2816 2876 */ 2817 static size_t rtHttpWriteData(char *pcBuf, size_t cbUnit, size_t cUnits, void *pvUser) 2818 { 2819 RTHTTPOUTPUTDATA *pOutput = (RTHTTPOUTPUTDATA *)pvUser; 2820 PRTHTTPINTERNAL pThis = pOutput->pHttp; 2877 static size_t rtHttpWriteData(char *pchBuf, size_t cbUnit, size_t cUnits, void *pvUser) 2878 { 2879 RTHTTPOUTPUTDATA *pOutput = (RTHTTPOUTPUTDATA *)pvUser; 2880 PRTHTTPINTERNAL pThis = pOutput->pHttp; 2881 size_t const cbToAppend = cbUnit * cUnits; 2882 2883 /* 2884 * If called on the body, check if this belongs to the body download callback. 2885 */ 2886 if ( pThis->pfnDownloadCallback 2887 && pOutput == &pThis->BodyOutput) 2888 { 2889 if (pThis->offDownloadContent == 0) 2890 rtHttpGetDownloadStatusAndLength(pThis); 2891 2892 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS 2893 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus) 2894 { 2895 int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbToAppend, pThis->uDownloadHttpStatus, pThis->offDownloadContent, 2896 pThis->cbDownloadContent, pThis->pvUploadCallbackUser); 2897 if (RT_SUCCESS(rc)) 2898 { 2899 pThis->offDownloadContent += cbToAppend; 2900 return cbToAppend; 2901 } 2902 if (RT_SUCCESS(pThis->rcOutput)) 2903 pThis->rcOutput = rc; 2904 pThis->fAbort = true; 2905 return 0; 2906 } 2907 } 2821 2908 2822 2909 /* 2823 2910 * Do max size and overflow checks. 2824 2911 */ 2825 size_t const cbToAppend = cbUnit * cUnits;2826 2912 size_t const cbCurSize = pOutput->uData.Mem.cb; 2827 2913 size_t const cbNewSize = cbCurSize + cbToAppend; … … 2831 2917 if (cbNewSize + 1 <= pOutput->uData.Mem.cbAllocated) 2832 2918 { 2833 memcpy(&pOutput->uData.Mem.pb[cbCurSize], pc Buf, cbToAppend);2919 memcpy(&pOutput->uData.Mem.pb[cbCurSize], pchBuf, cbToAppend); 2834 2920 pOutput->uData.Mem.cb = cbNewSize; 2835 2921 pOutput->uData.Mem.pb[cbNewSize] = '\0'; … … 2850 2936 if (pbNew) 2851 2937 { 2852 memcpy(&pbNew[cbCurSize], pc Buf, cbToAppend);2938 memcpy(&pbNew[cbCurSize], pchBuf, cbToAppend); 2853 2939 pbNew[cbNewSize] = '\0'; 2854 2940 … … 2872 2958 pThis->fAbort = true; 2873 2959 return 0; 2960 } 2961 2962 2963 /** 2964 * cURL callback for working the upload callback. 2965 */ 2966 static size_t rtHttpWriteDataToDownloadCallback(char *pchBuf, size_t cbUnit, size_t cUnits, void *pvUser) 2967 { 2968 PRTHTTPINTERNAL pThis = (PRTHTTPINTERNAL)pvUser; 2969 size_t const cbBuf = cbUnit * cUnits; 2970 2971 /* Get download info the first time we're called. */ 2972 if (pThis->offDownloadContent == 0) 2973 rtHttpGetDownloadStatusAndLength(pThis); 2974 2975 /* Call the callback if the HTTP status code matches, otherwise let it go to /dev/null. */ 2976 if ( (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS 2977 || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus) 2978 { 2979 int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbBuf, pThis->uDownloadHttpStatus, pThis->offDownloadContent, 2980 pThis->cbDownloadContent, pThis->pvUploadCallbackUser); 2981 if (RT_SUCCESS(rc)) 2982 { /* likely */ } 2983 else 2984 { 2985 if (RT_SUCCESS(pThis->rcOutput)) 2986 pThis->rcOutput = rc; 2987 pThis->fAbort = true; 2988 return 0; 2989 } 2990 } 2991 pThis->offDownloadContent += cbBuf; 2992 return cbBuf; 2874 2993 } 2875 2994 … … 2893 3012 2894 3013 /** 3014 * Callback feeding cURL data via the user upload callback. 3015 */ 3016 static size_t rtHttpReadDataFromUploadCallback(void *pvDst, size_t cbUnit, size_t cUnits, void *pvUser) 3017 { 3018 PRTHTTPINTERNAL pThis = (PRTHTTPINTERNAL)pvUser; 3019 size_t const cbReq = cbUnit * cUnits; 3020 3021 size_t cbActual = 0; 3022 int rc = pThis->pfnUploadCallback(pThis, pvDst, cbReq, pThis->offUploadContent, &cbActual, pThis->pvUploadCallbackUser); 3023 if (RT_SUCCESS(rc)) 3024 { 3025 pThis->offUploadContent += cbActual; 3026 return cbActual; 3027 } 3028 3029 if (RT_SUCCESS(pThis->rcOutput)) 3030 pThis->rcOutput = rc; 3031 pThis->fAbort = true; 3032 return CURL_READFUNC_ABORT; 3033 } 3034 3035 3036 /** 2895 3037 * Helper for installing a (body) write callback function. 2896 3038 * … … 2900 3042 * @param pvUser The callback user argument. 2901 3043 */ 2902 static CURLcode rtHttpSetWriteCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)3044 static CURLcode rtHttpSetWriteCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser) 2903 3045 { 2904 3046 CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_WRITEFUNCTION, pfnWrite); … … 2917 3059 * @param pvUser The callback user argument. 2918 3060 */ 2919 static CURLcode rtHttpSetHeaderCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)3061 static CURLcode rtHttpSetHeaderCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser) 2920 3062 { 2921 3063 CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HEADERFUNCTION, pfnWrite); … … 2934 3076 * @param pvUser The callback user argument. 2935 3077 */ 2936 static CURLcode rtHttpSetReadCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPREADCALLBACK pfnRead, void *pvUser)3078 static CURLcode rtHttpSetReadCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPREADCALLBACKRAW pfnRead, void *pvUser) 2937 3079 { 2938 3080 CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_READFUNCTION, pfnRead); … … 3090 3232 * cURL callback for writing data to a file. 3091 3233 */ 3092 static size_t rtHttpWriteDataToFile(char *pc Buf, size_t cbUnit, size_t cUnits, void *pvUser)3234 static size_t rtHttpWriteDataToFile(char *pchBuf, size_t cbUnit, size_t cUnits, void *pvUser) 3093 3235 { 3094 3236 RTHTTPOUTPUTDATA *pOutput = (RTHTTPOUTPUTDATA *)pvUser; … … 3096 3238 3097 3239 size_t cbWritten = 0; 3098 int rc = RTFileWrite(pOutput->uData.hFile, pc Buf, cbUnit * cUnits, &cbWritten);3240 int rc = RTFileWrite(pOutput->uData.hFile, pchBuf, cbUnit * cUnits, &cbWritten); 3099 3241 if (RT_SUCCESS(rc)) 3100 3242 return cbWritten; … … 3262 3404 pThis->ReadData.Mem.cbMem = cbReqBody; 3263 3405 pThis->ReadData.Mem.offMem = 0; 3264 rcCurl = rtHttpSetReadCallback(pThis, &rtHttpReadData, pThis);3406 rcCurl = rtHttpSetReadCallback(pThis, rtHttpReadData, pThis); 3265 3407 } 3266 3408 } 3409 else if (pThis->pfnUploadCallback && CURL_SUCCESS(rcCurl)) 3410 rcCurl = rtHttpSetReadCallback(pThis, rtHttpReadDataFromUploadCallback, pThis); 3267 3411 3268 3412 /* Headers. */ … … 3270 3414 { 3271 3415 RT_ZERO(pThis->HeadersOutput.uData.Mem); 3272 rcCurl = rtHttpSetHeaderCallback(pThis, &rtHttpWriteData, &pThis->HeadersOutput);3416 rcCurl = rtHttpSetHeaderCallback(pThis, rtHttpWriteData, &pThis->HeadersOutput); 3273 3417 } 3274 3418 … … 3277 3421 { 3278 3422 RT_ZERO(pThis->BodyOutput.uData.Mem); 3279 rcCurl = rtHttpSetWriteCallback(pThis, &rtHttpWriteData, &pThis->BodyOutput); 3280 } 3423 rcCurl = rtHttpSetWriteCallback(pThis, rtHttpWriteData, &pThis->BodyOutput); 3424 } 3425 else if (pThis->pfnDownloadCallback && CURL_SUCCESS(rcCurl)) 3426 rcCurl = rtHttpSetWriteCallback(pThis, rtHttpWriteDataToDownloadCallback, pThis); 3281 3427 3282 3428 if (CURL_SUCCESS(rcCurl)) … … 3355 3501 *********************************************************************************************************************************/ 3356 3502 3503 RTR3DECL(int) RTHttpSetUploadCallback(RTHTTP hHttp, uint64_t cbContent, PFNRTHTTPUPLOADCALLBACK pfnCallback, void *pvUser) 3504 { 3505 PRTHTTPINTERNAL pThis = hHttp; 3506 RTHTTP_VALID_RETURN(pThis); 3507 3508 pThis->pfnUploadCallback = pfnCallback; 3509 pThis->pvUploadCallbackUser = pvUser; 3510 pThis->cbUploadContent = cbContent; 3511 pThis->offUploadContent = 0; 3512 3513 if (cbContent != UINT64_MAX) 3514 { 3515 AssertCompile(sizeof(curl_off_t) == sizeof(uint64_t)); 3516 int rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_INFILESIZE_LARGE, cbContent); 3517 AssertMsgReturn(CURL_SUCCESS(rcCurl), ("%d (%#x)\n", rcCurl, rcCurl), VERR_HTTP_CURL_ERROR); 3518 } 3519 return VINF_SUCCESS; 3520 } 3521 3522 3523 RTR3DECL(int) RTHttpSetDownloadCallback(RTHTTP hHttp, uint32_t fFlags, PFNRTHTTPDOWNLOADCALLBACK pfnCallback, void *pvUser) 3524 { 3525 PRTHTTPINTERNAL pThis = hHttp; 3526 RTHTTP_VALID_RETURN(pThis); 3527 AssertReturn(!pfnCallback || (fFlags & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) != 0, VERR_INVALID_FLAGS); 3528 3529 pThis->pfnDownloadCallback = pfnCallback; 3530 pThis->pvDownloadCallbackUser = pvUser; 3531 pThis->fDownloadCallback = fFlags; 3532 pThis->uDownloadHttpStatus = UINT32_MAX; 3533 pThis->cbDownloadContent = UINT64_MAX; 3534 pThis->offDownloadContent = 0; 3535 3536 return VINF_SUCCESS; 3537 } 3538 3539 3357 3540 RTR3DECL(int) RTHttpSetDownloadProgressCallback(RTHTTP hHttp, PFNRTHTTPDOWNLDPROGRCALLBACK pfnCallback, void *pvUser) 3358 3541 { … … 3366 3549 3367 3550 3368 /** @todo questionable wrt calling convension */ 3369 RTR3DECL(int) RTHttpSetReadCallback(RTHTTP hHttp, PFNRTHTTPREADCALLBACK pfnRead, void *pvUser) 3551 /** @todo header field callback. */ 3552 3553 3554 /********************************************************************************************************************************* 3555 * Temporary raw cURL stuff. Will be gone before 6.0 is out! * 3556 *********************************************************************************************************************************/ 3557 3558 RTR3DECL(int) RTHttpRawSetUrl(RTHTTP hHttp, const char *pszUrl) 3559 { 3560 CURLcode rcCurl; 3561 3562 PRTHTTPINTERNAL pThis = hHttp; 3563 RTHTTP_VALID_RETURN(pThis); 3564 3565 int rc = rtHttpConfigureProxyForUrl(pThis, pszUrl); 3566 if (RT_FAILURE(rc)) 3567 return rc; 3568 3569 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_URL, pszUrl); 3570 if (CURL_FAILURE(rcCurl)) 3571 return VERR_HTTP_CURL_ERROR; 3572 3573 return VINF_SUCCESS; 3574 } 3575 3576 3577 RTR3DECL(int) RTHttpRawSetGet(RTHTTP hHttp) 3578 { 3579 CURLcode rcCurl; 3580 3581 PRTHTTPINTERNAL pThis = hHttp; 3582 RTHTTP_VALID_RETURN(pThis); 3583 3584 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPGET, 1L); 3585 if (CURL_FAILURE(rcCurl)) 3586 return VERR_HTTP_CURL_ERROR; 3587 3588 return VINF_SUCCESS; 3589 } 3590 3591 3592 RTR3DECL(int) RTHttpRawSetHead(RTHTTP hHttp) 3593 { 3594 CURLcode rcCurl; 3595 3596 PRTHTTPINTERNAL pThis = hHttp; 3597 RTHTTP_VALID_RETURN(pThis); 3598 3599 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPGET, 1L); 3600 if (CURL_FAILURE(rcCurl)) 3601 return VERR_HTTP_CURL_ERROR; 3602 3603 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_NOBODY, 1L); 3604 if (CURL_FAILURE(rcCurl)) 3605 return VERR_HTTP_CURL_ERROR; 3606 3607 return VINF_SUCCESS; 3608 } 3609 3610 3611 RTR3DECL(int) RTHttpRawSetPost(RTHTTP hHttp) 3612 { 3613 CURLcode rcCurl; 3614 3615 PRTHTTPINTERNAL pThis = hHttp; 3616 RTHTTP_VALID_RETURN(pThis); 3617 3618 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POST, 1L); 3619 if (CURL_FAILURE(rcCurl)) 3620 return VERR_HTTP_CURL_ERROR; 3621 3622 return VINF_SUCCESS; 3623 } 3624 3625 3626 RTR3DECL(int) RTHttpRawSetPut(RTHTTP hHttp) 3627 { 3628 CURLcode rcCurl; 3629 3630 PRTHTTPINTERNAL pThis = hHttp; 3631 RTHTTP_VALID_RETURN(pThis); 3632 3633 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_PUT, 1L); 3634 if (CURL_FAILURE(rcCurl)) 3635 return VERR_HTTP_CURL_ERROR; 3636 3637 return VINF_SUCCESS; 3638 } 3639 3640 3641 RTR3DECL(int) RTHttpRawSetDelete(RTHTTP hHttp) 3642 { 3643 /* curl doesn't provide an option for this */ 3644 return RTHttpRawSetCustomRequest(hHttp, "DELETE"); 3645 } 3646 3647 3648 RTR3DECL(int) RTHttpRawSetCustomRequest(RTHTTP hHttp, const char *pszVerb) 3649 { 3650 CURLcode rcCurl; 3651 3652 PRTHTTPINTERNAL pThis = hHttp; 3653 RTHTTP_VALID_RETURN(pThis); 3654 3655 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_CUSTOMREQUEST, pszVerb); 3656 if (CURL_FAILURE(rcCurl)) 3657 return VERR_HTTP_CURL_ERROR; 3658 3659 return VINF_SUCCESS; 3660 } 3661 3662 3663 RTR3DECL(int) RTHttpRawSetPostFields(RTHTTP hHttp, const void *pv, size_t cb) 3664 { 3665 CURLcode rcCurl; 3666 3667 PRTHTTPINTERNAL pThis = hHttp; 3668 RTHTTP_VALID_RETURN(pThis); 3669 3670 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POSTFIELDSIZE, cb); 3671 if (CURL_FAILURE(rcCurl)) 3672 return VERR_HTTP_CURL_ERROR; 3673 3674 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POSTFIELDS, pv); 3675 if (CURL_FAILURE(rcCurl)) 3676 return VERR_HTTP_CURL_ERROR; 3677 3678 return VINF_SUCCESS; 3679 } 3680 3681 RTR3DECL(int) RTHttpRawSetInfileSize(RTHTTP hHttp, RTFOFF cb) 3682 { 3683 CURLcode rcCurl; 3684 3685 PRTHTTPINTERNAL pThis = hHttp; 3686 RTHTTP_VALID_RETURN(pThis); 3687 3688 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_INFILESIZE_LARGE, cb); 3689 if (CURL_FAILURE(rcCurl)) 3690 return VERR_HTTP_CURL_ERROR; 3691 3692 return VINF_SUCCESS; 3693 } 3694 3695 3696 RTR3DECL(int) RTHttpRawSetVerbose(RTHTTP hHttp, bool fValue) 3697 { 3698 CURLcode rcCurl; 3699 3700 PRTHTTPINTERNAL pThis = hHttp; 3701 RTHTTP_VALID_RETURN(pThis); 3702 3703 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_VERBOSE, fValue ? 1L : 0L); 3704 if (CURL_FAILURE(rcCurl)) 3705 return VERR_HTTP_CURL_ERROR; 3706 3707 return VINF_SUCCESS; 3708 } 3709 3710 3711 RTR3DECL(int) RTHttpRawSetTimeout(RTHTTP hHttp, long sec) 3712 { 3713 CURLcode rcCurl; 3714 3715 PRTHTTPINTERNAL pThis = hHttp; 3716 RTHTTP_VALID_RETURN(pThis); 3717 3718 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_TIMEOUT, sec); 3719 if (CURL_FAILURE(rcCurl)) 3720 return VERR_HTTP_CURL_ERROR; 3721 3722 return VINF_SUCCESS; 3723 } 3724 3725 3726 RTR3DECL(int) RTHttpRawPerform(RTHTTP hHttp) 3727 { 3728 CURLcode rcCurl; 3729 3730 PRTHTTPINTERNAL pThis = hHttp; 3731 RTHTTP_VALID_RETURN(pThis); 3732 3733 /* 3734 * XXX: Do this here for now as a stop-gap measure as 3735 * RTHttpReset() resets this (and proxy settings). 3736 */ 3737 if (pThis->pszCaFile) 3738 { 3739 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_CAINFO, pThis->pszCaFile); 3740 if (CURL_FAILURE(rcCurl)) 3741 return VERR_HTTP_CURL_ERROR; 3742 } 3743 3744 rcCurl = curl_easy_perform(pThis->pCurl); 3745 if (CURL_FAILURE(rcCurl)) 3746 return VERR_HTTP_CURL_ERROR; 3747 3748 return VINF_SUCCESS; 3749 } 3750 3751 3752 RTR3DECL(int) RTHttpRawGetResponseCode(RTHTTP hHttp, long *plCode) 3753 { 3754 CURLcode rcCurl; 3755 3756 PRTHTTPINTERNAL pThis = hHttp; 3757 RTHTTP_VALID_RETURN(pThis); 3758 AssertPtrReturn(plCode, VERR_INVALID_PARAMETER); 3759 3760 rcCurl = curl_easy_getinfo(pThis->pCurl, CURLINFO_RESPONSE_CODE, plCode); 3761 if (CURL_FAILURE(rcCurl)) 3762 return VERR_HTTP_CURL_ERROR; 3763 3764 return VINF_SUCCESS; 3765 } 3766 3767 3768 RTR3DECL(int) RTHttpRawSetReadCallback(RTHTTP hHttp, PFNRTHTTPREADCALLBACKRAW pfnRead, void *pvUser) 3370 3769 { 3371 3770 CURLcode rcCurl; … … 3386 3785 3387 3786 3388 /** @todo questionable wrt calling convension */ 3389 RTR3DECL(int) RTHttpSetWriteCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser) 3787 RTR3DECL(int) RTHttpRawSetWriteCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser) 3390 3788 { 3391 3789 PRTHTTPINTERNAL pThis = hHttp; … … 3400 3798 3401 3799 3402 /** @todo questionable wrt calling convension */ 3403 RTR3DECL(int) RTHttpSetWriteHeaderCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser) 3800 RTR3DECL(int) RTHttpRawSetWriteHeaderCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser) 3404 3801 { 3405 3802 CURLcode rcCurl; … … 3419 3816 } 3420 3817 3421 3422 3423 3424 /*********************************************************************************************************************************3425 * Temporary raw cURL stuff. *3426 *********************************************************************************************************************************/3427 3428 RTR3DECL(int) RTHttpRawSetUrl(RTHTTP hHttp, const char *pszUrl)3429 {3430 CURLcode rcCurl;3431 3432 PRTHTTPINTERNAL pThis = hHttp;3433 RTHTTP_VALID_RETURN(pThis);3434 3435 int rc = rtHttpConfigureProxyForUrl(pThis, pszUrl);3436 if (RT_FAILURE(rc))3437 return rc;3438 3439 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_URL, pszUrl);3440 if (CURL_FAILURE(rcCurl))3441 return VERR_HTTP_CURL_ERROR;3442 3443 return VINF_SUCCESS;3444 }3445 3446 3447 RTR3DECL(int) RTHttpRawSetGet(RTHTTP hHttp)3448 {3449 CURLcode rcCurl;3450 3451 PRTHTTPINTERNAL pThis = hHttp;3452 RTHTTP_VALID_RETURN(pThis);3453 3454 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPGET, 1L);3455 if (CURL_FAILURE(rcCurl))3456 return VERR_HTTP_CURL_ERROR;3457 3458 return VINF_SUCCESS;3459 }3460 3461 3462 RTR3DECL(int) RTHttpRawSetHead(RTHTTP hHttp)3463 {3464 CURLcode rcCurl;3465 3466 PRTHTTPINTERNAL pThis = hHttp;3467 RTHTTP_VALID_RETURN(pThis);3468 3469 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPGET, 1L);3470 if (CURL_FAILURE(rcCurl))3471 return VERR_HTTP_CURL_ERROR;3472 3473 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_NOBODY, 1L);3474 if (CURL_FAILURE(rcCurl))3475 return VERR_HTTP_CURL_ERROR;3476 3477 return VINF_SUCCESS;3478 }3479 3480 3481 RTR3DECL(int) RTHttpRawSetPost(RTHTTP hHttp)3482 {3483 CURLcode rcCurl;3484 3485 PRTHTTPINTERNAL pThis = hHttp;3486 RTHTTP_VALID_RETURN(pThis);3487 3488 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POST, 1L);3489 if (CURL_FAILURE(rcCurl))3490 return VERR_HTTP_CURL_ERROR;3491 3492 return VINF_SUCCESS;3493 }3494 3495 3496 RTR3DECL(int) RTHttpRawSetPut(RTHTTP hHttp)3497 {3498 CURLcode rcCurl;3499 3500 PRTHTTPINTERNAL pThis = hHttp;3501 RTHTTP_VALID_RETURN(pThis);3502 3503 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_PUT, 1L);3504 if (CURL_FAILURE(rcCurl))3505 return VERR_HTTP_CURL_ERROR;3506 3507 return VINF_SUCCESS;3508 }3509 3510 3511 RTR3DECL(int) RTHttpRawSetDelete(RTHTTP hHttp)3512 {3513 /* curl doesn't provide an option for this */3514 return RTHttpRawSetCustomRequest(hHttp, "DELETE");3515 }3516 3517 3518 RTR3DECL(int) RTHttpRawSetCustomRequest(RTHTTP hHttp, const char *pszVerb)3519 {3520 CURLcode rcCurl;3521 3522 PRTHTTPINTERNAL pThis = hHttp;3523 RTHTTP_VALID_RETURN(pThis);3524 3525 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_CUSTOMREQUEST, pszVerb);3526 if (CURL_FAILURE(rcCurl))3527 return VERR_HTTP_CURL_ERROR;3528 3529 return VINF_SUCCESS;3530 }3531 3532 3533 RTR3DECL(int) RTHttpRawSetPostFields(RTHTTP hHttp, const void *pv, size_t cb)3534 {3535 CURLcode rcCurl;3536 3537 PRTHTTPINTERNAL pThis = hHttp;3538 RTHTTP_VALID_RETURN(pThis);3539 3540 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POSTFIELDSIZE, cb);3541 if (CURL_FAILURE(rcCurl))3542 return VERR_HTTP_CURL_ERROR;3543 3544 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_POSTFIELDS, pv);3545 if (CURL_FAILURE(rcCurl))3546 return VERR_HTTP_CURL_ERROR;3547 3548 return VINF_SUCCESS;3549 }3550 3551 RTR3DECL(int) RTHttpRawSetInfileSize(RTHTTP hHttp, RTFOFF cb)3552 {3553 CURLcode rcCurl;3554 3555 PRTHTTPINTERNAL pThis = hHttp;3556 RTHTTP_VALID_RETURN(pThis);3557 3558 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_INFILESIZE_LARGE, cb);3559 if (CURL_FAILURE(rcCurl))3560 return VERR_HTTP_CURL_ERROR;3561 3562 return VINF_SUCCESS;3563 }3564 3565 3566 RTR3DECL(int) RTHttpRawSetVerbose(RTHTTP hHttp, bool fValue)3567 {3568 CURLcode rcCurl;3569 3570 PRTHTTPINTERNAL pThis = hHttp;3571 RTHTTP_VALID_RETURN(pThis);3572 3573 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_VERBOSE, fValue ? 1L : 0L);3574 if (CURL_FAILURE(rcCurl))3575 return VERR_HTTP_CURL_ERROR;3576 3577 return VINF_SUCCESS;3578 }3579 3580 3581 RTR3DECL(int) RTHttpRawSetTimeout(RTHTTP hHttp, long sec)3582 {3583 CURLcode rcCurl;3584 3585 PRTHTTPINTERNAL pThis = hHttp;3586 RTHTTP_VALID_RETURN(pThis);3587 3588 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_TIMEOUT, sec);3589 if (CURL_FAILURE(rcCurl))3590 return VERR_HTTP_CURL_ERROR;3591 3592 return VINF_SUCCESS;3593 }3594 3595 3596 RTR3DECL(int) RTHttpRawPerform(RTHTTP hHttp)3597 {3598 CURLcode rcCurl;3599 3600 PRTHTTPINTERNAL pThis = hHttp;3601 RTHTTP_VALID_RETURN(pThis);3602 3603 /*3604 * XXX: Do this here for now as a stop-gap measure as3605 * RTHttpReset() resets this (and proxy settings).3606 */3607 if (pThis->pszCaFile)3608 {3609 rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_CAINFO, pThis->pszCaFile);3610 if (CURL_FAILURE(rcCurl))3611 return VERR_HTTP_CURL_ERROR;3612 }3613 3614 rcCurl = curl_easy_perform(pThis->pCurl);3615 if (CURL_FAILURE(rcCurl))3616 return VERR_HTTP_CURL_ERROR;3617 3618 return VINF_SUCCESS;3619 }3620 3621 3622 RTR3DECL(int) RTHttpRawGetResponseCode(RTHTTP hHttp, long *plCode)3623 {3624 CURLcode rcCurl;3625 3626 PRTHTTPINTERNAL pThis = hHttp;3627 RTHTTP_VALID_RETURN(pThis);3628 AssertPtrReturn(plCode, VERR_INVALID_PARAMETER);3629 3630 rcCurl = curl_easy_getinfo(pThis->pCurl, CURLINFO_RESPONSE_CODE, plCode);3631 if (CURL_FAILURE(rcCurl))3632 return VERR_HTTP_CURL_ERROR;3633 3634 return VINF_SUCCESS;3635 }
Note:
See TracChangeset
for help on using the changeset viewer.