Index: trunk/include/iprt/http-common.h
===================================================================
--- trunk/include/iprt/http-common.h	(revision 87004)
+++ trunk/include/iprt/http-common.h	(revision 87004)
@@ -0,0 +1,256 @@
+/* $Id$ */
+/** @file
+ * IPRT - Common (client / server) HTTP API.
+ */
+
+/*
+ * Copyright (C) 2012-2020 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef IPRT_INCLUDED_http_common_h
+#define IPRT_INCLUDED_http_common_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/list.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** HTTP methods. */
+typedef enum RTHTTPMETHOD
+{
+    RTHTTPMETHOD_INVALID = 0,
+    RTHTTPMETHOD_GET,
+    RTHTTPMETHOD_PUT,
+    RTHTTPMETHOD_POST,
+    RTHTTPMETHOD_PATCH,
+    RTHTTPMETHOD_DELETE,
+    RTHTTPMETHOD_HEAD,
+    RTHTTPMETHOD_OPTIONS,
+    RTHTTPMETHOD_TRACE,
+    RTHTTPMETHOD_END,
+    RTHTTPMETHOD_32BIT_HACK = 0x7fffffff
+} RTHTTPMETHOD;
+
+/** HTTP status codes. */
+typedef enum RTHTTPSTATUS
+{
+    RTHTTPSTATUS_INTERNAL_NOT_SET              = 0,
+    /**
+     * 2xx - Success / information codes.
+     */
+    RTHTTPSTATUS_OK                            = 200,
+	RTHTTPSTATUS_CREATED                       = 201,
+	RTHTTPSTATUS_ACCEPTED                      = 202,
+	RTHTTPSTATUS_NONAUTHORITATIVEINFORMATION   = 203,
+	RTHTTPSTATUS_NOCONTENT                     = 204,
+	RTHTTPSTATUS_RESETCONTENT                  = 205,
+	RTHTTPSTATUS_PARTIALCONTENT                = 206,
+	RTHTTPSTATUS_MULTISTATUS                   = 207,
+	RTHTTPSTATUS_ALREADYREPORTED               = 208,
+	RTHTTPSTATUS_IMUSED                        = 226,
+    /**
+     * 4xx - Client error codes.
+     */
+    RTHTTPSTATUS_BADREQUEST                    = 400,
+    RTHTTPSTATUS_UNAUTHORIZED                  = 401,
+    RTHTTPSTATUS_PAYMENTREQUIRED               = 402,
+    RTHTTPSTATUS_FORBIDDEN                     = 403,
+    RTHTTPSTATUS_NOTFOUND                      = 404,
+    RTHTTPSTATUS_METHODNOTALLOWED              = 405,
+    RTHTTPSTATUS_NOTACCEPTABLE                 = 406,
+    RTHTTPSTATUS_PROXYAUTHENTICATIONREQUIRED   = 407,
+    RTHTTPSTATUS_REQUESTTIMEOUT                = 408,
+    RTHTTPSTATUS_CONFLICT                      = 409,
+    RTHTTPSTATUS_GONE                          = 410,
+    RTHTTPSTATUS_LENGTHREQUIRED                = 411,
+    RTHTTPSTATUS_PRECONDITIONFAILED            = 412,
+    RTHTTPSTATUS_PAYLOADTOOLARGE               = 413,
+    RTHTTPSTATUS_URITOOLONG                    = 414,
+    RTHTTPSTATUS_UNSUPPORTEDMEDIATYPE          = 415,
+    RTHTTPSTATUS_RANGENOTSATISFIABLE           = 416,
+    RTHTTPSTATUS_EXPECTATIONFAILED             = 417,
+    RTHTTPSTATUS_IMATEAPOT                     = 418,
+    RTHTTPSTATUS_UNPROCESSABLEENTITY           = 422,
+    RTHTTPSTATUS_LOCKED                        = 423,
+    RTHTTPSTATUS_FAILEDDEPENDENCY              = 424,
+    RTHTTPSTATUS_UPGRADEREQUIRED               = 426,
+    RTHTTPSTATUS_PRECONDITIONREQUIRED          = 428,
+    RTHTTPSTATUS_TOOMANYREQUESTS               = 429,
+    RTHTTPSTATUS_REQUESTHEADERFIELDSTOOLARGE   = 431,
+    RTHTTPSTATUS_UNAVAILABLEFORLEGALREASONS    = 451,
+    /**
+     * 5xx - Server error codes.
+     */
+    RTHTTPSTATUS_INTERNALSERVERERROR           = 500,
+    RTHTTPSTATUS_NOTIMPLEMENTED                = 501,
+    RTHTTPSTATUS_BADGATEWAY                    = 502,
+    RTHTTPSTATUS_SERVICEUNAVAILABLE            = 503,
+    RTHTTPSTATUS_GATEWAYTIMEOUT                = 504,
+    RTHTTPSTATUS_HTTPVERSIONNOTSUPPORTED       = 505,
+    RTHTTPSTATUS_VARIANTALSONEGOTIATES         = 506,
+    RTHTTPSTATUS_INSUFFICIENTSTORAGE           = 507,
+    RTHTTPSTATUS_LOOPDETECTED                  = 508,
+    RTHTTPSTATUS_NOTEXTENDED                   = 510,
+    RTHTTPSTATUS_NETWORKAUTHENTICATIONREQUIRED = 511,
+
+    RTHTTPSTATUS_32BIT_HACK                    = 0x7fffffff
+} RTHTTPSTATUS;
+
+/** Checks whether a HTTP status is of type "informational" or not. */
+#define RTHTTPSTATUS_IS_INFO(a_Code)        (a_Code >= 100 && a_Code < 200)
+/** Checks whether a HTTP status indicates success or not. */
+#define RTHTTPSTATUS_IS_OK(a_Code)          (a_Code >= 200 && a_Code < 300)
+/** Checks whether a HTTP status indicates a redirection or not. */
+#define RTHTTPSTATUS_IS_REDIRECT(a_Code)    (a_Code >= 300 && a_Code < 400)
+/** Checks whether a HTTP status indicates a client error or not. */
+#define RTHTTPSTATUS_IS_CLIENTERROR(a_Code) (a_Code >= 400 && a_Code < 500)
+/** Checks whether a HTTP status indicates a server error or not. */
+#define RTHTTPSTATUS_IS_SERVERERROR(a_Code) (a_Code >= 500 && a_Code < 600)
+/** Checks whether a HTTP status indicates an error or not. */
+#define RTHTTPSTATUS_IS_ERROR(a_Code)       (a_Code >= 400)
+
+/** Specifies a HTTP MIME type. */
+typedef uint32_t RTHTTPMIMETYPE;
+
+#define RTHTTPMIMETYPE_TEXT_PLAIN               "text/plain"
+#define RTHTTPMIMETYPE_APPLICATION_OCTET_STREAM "application/octet-stream"
+
+/** Specifies HTTP version 1.1 as a string. */
+#define RTHTTPVER_1_1_STR                       "HTTP/1.1"
+
+/** @todo the following three definitions may move the iprt/types.h later. */
+/** HTTP header list handle. */
+typedef R3PTRTYPE(struct RTHTTPHEADERLISTINTERNAL *) RTHTTPHEADERLIST;
+/** Pointer to a HTTP header list handle. */
+typedef RTHTTPHEADERLIST                            *PRTHTTPHEADERLIST;
+/** Nil HTTP HTTP header list handle. */
+#define NIL_RTHTTPHEADERLIST                         ((RTHTTPHEADERLIST)0)
+
+/**
+ * HTTP header list entry.
+ */
+typedef struct RTHTTPHEADERENTRY
+{
+    /** The list node. */
+    RTLISTNODE          Node;
+    /** The field name length. */
+    uint32_t            cchName;
+    /** The value offset. */
+    uint32_t            offValue;
+    /** The full header field. */
+    RT_FLEXIBLE_ARRAY_EXTENSION
+    RT_GCC_EXTENSION char szData[RT_FLEXIBLE_ARRAY];
+} RTHTTPHEADERENTRY;
+/** Pointer to a HTTP header. */
+typedef RTHTTPHEADERENTRY *PRTHTTPHEADERENTRY;
+
+/**
+ * Returns the name of the HTTP method.
+ * @returns Read only string.
+ * @param   enmMethod       The HTTP method to name.
+ */
+RTR3DECL(const char *) RTHttpMethodToStr(RTHTTPMETHOD enmMethod);
+
+RTR3DECL(const char *) RTHttpStatusToStr(RTHTTPSTATUS enmSts);
+
+RTR3DECL(int) RTHttpHeaderListInit(PRTHTTPHEADERLIST hHdrList);
+
+RTR3DECL(void) RTHttpHeaderListDestroy(RTHTTPHEADERLIST hHdrList);
+
+/**
+ * Set custom raw headers.
+ *
+ * @returns IPRT status code.
+ * @param   hHdrLst         The HTTP header list handle.
+ * @param   cHeaders        Number of custom headers.
+ * @param   papszHeaders    Array of headers in form "foo: bar".
+ */
+RTR3DECL(int) RTHttpHeaderListSet(RTHTTPHEADERLIST hHdrLst, size_t cHeaders, const char * const *papszHeaders);
+
+/** @name RTHTTPHEADERLISTADD_F_XXX - Flags for RTHttpHeaderListAddRaw and RTHttpHeaderListAdd
+ * @{ */
+#define RTHTTPHEADERLISTADD_F_BACK     UINT32_C(0) /**< Append the header. */
+#define RTHTTPHEADERLISTADD_F_FRONT    UINT32_C(1) /**< Prepend the header. */
+/** @} */
+
+/**
+ * Adds a raw header.
+ *
+ * @returns IPRT status code.
+ * @param   hHdrLst         The HTTP header list handle.
+ * @param   pszHeader       Header string on the form "foo: bar".
+ * @param   fFlags          RTHTTPADDHDR_F_FRONT or RTHTTPADDHDR_F_BACK.
+ */
+RTR3DECL(int) RTHttpHeaderListAddRaw(RTHTTPHEADERLIST hHdrLst, const char *pszHeader, uint32_t fFlags);
+
+/**
+ * Adds a header field and value.
+ *
+ * @returns IPRT status code.
+ * @param   hHdrLst         The HTTP header list handle.
+ * @param   pszField        The header field name.
+ * @param   pszValue        The header field value.
+ * @param   cchValue        The value length or RTSTR_MAX.
+ * @param   fFlags          Only RTHTTPADDHDR_F_FRONT or RTHTTPADDHDR_F_BACK,
+ *                          may be extended with encoding controlling flags if
+ *                          needed later.
+ */
+RTR3DECL(int) RTHttpHeaderListAdd(RTHTTPHEADERLIST hHdrLst, const char *pszField, const char *pszValue, size_t cchValue, uint32_t fFlags);
+
+/**
+ * Gets a header previously added using RTHttpSetHeaders, RTHttpAppendRawHeader
+ * or RTHttpAppendHeader.
+ *
+ * @returns Pointer to the header value on if found, otherwise NULL.
+ * @param   hHdrLst         The HTTP header list handle.
+ * @param   pszField        The field name (no colon).
+ * @param   cchField        The length of the field name or RTSTR_MAX.
+ */
+RTR3DECL(const char *) RTHttpHeaderListGet(RTHTTPHEADERLIST hHdrLst, const char *pszField, size_t cchField);
+
+/**
+ * Gets the number of headers specified by RTHttpAddHeader, RTHttpAddRawHeader or RTHttpSetHeaders.
+ *
+ * @returns Number of headers.
+ * @param   hHdrLst         The HTTP header list handle.
+ * @note    This can be slow and is only really intended for test cases and debugging!
+ */
+RTR3DECL(size_t)    RTHttpHeaderListGetCount(RTHTTPHEADERLIST hHdrLst);
+
+/**
+ * Gets a header by ordinal.
+ *
+ * Can be used together with RTHttpGetHeaderCount by test case and debug code to
+ * iterate headers specified by RTHttpAddHeader, RTHttpAddRawHeader or RTHttpSetHeaders.
+ *
+ * @returns The header string ("field: value").
+ * @param   hHdrLst         The HTTP header list handle.
+ * @param   iOrdinal        The number of the header to get.
+ * @note    This can be slow and is only really intended for test cases and debugging!
+ */
+RTR3DECL(const char *) RTHttpHeaderListGetByOrdinal(RTHTTPHEADERLIST hHdrLst, size_t iOrdinal);
+
+RT_C_DECLS_END
+
+#endif /* !IPRT_INCLUDED_http_common_h */
+
Index: trunk/include/iprt/http-server.h
===================================================================
--- trunk/include/iprt/http-server.h	(revision 87004)
+++ trunk/include/iprt/http-server.h	(revision 87004)
@@ -0,0 +1,162 @@
+/* $Id$ */
+/** @file
+ * Header file for HTTP server implementation.
+ */
+
+/*
+ * Copyright (C) 2020 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef IPRT_INCLUDED_http_server_h
+#define IPRT_INCLUDED_http_server_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/http-common.h>
+#include <iprt/types.h>
+#include <iprt/fs.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_http       RTHttp - HTTP server.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @defgroup grp_rt_httpserver  RTHttpServer - HTTP server implementation.
+ * @{
+ */
+
+/** @todo the following three definitions may move the iprt/types.h later. */
+/** HTTP server handle. */
+typedef R3PTRTYPE(struct RTHTTPSERVERINTERNAL *) RTHTTPSERVER;
+/** Pointer to a HTTP server handle. */
+typedef RTHTTPSERVER                            *PRTHTTPSERVER;
+/** Nil HTTP client handle. */
+#define NIL_RTHTTPSERVER                         ((RTHTTPSERVER)0)
+
+/**
+ * Structure for maintaining a HTTP client request.
+ */
+typedef struct RTHTTPSERVERREQ
+{
+    char            *pszUrl;
+    RTHTTPMETHOD     enmMethod;
+    RTHTTPHEADERLIST hHdrLst;
+    void            *pvBody;
+    size_t           cbBodyAlloc;
+    size_t           cbBodyUsed;
+} RTHTTPSERVERREQ;
+/** Pointer to a HTTP client request. */
+typedef RTHTTPSERVERREQ *PRTHTTPSERVERREQ;
+
+/**
+ * Structure for maintaining a HTTP server response.
+ */
+typedef struct RTHTTPSERVERRESP
+{
+    RTHTTPSTATUS     enmSts;
+    RTHTTPHEADERLIST hHdrLst;
+    void            *pvBody;
+    size_t           cbBodyAlloc;
+    size_t           cbBodyUsed;
+} RTHTTPSERVERRESP;
+/** Pointer to a HTTP server response. */
+typedef RTHTTPSERVERRESP *PRTHTTPSERVERRESP;
+
+/**
+ * Structure for maintaining a HTTP server client state.
+ *
+ * Note: The HTTP protocol itself is stateless, but we want to have to possibility to store
+ *       some state stuff here nevertheless.
+ */
+typedef struct RTHTTPSERVERCLIENTSTATE
+{
+
+} RTHTTPSERVERCLIENTSTATE;
+/** Pointer to a FTP server client state. */
+typedef RTHTTPSERVERCLIENTSTATE *PRTHTTPSERVERCLIENTSTATE;
+
+/**
+ * Structure for storing HTTP server callback data.
+ */
+typedef struct RTHTTPCALLBACKDATA
+{
+    /** Pointer to the client state. */
+    PRTHTTPSERVERCLIENTSTATE pClient;
+    /** Saved user pointer. */
+    void                    *pvUser;
+    /** Size (in bytes) of data at user pointer. */
+    size_t                   cbUser;
+} RTHTTPCALLBACKDATA;
+/** Pointer to HTTP server callback data. */
+typedef RTHTTPCALLBACKDATA *PRTHTTPCALLBACKDATA;
+
+/**
+ * Function callback table for the HTTP server implementation.
+ *
+ * All callbacks are optional and therefore can be NULL.
+ */
+typedef struct RTHTTPSERVERCALLBACKS
+{
+    DECLCALLBACKMEMBER(int, pfnOpen,(PRTHTTPCALLBACKDATA pData, const char *pszUrl, uint64_t *pidObj));
+    DECLCALLBACKMEMBER(int, pfnRead,(PRTHTTPCALLBACKDATA pData, uint64_t idObj, void *pvBuf, size_t cbBuf, size_t *pcbRead));
+    DECLCALLBACKMEMBER(int, pfnClose,(PRTHTTPCALLBACKDATA pData, uint64_t idObj));
+    DECLCALLBACKMEMBER(int, pfnQueryInfo,(PRTHTTPCALLBACKDATA pData, const char *pszUrl, PRTFSOBJINFO pObjInfo));
+    DECLCALLBACKMEMBER(int, pfnOnGetRequest,(PRTHTTPCALLBACKDATA pData, PRTHTTPSERVERREQ pReq));
+    DECLCALLBACKMEMBER(int, pfnOnHeadRequest,(PRTHTTPCALLBACKDATA pData, PRTHTTPSERVERREQ pReq));
+} RTHTTPSERVERCALLBACKS;
+/** Pointer to a HTTP server callback data table. */
+typedef RTHTTPSERVERCALLBACKS *PRTHTTPSERVERCALLBACKS;
+
+/** Maximum length (in bytes) a client request can have. */
+#define RTHTTPSERVER_MAX_REQ_LEN        _8K
+
+/**
+ * Creates a HTTP server instance.
+ *
+ * @returns IPRT status code.
+ * @param   phHTTPServer        Where to store the HTTP server handle.
+ * @param   pcszAddress         The address for creating a listening socket.
+ *                              If NULL or empty string the server is bound to all interfaces.
+ * @param   uPort               The port for creating a listening socket.
+ * @param   pCallbacks          Callback table to use.
+ * @param   pvUser              Pointer to user-specific data. Optional.
+ * @param   cbUser              Size of user-specific data. Optional.
+ */
+RTR3DECL(int) RTHttpServerCreate(PRTHTTPSERVER phHttpServer, const char *pcszAddress, uint16_t uPort,
+                                 PRTHTTPSERVERCALLBACKS pCallbacks, void *pvUser, size_t cbUser);
+
+/**
+ * Destroys a HTTP server instance.
+ *
+ * @returns IPRT status code.
+ * @param   hHttpServer          Handle to the HTTP server handle.
+ */
+RTR3DECL(int) RTHttpServerDestroy(RTHTTPSERVER hHttpServer);
+
+/** @} */
+
+/** @} */
+RT_C_DECLS_END
+
+#endif /* !IPRT_INCLUDED_http_server_h */
+
Index: trunk/include/iprt/http.h
===================================================================
--- trunk/include/iprt/http.h	(revision 86973)
+++ trunk/include/iprt/http.h	(revision 87004)
@@ -32,4 +32,5 @@
 
 #include <iprt/types.h>
+#include <iprt/http-common.h>
 
 RT_C_DECLS_BEGIN
@@ -206,27 +207,4 @@
  */
 RTR3DECL(int) RTHttpGetFile(RTHTTP hHttp, const char *pszUrl, const char *pszDstFile);
-
-/** HTTP methods. */
-typedef enum RTHTTPMETHOD
-{
-    RTHTTPMETHOD_INVALID = 0,
-    RTHTTPMETHOD_GET,
-    RTHTTPMETHOD_PUT,
-    RTHTTPMETHOD_POST,
-    RTHTTPMETHOD_PATCH,
-    RTHTTPMETHOD_DELETE,
-    RTHTTPMETHOD_HEAD,
-    RTHTTPMETHOD_OPTIONS,
-    RTHTTPMETHOD_TRACE,
-    RTHTTPMETHOD_END,
-    RTHTTPMETHOD_32BIT_HACK = 0x7fffffff
-} RTHTTPMETHOD;
-
-/**
- * Returns the name of the HTTP method.
- * @returns Read only string.
- * @param   enmMethod       The HTTP method to name.
- */
-RTR3DECL(const char *) RTHttpMethodName(RTHTTPMETHOD enmMethod);
 
 /**
Index: trunk/include/iprt/mangling.h
===================================================================
--- trunk/include/iprt/mangling.h	(revision 86973)
+++ trunk/include/iprt/mangling.h	(revision 87004)
@@ -1174,6 +1174,18 @@
 # define RTHttpSetFollowRedirects                       RT_MANGLER(RTHttpSetFollowRedirects)
 # define RTHttpGetVerifyPeer                            RT_MANGLER(RTHttpGetVerifyPeer)
+# define RTHttpHeaderListInit                           RT_MANGLER(RTHttpHeaderListInit)
+# define RTHttpHeaderListDestroy                        RT_MANGLER(RTHttpHeaderListDestroy)
+# define RTHttpHeaderListSet                            RT_MANGLER(RTHttpHeaderListSet)
+# define RTHttpHeaderListAddRaw                         RT_MANGLER(RTHttpHeaderListAddRaw)
+# define RTHttpHeaderListAdd                            RT_MANGLER(RTHttpHeaderListAdd)
+# define RTHttpHeaderListGet                            RT_MANGLER(RTHttpHeaderListGet)
+# define RTHttpHeaderListGetCount                       RT_MANGLER(RTHttpHeaderListGetCount)
+# define RTHttpHeaderListGetByOrdinal                   RT_MANGLER(RTHttpHeaderListGetByOrdinal)
+# define RTHttpMethodToStr                              RT_MANGLER(RTHttpMethodToStr)
 # define RTHttpSetVerifyPeer                            RT_MANGLER(RTHttpSetVerifyPeer)
 # define RTHttpUseSystemProxySettings                   RT_MANGLER(RTHttpUseSystemProxySettings)
+# define RTHttpServerCreate                             RT_MANGLER(RTHttpServerCreate)
+# define RTHttpServerDestroy                            RT_MANGLER(RTHttpServerDestroy)
+# define RTHttpStatusToStr                              RT_MANGLER(RTHttpStatusToStr)
 # define RTIniFileCreateFromVfsFile                     RT_MANGLER(RTIniFileCreateFromVfsFile)
 # define RTIniFileRetain                                RT_MANGLER(RTIniFileRetain)
