VirtualBox

Changeset 74126 in vbox for trunk


Ignore:
Timestamp:
Sep 6, 2018 6:29:40 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/rest: More work on binary downloads and uploads. bugref:9167

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/restbinarystring.h

    r74117 r74126  
    5151    /** Safe copy assignment method. */
    5252    int assignCopy(RTCRestBinaryString const &a_rThat);
     53
     54    /** Frees the data held by the object.
     55     * Will set m_pbData to NULL and m_cbData to UINT64_MAX.  */
     56    void freeData();
    5357
    5458    /* Overridden methods: */
     
    6670
    6771    /**
    68      * Gets the data size.
    69      *
    70      * This can be used from a consumer callback to get the Content-Length field
    71      * value if available.  Returns UINT64_MAX if not available.
    72      */
    73     uint64_t getDataSize() const { return m_cbData; }
     72     * Retrieves the callback data.
     73     */
     74    void *getCallbackData() const  { return m_pvCallbackData; }
     75
     76
     77    /** @name Upload methods
     78     * @{ */
     79
     80    /**
     81     * Sets the content-type for an upload.
     82     *
     83     * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
     84     * @param   a_pszContentType    The content type to set.
     85     *                              If NULL, no content type is set.
     86     */
     87    int setContentType(const char *a_pszContentType);
     88
     89    /**
     90     * Gets the content type that was set.
     91     */
     92    RTCString const &getContentType() const { return m_strContentType; }
    7493
    7594    /**
     
    85104     *                              for the entire lifetime of this object (or until
    86105     *                              setUploadData is called with NULL parameters).
    87      * @param   a_pszContentType    Specifies the content type to set.  Pass NULL (default)
    88      *                              to not explictly set the content type.
    89      */
    90     int setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy, const char *a_pszContentType = NULL);
    91 
    92     /** @name Data callbacks.
    93      * @{ */
     106     *
     107     * @note    This will drop any previously registered producer callback and user data..
     108     */
     109    int setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy = true);
     110
    94111    /**
    95112     * Callback for producing bytes to upload.
     
    109126
    110127    /**
    111      * Callback for consuming downloaded bytes.
    112      *
    113      * @returns IPRT status code.
    114      * @param   a_pThis     The related string object.
    115      * @param   a_pvSrc     Buffer containing the bytes.
    116      * @param   a_cbSrc     The number of bytes in the buffer.
    117      * @remarks Use getCallbackData to get the user data.
    118      */
    119     typedef DECLCALLBACK(int) FNCONSUMER(RTCRestBinaryString *a_pThis, const void *a_pvSrc, size_t a_cbSrc);
    120     /** Pointer to a byte consumer callback. */
    121     typedef FNCONSUMER *PFNCONSUMER;
    122 
    123     /**
    124      * Retrieves the callback data.
    125      */
    126     void *getCallbackData() const  { return m_pvCallbackData; }
    127 
    128     /**
    129      * Sets the consumer callback.
    130      *
    131      * @returns IPRT status code.
    132      * @param   a_pfnConsumer       The callback function for consuming downloaded data.
    133      *                              NULL if data should be stored in m_pbData/m_cbData (the default).
    134      * @param   a_pvCallbackData    Data the can be retrieved from the callback
    135      *                              using getCallbackData().
    136      */
    137     int setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData = NULL);
    138 
    139     /**
    140128     * Sets the producer callback.
    141129     *
    142      * @returns IPRT status code.
    143130     * @param   a_pfnProducer       The callback function for producing data.
    144131     * @param   a_pvCallbackData    Data the can be retrieved from the callback
    145132     *                              using getCallbackData().
    146      * @param   a_cbData            The amount of data that will be uploaded,
    147      *                              UINT64_MAX if not unknown.
    148      *
    149      * @note    This will drop any buffer previously registered using
    150      *          setUploadData(), unless a_pfnProducer is NULL.
    151      */
    152     int setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData = NULL, uint64_t a_cbData = UINT64_MAX);
     133     * @param   a_cbContentLength   The amount of data that will be uploaded and
     134     *                              to be set as the value of the content-length
     135     *                              header field.  Pass UINT64_MAX if not known.
     136     *
     137     * @note    This will drop any buffer previously registered using setUploadData().
     138     */
     139    void setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData = NULL, uint64_t a_cbContentLength = UINT64_MAX);
     140
     141    /**
     142     * Preprares transmission via the @a a_hHttp client instance.
     143     *
     144     * @returns IPRT status code.
     145     * @param   a_hHttp             The HTTP client instance.
     146     * @internal
     147     */
     148    virtual int xmitPrepare(RTHTTP a_hHttp) const;
     149
     150    /**
     151     * For completing and/or undoing setup from xmitPrepare.
     152     *
     153     * @param   a_hHttp             The HTTP client instance.
     154     * @internal
     155     */
     156    virtual void xmitComplete(RTHTTP a_hHttp) const;
    153157    /** @} */
    154158
    155159
    156     /**
    157      * Preprares transmission via @a a_hHttp.
    158      *
    159      * @returns IPRT status code.
    160      * @param   a_hHttp             The HTTP client instance.
    161      */
    162     virtual int  xmitPrepare(RTHTTP a_hHttp) const;
    163 
    164     /**
    165      * For completing and/or undoing setup from xmitPrepare.
    166      *
    167      * @param   a_hHttp             The HTTP client instance.
    168      */
    169     virtual void xmitComplete(RTHTTP a_hHttp) const;
    170 
    171     //virtual int receivePrepare(RTHTTP a_hHttp);
    172     //virtual int receiveComplete(int a_rcStatus, RTHTTP a_hHttp);
     160    /** @name Download methods
     161     * @{ */
     162
     163    /**
     164     * Sets the max size to download to memory.
     165     *
     166     * This also indicates the intention to download to a memory buffer, so it
     167     * will drop any previously registered consumer callback and its user data.
     168     *
     169     * @param   a_cbMax Maximum number of bytes to download to memory.
     170     *                  If 0, a default is selected (currently 32MiB for
     171     *                  32-bit hosts and 128MiB for 64-bit).
     172     */
     173    void setMaxDownloadSize(size_t a_cbMaxDownload);
     174
     175    /**
     176     * Gets the content-length value (UINT64_MAX if not available).
     177     */
     178    uint64_t getContentLength() const { return m_cbContentLength; }
     179
     180    /**
     181     * Gets the number of bytes that has actually been downloaded.
     182     */
     183    uint64_t getDownloadSize() const { return m_cbDownloaded; }
     184
     185    /**
     186     * Returns the pointer to the download buffer.
     187     * @note returns NULL if setConsumerCallback was used or no data was downloaded.
     188     */
     189    uint8_t const *getDownloadData() const { return m_pbData; }
     190
     191    /**
     192     * Callback for consuming downloaded bytes.
     193     *
     194     * @returns IPRT status code.
     195     * @param   a_pThis         The related string object.
     196     * @param   a_pvSrc         Buffer containing the bytes.
     197     * @param   a_cbSrc         The number of bytes in the buffer.
     198     * @param   a_uHttpStatus   The HTTP status code.
     199     * @param   a_offContent    The byte offset corresponding to the start of @a a_pvSrc.
     200     * @param   a_cbContent     The content length field value, UINT64_MAX if not available.
     201     * @remarks Use getCallbackData to get the user data.
     202     */
     203    typedef DECLCALLBACK(int) FNCONSUMER(RTCRestBinaryString *a_pThis, const void *a_pvSrc, size_t a_cbSrc,
     204                                         uint32_t a_uHttpStatus, uint64_t a_offContent, uint64_t a_cbContent);
     205    /** Pointer to a byte consumer callback. */
     206    typedef FNCONSUMER *PFNCONSUMER;
     207
     208    /**
     209     * Sets the consumer callback.
     210     *
     211     * @param   a_pfnConsumer       The callback function for consuming downloaded data.
     212     *                              NULL if data should be stored in m_pbData (the default).
     213     * @param   a_pvCallbackData    Data the can be retrieved from the callback
     214     *                              using getCallbackData().
     215     */
     216    void setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData = NULL);
     217
     218    /**
     219     * Preprares for receiving via the @a a_hHttp client instance.
     220     *
     221     * @returns IPRT status code.
     222     * @param   a_hHttp             The HTTP client instance.
     223     * @param   a_fCallbackFlags    The HTTP callback flags (status code spec).
     224     * @internal
     225     */
     226    virtual int receivePrepare(RTHTTP a_hHttp, uint32_t a_fCallbackFlags);
     227
     228    /**
     229     * For completing and/or undoing setup from receivePrepare.
     230     *
     231     * @param   a_hHttp             The HTTP client instance.
     232     * @internal
     233     */
     234    virtual void receiveComplete(RTHTTP a_hHttp);
     235    /** @} */
     236
    173237
    174238protected:
    175     /** Pointer to the bytes, if provided directly. */
     239    /** Pointer to the bytes, if provided directly. (both) */
    176240    uint8_t    *m_pbData;
    177     /** Number of bytes.  UINT64_MAX if not known. */
    178     uint64_t    m_cbData;
    179     /** User argument for callbacks. */
     241    /** Number of bytes allocated for the m_pbData buffer (both). */
     242    size_t      m_cbAllocated;
     243    /** Set if m_pbData must be freed (both). */
     244    bool        m_fFreeData;
     245    /** Number of bytes corresponding to content-length.
     246     * UINT64_MAX if not known.  Used both for unploads and downloads. */
     247    uint64_t    m_cbContentLength;
     248    /** User argument for both callbacks (both). */
    180249    void       *m_pvCallbackData;
    181     /** Pointer to user-registered consumer callback function. */
     250
     251    /** Pointer to user-registered producer callback function (upload only). */
     252    PFNPRODUCER m_pfnProducer;
     253    /** The content type if set (upload only). */
     254    RTCString   m_strContentType;
     255
     256    /** Pointer to user-registered consumer callback function (download only). */
    182257    PFNCONSUMER m_pfnConsumer;
    183     /** Pointer to user-registered producer callback function. */
    184     PFNPRODUCER m_pfnProducer;
    185     /** Set if m_pbData must be freed. */
    186     bool        m_fFreeData;
    187     /** The content type (upload only). */
    188     RTCString   m_strContentType;
    189 
    190 
    191     static FNRTHTTPUPLOADCALLBACK xmitHttpCallback;
     258    /** Number of bytes downloaded thus far. */
     259    uint64_t    m_cbDownloaded;
     260    /** Maximum data to download to memory (download only). */
     261    size_t      m_cbMaxDownload;
     262
     263    /** Callback for use with RTHttpSetUploadCallback. */
     264    static FNRTHTTPUPLOADCALLBACK   xmitHttpCallback;
     265    /** Callback for use with RTHttpSetDownloadCallback. */
     266    static FNRTHTTPDOWNLOADCALLBACK receiveHttpCallback;
    192267
    193268private:
  • trunk/include/iprt/http.h

    r74091 r74126  
    473473 * For all other status codes, any body data will be returned via the
    474474 * RTHttpPerform ppvBody/pcbBody return parameters. */
    475 #define RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK     UINT32_C(0x000003ff)
     475#define RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK       UINT32_C(0x000003ff)
    476476/** Callback requires no special HTTP status. */
    477 #define RTHTTPDOWNLOAD_F_F_ANY_STATUS           UINT32_C(0x000003ff)
     477#define RTHTTPDOWNLOAD_F_ANY_STATUS             UINT32_C(0x000003ff)
    478478/** @} */
    479479
  • trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp

    r74117 r74126  
    3636
    3737
     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
    3848
    3949/** Default constructor. */
     
    4151    : RTCRestObjectBase()
    4252    , m_pbData(NULL)
    43     , m_cbData(UINT64_MAX)
     53    , m_cbAllocated(0)
     54    , m_fFreeData(false)
     55    , m_cbContentLength(UINT64_MAX)
    4456    , m_pvCallbackData(NULL)
     57    , m_strContentType()
     58    , m_pfnProducer(NULL)
    4559    , 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)
    4962{
    5063}
     
    5669RTCRestBinaryString::~RTCRestBinaryString()
    5770{
    58     if (m_pbData)
    59     {
    60         if (m_fFreeData)
    61             RTMemFree(m_pbData);
    62         m_pbData = NULL;
    63     }
    64     m_fFreeData      = false;
     71    freeData();
    6572    m_pvCallbackData = NULL;
    6673    m_pfnProducer    = NULL;
     
    7986
    8087
     88void 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
    81103/*********************************************************************************************************************************
    82104*   Overridden methods                                                                                                           *
     
    141163*********************************************************************************************************************************/
    142164
     165int RTCRestBinaryString::setContentType(const char *a_pszContentType)
     166{
     167    return m_strContentType.assignNoThrow(a_pszContentType);
     168}
     169
     170
     171int 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
     196void 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
    143207int RTCRestBinaryString::xmitPrepare(RTHTTP a_hHttp) const
    144208{
     209    AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbContentLength == 0, VERR_INVALID_STATE);
     210
     211
    145212    /*
    146213     * Set the content type if given.
     
    157224     * Set the content length if given.
    158225     */
    159     if (m_cbData != UINT64_MAX)
     226    if (m_cbContentLength != UINT64_MAX)
    160227    {
    161228        const char *pszContentLength = RTHttpGetHeader(a_hHttp, RT_STR_TUPLE("Content-Length"));
    162         AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cbData,
    163                         ("pszContentLength=%s does not match m_cbData=%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),
    164231                        VERR_MISMATCH);
    165232        if (!pszContentLength)
    166233        {
    167234            char szValue[64];
    168             ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbData, 10, 0, 0, 0);
     235            ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbContentLength, 10, 0, 0, 0);
    169236            int rc = RTHttpAddHeader(a_hHttp, "Content-Length", szValue, cchValue, RTHTTPADDHDR_F_BACK);
    170237            AssertRCReturn(rc, rc);
     
    175242     * Register an upload callback.
    176243     */
    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);
    180245    AssertRCReturn(rc, rc);
    181246
     
    199264     * Feed from the memory buffer.
    200265     */
    201     if (offContent < pThis->m_cbData)
    202     {
    203         uint64_t const cbLeft = pThis->m_cbData - offContent;
     266    if (offContent < pThis->m_cbContentLength)
     267    {
     268        uint64_t const cbLeft = pThis->m_cbContentLength - offContent;
    204269        size_t const cbToCopy = cbLeft >= cbBuf ? cbBuf : (size_t)cbLeft;
    205270        memcpy(pvBuf, &pThis->m_pbData[(size_t)offContent], cbToCopy);
     
    217282{
    218283    /* Unset the callback. */
    219     int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, NULL, NULL);
     284    int rc = RTHttpSetUploadCallback(a_hHttp, UINT64_MAX, NULL, NULL);
    220285    AssertRC(rc);
    221286}
    222287
    223288
     289/*********************************************************************************************************************************
     290*   Download related methods                                                                                                     *
     291*********************************************************************************************************************************/
     292
     293void 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
     302void 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
     311int 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
     323void 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)
     332RTCRestBinaryString::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  
    29062906            rtHttpGetDownloadStatusAndLength(pThis);
    29072907
    2908         if (   (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS
    2909             || (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)
    29102910        {
    29112911            int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbToAppend, pThis->uDownloadHttpStatus, pThis->offDownloadContent,
     
    29902990
    29912991    /* 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_STATUS
    2993         || (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)
    29942994    {
    29952995        int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbBuf, pThis->uDownloadHttpStatus, pThis->offDownloadContent,
     
    35413541    PRTHTTPINTERNAL pThis = hHttp;
    35423542    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);
    35443544
    35453545    pThis->pfnDownloadCallback      = pfnCallback;
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