VirtualBox

Changeset 74090 in vbox for trunk/src


Ignore:
Timestamp:
Sep 5, 2018 5:41:03 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/http: New read/write callbacks APIs (untested). bugref:9167

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/http-curl.cpp

    r74077 r74090  
    216216    int                 rcOutput;
    217217
     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     * @{ */
    218248    /** Download size hint set by the progress callback. */
    219     uint64_t            cbDownloadHint;
     249    uint64_t                       cbDownloadHint;
    220250    /** Callback called during download. */
    221     PFNRTHTTPDOWNLDPROGRCALLBACK pfnDownloadProgress;
     251    PFNRTHTTPDOWNLDPROGRCALLBACK   pfnDownloadProgress;
    222252    /** User pointer parameter for pfnDownloadProgress. */
    223     void               *pvDownloadProgressUser;
     253    void                           *pvDownloadProgressUser;
     254    /** @} */
    224255} RTHTTPINTERNAL;
    225256/** Pointer to an internal HTTP client instance. */
     
    345376                pThis->BodyOutput.pHttp         = pThis;
    346377                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;
    347383
    348384
     
    370406
    371407    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;
    372415
    373416    /* This resets options, but keeps open connections, cookies, etc. */
     
    28032846static void rtHttpResetState(PRTHTTPINTERNAL pThis)
    28042847{
    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;
    28082856    Assert(pThis->BodyOutput.pHttp == pThis);
    28092857    Assert(pThis->HeadersOutput.pHttp == pThis);
     
    28112859
    28122860
     2861static 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
    28132873
    28142874/**
    28152875 * cURL callback for writing data.
    28162876 */
    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;
     2877static 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    }
    28212908
    28222909    /*
    28232910     * Do max size and overflow checks.
    28242911     */
    2825     size_t const cbToAppend = cbUnit * cUnits;
    28262912    size_t const cbCurSize  = pOutput->uData.Mem.cb;
    28272913    size_t const cbNewSize  = cbCurSize + cbToAppend;
     
    28312917        if (cbNewSize + 1 <= pOutput->uData.Mem.cbAllocated)
    28322918        {
    2833             memcpy(&pOutput->uData.Mem.pb[cbCurSize], pcBuf, cbToAppend);
     2919            memcpy(&pOutput->uData.Mem.pb[cbCurSize], pchBuf, cbToAppend);
    28342920            pOutput->uData.Mem.cb = cbNewSize;
    28352921            pOutput->uData.Mem.pb[cbNewSize] = '\0';
     
    28502936        if (pbNew)
    28512937        {
    2852             memcpy(&pbNew[cbCurSize], pcBuf, cbToAppend);
     2938            memcpy(&pbNew[cbCurSize], pchBuf, cbToAppend);
    28532939            pbNew[cbNewSize] = '\0';
    28542940
     
    28722958    pThis->fAbort   = true;
    28732959    return 0;
     2960}
     2961
     2962
     2963/**
     2964 * cURL callback for working the upload callback.
     2965 */
     2966static 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;
    28742993}
    28752994
     
    28933012
    28943013/**
     3014 * Callback feeding cURL data via the user upload callback.
     3015 */
     3016static 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/**
    28953037 * Helper for installing a (body) write callback function.
    28963038 *
     
    29003042 * @param   pvUser              The callback user argument.
    29013043 */
    2902 static CURLcode rtHttpSetWriteCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)
     3044static CURLcode rtHttpSetWriteCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser)
    29033045{
    29043046    CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_WRITEFUNCTION, pfnWrite);
     
    29173059 * @param   pvUser              The callback user argument.
    29183060 */
    2919 static CURLcode rtHttpSetHeaderCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)
     3061static CURLcode rtHttpSetHeaderCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser)
    29203062{
    29213063    CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HEADERFUNCTION, pfnWrite);
     
    29343076 * @param   pvUser              The callback user argument.
    29353077 */
    2936 static CURLcode rtHttpSetReadCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPREADCALLBACK pfnRead, void *pvUser)
     3078static CURLcode rtHttpSetReadCallback(PRTHTTPINTERNAL pThis, PFNRTHTTPREADCALLBACKRAW pfnRead, void *pvUser)
    29373079{
    29383080    CURLcode rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_READFUNCTION, pfnRead);
     
    30903232 * cURL callback for writing data to a file.
    30913233 */
    3092 static size_t rtHttpWriteDataToFile(char *pcBuf, size_t cbUnit, size_t cUnits, void *pvUser)
     3234static size_t rtHttpWriteDataToFile(char *pchBuf, size_t cbUnit, size_t cUnits, void *pvUser)
    30933235{
    30943236    RTHTTPOUTPUTDATA *pOutput   = (RTHTTPOUTPUTDATA *)pvUser;
     
    30963238
    30973239    size_t            cbWritten = 0;
    3098     int rc = RTFileWrite(pOutput->uData.hFile, pcBuf, cbUnit * cUnits, &cbWritten);
     3240    int rc = RTFileWrite(pOutput->uData.hFile, pchBuf, cbUnit * cUnits, &cbWritten);
    30993241    if (RT_SUCCESS(rc))
    31003242        return cbWritten;
     
    32623404                pThis->ReadData.Mem.cbMem  = cbReqBody;
    32633405                pThis->ReadData.Mem.offMem = 0;
    3264                 rcCurl = rtHttpSetReadCallback(pThis, &rtHttpReadData, pThis);
     3406                rcCurl = rtHttpSetReadCallback(pThis, rtHttpReadData, pThis);
    32653407            }
    32663408        }
     3409        else if (pThis->pfnUploadCallback && CURL_SUCCESS(rcCurl))
     3410            rcCurl = rtHttpSetReadCallback(pThis, rtHttpReadDataFromUploadCallback, pThis);
    32673411
    32683412        /* Headers. */
     
    32703414        {
    32713415            RT_ZERO(pThis->HeadersOutput.uData.Mem);
    3272             rcCurl = rtHttpSetHeaderCallback(pThis, &rtHttpWriteData, &pThis->HeadersOutput);
     3416            rcCurl = rtHttpSetHeaderCallback(pThis, rtHttpWriteData, &pThis->HeadersOutput);
    32733417        }
    32743418
     
    32773421        {
    32783422            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);
    32813427
    32823428        if (CURL_SUCCESS(rcCurl))
     
    33553501*********************************************************************************************************************************/
    33563502
     3503RTR3DECL(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
     3523RTR3DECL(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
    33573540RTR3DECL(int) RTHttpSetDownloadProgressCallback(RTHTTP hHttp, PFNRTHTTPDOWNLDPROGRCALLBACK pfnCallback, void *pvUser)
    33583541{
     
    33663549
    33673550
    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
     3558RTR3DECL(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
     3577RTR3DECL(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
     3592RTR3DECL(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
     3611RTR3DECL(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
     3626RTR3DECL(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
     3641RTR3DECL(int) RTHttpRawSetDelete(RTHTTP hHttp)
     3642{
     3643    /* curl doesn't provide an option for this */
     3644    return RTHttpRawSetCustomRequest(hHttp, "DELETE");
     3645}
     3646
     3647
     3648RTR3DECL(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
     3663RTR3DECL(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
     3681RTR3DECL(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
     3696RTR3DECL(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
     3711RTR3DECL(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
     3726RTR3DECL(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
     3752RTR3DECL(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
     3768RTR3DECL(int) RTHttpRawSetReadCallback(RTHTTP hHttp, PFNRTHTTPREADCALLBACKRAW pfnRead, void *pvUser)
    33703769{
    33713770    CURLcode rcCurl;
     
    33863785
    33873786
    3388 /** @todo questionable wrt calling convension */
    3389 RTR3DECL(int) RTHttpSetWriteCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)
     3787RTR3DECL(int) RTHttpRawSetWriteCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser)
    33903788{
    33913789    PRTHTTPINTERNAL pThis = hHttp;
     
    34003798
    34013799
    3402 /** @todo questionable wrt calling convension */
    3403 RTR3DECL(int) RTHttpSetWriteHeaderCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACK pfnWrite, void *pvUser)
     3800RTR3DECL(int) RTHttpRawSetWriteHeaderCallback(RTHTTP hHttp, PFNRTHTTPWRITECALLBACKRAW pfnWrite, void *pvUser)
    34043801{
    34053802    CURLcode rcCurl;
     
    34193816}
    34203817
    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 as
    3605      * 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.

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