Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 45453)
+++ /trunk/include/iprt/err.h	(revision 45454)
@@ -1588,4 +1588,6 @@
 /** Certificate cannot be authenticated with the given CA certificates. */
 #define VERR_HTTP_CACERT_CANNOT_AUTHENTICATE    (-892)
+/** The current HTTP request was forcefully aborted */
+#define VERR_HTTP_ABORTED                       (-893)
 /** @} */
 
Index: /trunk/include/iprt/http.h
===================================================================
--- /trunk/include/iprt/http.h	(revision 45453)
+++ /trunk/include/iprt/http.h	(revision 45454)
@@ -75,4 +75,15 @@
 
 /**
+ * Abort a pending HTTP request. A blocking RTHttpGet() call will return with
+ * VERR_HTTP_ABORTED. It may take some time (current cURL implementation needs
+ * up to 1 second) before the request is aborted.
+ *
+ * @returns iprt status code.
+ *
+ * @param    hHttp         HTTP interface handle.
+ */
+RTR3DECL(int) RTHttpAbort(RTHTTP hHttp);
+
+/**
  * Specify proxy settings.
  *
Index: /trunk/src/VBox/Runtime/common/misc/http.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/http.cpp	(revision 45453)
+++ /trunk/src/VBox/Runtime/common/misc/http.cpp	(revision 45454)
@@ -47,9 +47,15 @@
 typedef struct RTHTTPINTERNAL
 {
+    /** magic value */
     uint32_t u32Magic;
+    /** cURL handle */
     CURL *pCurl;
     long lLastResp;
+    /** custom headers */
     struct curl_slist *pHeaders;
+    /** CA certificate for HTTPS authentication check */
     const char *pcszCAFile;
+    /** abort the current HTTP request if true */
+    bool fAbort;
 } RTHTTPINTERNAL;
 typedef RTHTTPINTERNAL *PRTHTTPINTERNAL;
@@ -129,5 +135,5 @@
 }
 
-static size_t rtHttpWriteData(void *pvBuf, size_t cb, size_t n, void *pvUser)
+static DECLCALLBACK(size_t) rtHttpWriteData(void *pvBuf, size_t cb, size_t n, void *pvUser)
 {
     PRTHTTPMEMCHUNK pMem = (PRTHTTPMEMCHUNK)pvUser;
@@ -142,4 +148,23 @@
     }
     return cbAll;
+}
+
+static DECLCALLBACK(int) rtHttpProgress(void *pData, double DlTotal, double DlNow,
+                                        double UlTotal, double UlNow)
+{
+    PRTHTTPINTERNAL pHttpInt = (PRTHTTPINTERNAL)pData;
+    AssertReturn(pHttpInt->u32Magic == RTHTTP_MAGIC, 1);
+
+    return pHttpInt->fAbort ? 1 : 0;
+}
+
+RTR3DECL(int) RTHttpAbort(RTHTTP hHttp)
+{
+    PRTHTTPINTERNAL pHttpInt = hHttp;
+    RTHTTP_VALID_RETURN(pHttpInt);
+
+    pHttpInt->fAbort = true;
+
+    return VINF_SUCCESS;
 }
 
@@ -278,4 +303,6 @@
     RTHTTP_VALID_RETURN(pHttpInt);
 
+    pHttpInt->fAbort = false;
+
     int rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_URL, pcszUrl);
     if (CURL_FAILED(rcCurl))
@@ -303,4 +330,13 @@
         return VERR_INTERNAL_ERROR;
     rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_WRITEDATA, (void*)&chunk);
+    if (CURL_FAILED(rcCurl))
+        return VERR_INTERNAL_ERROR;
+    rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROGRESSFUNCTION, &rtHttpProgress);
+    if (CURL_FAILED(rcCurl))
+        return VERR_INTERNAL_ERROR;
+    rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROGRESSDATA, (void*)pHttpInt);
+    if (CURL_FAILED(rcCurl))
+        return VERR_INTERNAL_ERROR;
+    rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_NOPROGRESS, (long)0);
     if (CURL_FAILED(rcCurl))
         return VERR_INTERNAL_ERROR;
@@ -356,4 +392,8 @@
                 rc = VERR_HTTP_CACERT_WRONG_FORMAT;
                 break;
+            case CURLE_ABORTED_BY_CALLBACK:
+                /* forcefully aborted */
+                rc = VERR_HTTP_ABORTED;
+                break;
             default:
                 break;
