Index: trunk/include/iprt/cpp/restbinarystring.h
===================================================================
--- trunk/include/iprt/cpp/restbinarystring.h	(revision 74125)
+++ trunk/include/iprt/cpp/restbinarystring.h	(revision 74126)
@@ -51,4 +51,8 @@
     /** Safe copy assignment method. */
     int assignCopy(RTCRestBinaryString const &a_rThat);
+
+    /** Frees the data held by the object.
+     * Will set m_pbData to NULL and m_cbData to UINT64_MAX.  */
+    void freeData();
 
     /* Overridden methods: */
@@ -66,10 +70,25 @@
 
     /**
-     * Gets the data size.
-     *
-     * This can be used from a consumer callback to get the Content-Length field
-     * value if available.  Returns UINT64_MAX if not available.
-     */
-    uint64_t getDataSize() const { return m_cbData; }
+     * Retrieves the callback data.
+     */
+    void *getCallbackData() const  { return m_pvCallbackData; }
+
+
+    /** @name Upload methods
+     * @{ */
+
+    /**
+     * Sets the content-type for an upload.
+     *
+     * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
+     * @param   a_pszContentType    The content type to set.
+     *                              If NULL, no content type is set.
+     */
+    int setContentType(const char *a_pszContentType);
+
+    /**
+     * Gets the content type that was set.
+     */
+    RTCString const &getContentType() const { return m_strContentType; }
 
     /**
@@ -85,11 +104,9 @@
      *                              for the entire lifetime of this object (or until
      *                              setUploadData is called with NULL parameters).
-     * @param   a_pszContentType    Specifies the content type to set.  Pass NULL (default)
-     *                              to not explictly set the content type.
-     */
-    int setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy, const char *a_pszContentType = NULL);
-
-    /** @name Data callbacks.
-     * @{ */
+     *
+     * @note    This will drop any previously registered producer callback and user data..
+     */
+    int setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy = true);
+
     /**
      * Callback for producing bytes to upload.
@@ -109,85 +126,143 @@
 
     /**
-     * Callback for consuming downloaded bytes.
-     *
-     * @returns IPRT status code.
-     * @param   a_pThis     The related string object.
-     * @param   a_pvSrc     Buffer containing the bytes.
-     * @param   a_cbSrc     The number of bytes in the buffer.
-     * @remarks Use getCallbackData to get the user data.
-     */
-    typedef DECLCALLBACK(int) FNCONSUMER(RTCRestBinaryString *a_pThis, const void *a_pvSrc, size_t a_cbSrc);
-    /** Pointer to a byte consumer callback. */
-    typedef FNCONSUMER *PFNCONSUMER;
-
-    /**
-     * Retrieves the callback data.
-     */
-    void *getCallbackData() const  { return m_pvCallbackData; }
-
-    /**
-     * Sets the consumer callback.
-     *
-     * @returns IPRT status code.
-     * @param   a_pfnConsumer       The callback function for consuming downloaded data.
-     *                              NULL if data should be stored in m_pbData/m_cbData (the default).
-     * @param   a_pvCallbackData    Data the can be retrieved from the callback
-     *                              using getCallbackData().
-     */
-    int setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData = NULL);
-
-    /**
      * Sets the producer callback.
      *
-     * @returns IPRT status code.
      * @param   a_pfnProducer       The callback function for producing data.
      * @param   a_pvCallbackData    Data the can be retrieved from the callback
      *                              using getCallbackData().
-     * @param   a_cbData            The amount of data that will be uploaded,
-     *                              UINT64_MAX if not unknown.
-     *
-     * @note    This will drop any buffer previously registered using
-     *          setUploadData(), unless a_pfnProducer is NULL.
-     */
-    int setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData = NULL, uint64_t a_cbData = UINT64_MAX);
+     * @param   a_cbContentLength   The amount of data that will be uploaded and
+     *                              to be set as the value of the content-length
+     *                              header field.  Pass UINT64_MAX if not known.
+     *
+     * @note    This will drop any buffer previously registered using setUploadData().
+     */
+    void setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData = NULL, uint64_t a_cbContentLength = UINT64_MAX);
+
+    /**
+     * Preprares transmission via the @a a_hHttp client instance.
+     *
+     * @returns IPRT status code.
+     * @param   a_hHttp             The HTTP client instance.
+     * @internal
+     */
+    virtual int xmitPrepare(RTHTTP a_hHttp) const;
+
+    /**
+     * For completing and/or undoing setup from xmitPrepare.
+     *
+     * @param   a_hHttp             The HTTP client instance.
+     * @internal
+     */
+    virtual void xmitComplete(RTHTTP a_hHttp) const;
     /** @} */
 
 
-    /**
-     * Preprares transmission via @a a_hHttp.
-     *
-     * @returns IPRT status code.
-     * @param   a_hHttp             The HTTP client instance.
-     */
-    virtual int  xmitPrepare(RTHTTP a_hHttp) const;
-
-    /**
-     * For completing and/or undoing setup from xmitPrepare.
-     *
-     * @param   a_hHttp             The HTTP client instance.
-     */
-    virtual void xmitComplete(RTHTTP a_hHttp) const;
-
-    //virtual int receivePrepare(RTHTTP a_hHttp);
-    //virtual int receiveComplete(int a_rcStatus, RTHTTP a_hHttp);
+    /** @name Download methods
+     * @{ */
+
+    /**
+     * Sets the max size to download to memory.
+     *
+     * This also indicates the intention to download to a memory buffer, so it
+     * will drop any previously registered consumer callback and its user data.
+     *
+     * @param   a_cbMax Maximum number of bytes to download to memory.
+     *                  If 0, a default is selected (currently 32MiB for
+     *                  32-bit hosts and 128MiB for 64-bit).
+     */
+    void setMaxDownloadSize(size_t a_cbMaxDownload);
+
+    /**
+     * Gets the content-length value (UINT64_MAX if not available).
+     */
+    uint64_t getContentLength() const { return m_cbContentLength; }
+
+    /**
+     * Gets the number of bytes that has actually been downloaded.
+     */
+    uint64_t getDownloadSize() const { return m_cbDownloaded; }
+
+    /**
+     * Returns the pointer to the download buffer.
+     * @note returns NULL if setConsumerCallback was used or no data was downloaded.
+     */
+    uint8_t const *getDownloadData() const { return m_pbData; }
+
+    /**
+     * Callback for consuming downloaded bytes.
+     *
+     * @returns IPRT status code.
+     * @param   a_pThis         The related string object.
+     * @param   a_pvSrc         Buffer containing the bytes.
+     * @param   a_cbSrc         The number of bytes in the buffer.
+     * @param   a_uHttpStatus   The HTTP status code.
+     * @param   a_offContent    The byte offset corresponding to the start of @a a_pvSrc.
+     * @param   a_cbContent     The content length field value, UINT64_MAX if not available.
+     * @remarks Use getCallbackData to get the user data.
+     */
+    typedef DECLCALLBACK(int) FNCONSUMER(RTCRestBinaryString *a_pThis, const void *a_pvSrc, size_t a_cbSrc,
+                                         uint32_t a_uHttpStatus, uint64_t a_offContent, uint64_t a_cbContent);
+    /** Pointer to a byte consumer callback. */
+    typedef FNCONSUMER *PFNCONSUMER;
+
+    /**
+     * Sets the consumer callback.
+     *
+     * @param   a_pfnConsumer       The callback function for consuming downloaded data.
+     *                              NULL if data should be stored in m_pbData (the default).
+     * @param   a_pvCallbackData    Data the can be retrieved from the callback
+     *                              using getCallbackData().
+     */
+    void setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData = NULL);
+
+    /**
+     * Preprares for receiving via the @a a_hHttp client instance.
+     *
+     * @returns IPRT status code.
+     * @param   a_hHttp             The HTTP client instance.
+     * @param   a_fCallbackFlags    The HTTP callback flags (status code spec).
+     * @internal
+     */
+    virtual int receivePrepare(RTHTTP a_hHttp, uint32_t a_fCallbackFlags);
+
+    /**
+     * For completing and/or undoing setup from receivePrepare.
+     *
+     * @param   a_hHttp             The HTTP client instance.
+     * @internal
+     */
+    virtual void receiveComplete(RTHTTP a_hHttp);
+    /** @} */
+
 
 protected:
-    /** Pointer to the bytes, if provided directly. */
+    /** Pointer to the bytes, if provided directly. (both) */
     uint8_t    *m_pbData;
-    /** Number of bytes.  UINT64_MAX if not known. */
-    uint64_t    m_cbData;
-    /** User argument for callbacks. */
+    /** Number of bytes allocated for the m_pbData buffer (both). */
+    size_t      m_cbAllocated;
+    /** Set if m_pbData must be freed (both). */
+    bool        m_fFreeData;
+    /** Number of bytes corresponding to content-length.
+     * UINT64_MAX if not known.  Used both for unploads and downloads. */
+    uint64_t    m_cbContentLength;
+    /** User argument for both callbacks (both). */
     void       *m_pvCallbackData;
-    /** Pointer to user-registered consumer callback function. */
+
+    /** Pointer to user-registered producer callback function (upload only). */
+    PFNPRODUCER m_pfnProducer;
+    /** The content type if set (upload only). */
+    RTCString   m_strContentType;
+
+    /** Pointer to user-registered consumer callback function (download only). */
     PFNCONSUMER m_pfnConsumer;
-    /** Pointer to user-registered producer callback function. */
-    PFNPRODUCER m_pfnProducer;
-    /** Set if m_pbData must be freed. */
-    bool        m_fFreeData;
-    /** The content type (upload only). */
-    RTCString   m_strContentType;
-
-
-    static FNRTHTTPUPLOADCALLBACK xmitHttpCallback;
+    /** Number of bytes downloaded thus far. */
+    uint64_t    m_cbDownloaded;
+    /** Maximum data to download to memory (download only). */
+    size_t      m_cbMaxDownload;
+
+    /** Callback for use with RTHttpSetUploadCallback. */
+    static FNRTHTTPUPLOADCALLBACK   xmitHttpCallback;
+    /** Callback for use with RTHttpSetDownloadCallback. */
+    static FNRTHTTPDOWNLOADCALLBACK receiveHttpCallback;
 
 private:
Index: trunk/include/iprt/http.h
===================================================================
--- trunk/include/iprt/http.h	(revision 74125)
+++ trunk/include/iprt/http.h	(revision 74126)
@@ -473,7 +473,7 @@
  * For all other status codes, any body data will be returned via the
  * RTHttpPerform ppvBody/pcbBody return parameters. */
-#define RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK     UINT32_C(0x000003ff)
+#define RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK       UINT32_C(0x000003ff)
 /** Callback requires no special HTTP status. */
-#define RTHTTPDOWNLOAD_F_F_ANY_STATUS           UINT32_C(0x000003ff)
+#define RTHTTPDOWNLOAD_F_ANY_STATUS             UINT32_C(0x000003ff)
 /** @} */
 
Index: trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp	(revision 74125)
+++ trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp	(revision 74126)
@@ -36,4 +36,14 @@
 
 
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** The default maximum download size. */
+#if ARCH_BITS == 32
+# define RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT  _32M
+#else
+# define RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT  _128M
+#endif
+
 
 /** Default constructor. */
@@ -41,10 +51,13 @@
     : RTCRestObjectBase()
     , m_pbData(NULL)
-    , m_cbData(UINT64_MAX)
+    , m_cbAllocated(0)
+    , m_fFreeData(false)
+    , m_cbContentLength(UINT64_MAX)
     , m_pvCallbackData(NULL)
+    , m_strContentType()
+    , m_pfnProducer(NULL)
     , m_pfnConsumer(NULL)
-    , m_pfnProducer(NULL)
-    , m_fFreeData(false)
-    , m_strContentType()
+    , m_cbDownloaded(0)
+    , m_cbMaxDownload(RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT)
 {
 }
@@ -56,11 +69,5 @@
 RTCRestBinaryString::~RTCRestBinaryString()
 {
-    if (m_pbData)
-    {
-        if (m_fFreeData)
-            RTMemFree(m_pbData);
-        m_pbData = NULL;
-    }
-    m_fFreeData      = false;
+    freeData();
     m_pvCallbackData = NULL;
     m_pfnProducer    = NULL;
@@ -79,4 +86,19 @@
 
 
+void RTCRestBinaryString::freeData()
+{
+    if (m_pbData)
+    {
+        if (m_fFreeData)
+            RTMemFree(m_pbData);
+        m_pbData = NULL;
+    }
+    m_fFreeData       = false;
+    m_cbAllocated     = 0;
+    m_cbDownloaded    = 0;
+    m_cbContentLength = UINT64_MAX;
+}
+
+
 /*********************************************************************************************************************************
 *   Overridden methods                                                                                                           *
@@ -141,6 +163,51 @@
 *********************************************************************************************************************************/
 
+int RTCRestBinaryString::setContentType(const char *a_pszContentType)
+{
+    return m_strContentType.assignNoThrow(a_pszContentType);
+}
+
+
+int RTCRestBinaryString::setUploadData(void const *a_pvData, size_t a_cbData, bool a_fCopy /*= true*/)
+{
+    freeData();
+
+    if (a_cbData != 0)
+    {
+        if (a_fCopy)
+        {
+            m_pbData = (uint8_t *)RTMemDup(a_pvData, a_cbData);
+            AssertReturn(m_pbData, VERR_NO_MEMORY);
+            m_fFreeData   = true;
+            m_cbAllocated = a_cbData;
+        }
+        else
+        {
+            AssertPtrReturn(a_pvData, VERR_INVALID_POINTER);
+            m_pbData = (uint8_t *)a_pvData;
+        }
+    }
+    m_cbContentLength = a_cbData;
+
+    return VINF_SUCCESS;
+}
+
+
+void RTCRestBinaryString::setProducerCallback(PFNPRODUCER a_pfnProducer, void *a_pvCallbackData /*= NULL*/,
+                                              uint64_t a_cbContentLength /*= UINT64_MAX*/)
+{
+    freeData();
+
+    m_cbContentLength = a_cbContentLength;
+    m_pfnProducer     = a_pfnProducer;
+    m_pvCallbackData  = a_pvCallbackData;
+}
+
+
 int RTCRestBinaryString::xmitPrepare(RTHTTP a_hHttp) const
 {
+    AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbContentLength == 0, VERR_INVALID_STATE);
+
+
     /*
      * Set the content type if given.
@@ -157,14 +224,14 @@
      * Set the content length if given.
      */
-    if (m_cbData != UINT64_MAX)
+    if (m_cbContentLength != UINT64_MAX)
     {
         const char *pszContentLength = RTHttpGetHeader(a_hHttp, RT_STR_TUPLE("Content-Length"));
-        AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cbData,
-                        ("pszContentLength=%s does not match m_cbData=%RU64\n", pszContentLength, m_cbData),
+        AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cbContentLength,
+                        ("pszContentLength=%s does not match m_cbContentLength=%RU64\n", pszContentLength, m_cbContentLength),
                         VERR_MISMATCH);
         if (!pszContentLength)
         {
             char szValue[64];
-            ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbData, 10, 0, 0, 0);
+            ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbContentLength, 10, 0, 0, 0);
             int rc = RTHttpAddHeader(a_hHttp, "Content-Length", szValue, cchValue, RTHTTPADDHDR_F_BACK);
             AssertRCReturn(rc, rc);
@@ -175,7 +242,5 @@
      * Register an upload callback.
      */
-    AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbData == 0, VERR_INVALID_STATE);
-
-    int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, xmitHttpCallback, (RTCRestBinaryString *)this);
+    int rc = RTHttpSetUploadCallback(a_hHttp, m_cbContentLength, xmitHttpCallback, (RTCRestBinaryString *)this);
     AssertRCReturn(rc, rc);
 
@@ -199,7 +264,7 @@
      * Feed from the memory buffer.
      */
-    if (offContent < pThis->m_cbData)
-    {
-        uint64_t const cbLeft = pThis->m_cbData - offContent;
+    if (offContent < pThis->m_cbContentLength)
+    {
+        uint64_t const cbLeft = pThis->m_cbContentLength - offContent;
         size_t const cbToCopy = cbLeft >= cbBuf ? cbBuf : (size_t)cbLeft;
         memcpy(pvBuf, &pThis->m_pbData[(size_t)offContent], cbToCopy);
@@ -217,7 +282,123 @@
 {
     /* Unset the callback. */
-    int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, NULL, NULL);
+    int rc = RTHttpSetUploadCallback(a_hHttp, UINT64_MAX, NULL, NULL);
     AssertRC(rc);
 }
 
 
+/*********************************************************************************************************************************
+*   Download related methods                                                                                                     *
+*********************************************************************************************************************************/
+
+void RTCRestBinaryString::setMaxDownloadSize(size_t a_cbMaxDownload)
+{
+    if (a_cbMaxDownload == 0)
+        m_cbMaxDownload = RTCREST_MAX_DOWNLOAD_SIZE_DEFAULT;
+    else
+        m_cbMaxDownload = a_cbMaxDownload;
+}
+
+
+void RTCRestBinaryString::setConsumerCallback(PFNCONSUMER a_pfnConsumer, void *a_pvCallbackData /*= NULL*/)
+{
+    freeData();
+
+    a_pfnConsumer    = a_pfnConsumer;
+    m_pvCallbackData = a_pvCallbackData;
+}
+
+
+int RTCRestBinaryString::receivePrepare(RTHTTP a_hHttp, uint32_t a_fCallbackFlags)
+{
+    /*
+     * Register an download callback.
+     */
+    int rc = RTHttpSetDownloadCallback(a_hHttp, a_fCallbackFlags, receiveHttpCallback, this);
+    AssertRCReturn(rc, rc);
+
+    return VINF_SUCCESS;
+}
+
+
+void RTCRestBinaryString::receiveComplete(RTHTTP a_hHttp)
+{
+    /* Unset the callback. */
+    int rc = RTHttpSetDownloadCallback(a_hHttp, RTHTTPDOWNLOAD_F_ANY_STATUS, NULL, NULL);
+    AssertRC(rc);
+}
+
+
+/*static*/ DECLCALLBACK(int)
+RTCRestBinaryString::receiveHttpCallback(RTHTTP hHttp, void const *pvBuf, size_t cbBuf, uint32_t uHttpStatus,
+                                         uint64_t offContent, uint64_t cbContent, void *pvUser)
+{
+    RTCRestBinaryString *pThis = (RTCRestBinaryString *)pvUser;
+    Assert(offContent == pThis->m_cbDownloaded);
+    pThis->m_cbContentLength = cbContent;
+
+    /*
+     * Call the user download callback if we've got one.
+     */
+    if (pThis->m_pfnConsumer)
+    {
+        int rc = pThis->m_pfnConsumer(pThis, pvBuf, cbBuf, uHttpStatus, offContent, cbContent);
+        if (RT_SUCCESS(rc))
+            pThis->m_cbDownloaded = offContent + cbBuf;
+        return rc;
+    }
+
+    /*
+     * Check download limit before adding more data.
+     */
+    AssertMsgReturn(offContent + cbBuf <= pThis->m_cbMaxDownload,
+                    ("%RU64 + %zu = %RU64; max=%RU64", offContent, cbBuf, offContent + cbBuf, pThis->m_cbMaxDownload),
+                    VERR_TOO_MUCH_DATA);
+    if (offContent == 0 && cbContent != UINT64_MAX)
+        AssertMsgReturn(cbContent <= pThis->m_cbMaxDownload, ("cbContent: %RU64; max=%RU64", cbContent,  pThis->m_cbMaxDownload),
+                        VERR_TOO_MUCH_DATA);
+
+    /*
+     * Make sure we've got buffer space before we copy in the data.
+     */
+    if (offContent + cbBuf <= pThis->m_cbAllocated)
+    { /* likely, except for the first time. */ }
+    else if (offContent == 0 && cbContent != UINT64_MAX)
+    {
+        void *pvNew = RTMemRealloc(pThis->m_pbData, (size_t)cbContent);
+        if (!pvNew)
+            return VERR_NO_MEMORY;
+        pThis->m_pbData = (uint8_t *)pvNew;
+        pThis->m_cbAllocated = (size_t)cbContent;
+    }
+    else
+    {
+        size_t cbNeeded = offContent + cbBuf;
+        size_t cbNew;
+        if (pThis->m_cbAllocated == 0)
+            cbNew = RT_MAX(_64K, RT_ALIGN_Z(cbNeeded, _64K));
+        else if (pThis->m_cbAllocated < _64M && cbNeeded <= _64M)
+        {
+            cbNew = pThis->m_cbAllocated * 2;
+            while (cbNew < cbNeeded)
+                cbNew *= 2;
+        }
+        else
+            cbNew = RT_ALIGN_Z(cbNeeded, _32M);
+
+        void *pvNew = RTMemRealloc(pThis->m_pbData, cbNew);
+        if (!pvNew)
+            return VERR_NO_MEMORY;
+        pThis->m_pbData = (uint8_t *)pvNew;
+        pThis->m_cbAllocated = cbNew;
+    }
+
+    /*
+     * Do the copying.
+     */
+    memcpy(&pThis->m_pbData[(size_t)offContent], pvBuf, cbBuf);
+    pThis->m_cbDownloaded = offContent + cbBuf;
+
+    RT_NOREF(hHttp);
+    return VINF_SUCCESS;
+}
+
Index: trunk/src/VBox/Runtime/generic/http-curl.cpp
===================================================================
--- trunk/src/VBox/Runtime/generic/http-curl.cpp	(revision 74125)
+++ trunk/src/VBox/Runtime/generic/http-curl.cpp	(revision 74126)
@@ -2906,6 +2906,6 @@
             rtHttpGetDownloadStatusAndLength(pThis);
 
-        if (   (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS
-            || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)
+        if (   (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_ANY_STATUS
+            || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)
         {
             int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbToAppend, pThis->uDownloadHttpStatus, pThis->offDownloadContent,
@@ -2990,6 +2990,6 @@
 
     /* Call the callback if the HTTP status code matches, otherwise let it go to /dev/null. */
-    if (   (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_F_ANY_STATUS
-        || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)
+    if (   (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == RTHTTPDOWNLOAD_F_ANY_STATUS
+        || (pThis->fDownloadCallback & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) == pThis->uDownloadHttpStatus)
     {
         int rc = pThis->pfnDownloadCallback(pThis, pchBuf, cbBuf, pThis->uDownloadHttpStatus, pThis->offDownloadContent,
@@ -3541,5 +3541,5 @@
     PRTHTTPINTERNAL pThis = hHttp;
     RTHTTP_VALID_RETURN(pThis);
-    AssertReturn(!pfnCallback || (fFlags & RTHTTPDOWNLOAD_F_F_ONLY_STATUS_MASK) != 0, VERR_INVALID_FLAGS);
+    AssertReturn(!pfnCallback || (fFlags & RTHTTPDOWNLOAD_F_ONLY_STATUS_MASK) != 0, VERR_INVALID_FLAGS);
 
     pThis->pfnDownloadCallback      = pfnCallback;
