VirtualBox

Changeset 87016 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 30, 2020 4:45:54 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
141597
Message:

Shared Clipboard/Transfers: Initial code for directory listing support. More documentation. bugref:9874

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/http-server.cpp

    r87013 r87016  
    160160            return pCallbacks->a_Name(&Data, __VA_ARGS__); \
    161161        } \
    162         return VERR_NOT_IMPLEMENTED; \
    163162    } while (0)
    164163
     
    355354}
    356355
     356/**
     357 * Initializes a HTTP server response with an allocated body size.
     358 *
     359 * @returns VBox status code.
     360 * @param   pResp               HTTP server response to initialize.
     361 * @param   cbBody              Body size (in bytes) to allocate.
     362 */
     363RTR3DECL(int) RTHttpServerResponseInitEx(PRTHTTPSERVERRESP pResp, size_t cbBody)
     364{
     365    pResp->enmSts = RTHTTPSTATUS_INTERNAL_NOT_SET;
     366
     367    int rc = RTHttpHeaderListInit(&pResp->hHdrLst);
     368    AssertRCReturn(rc, rc);
     369
     370    if (cbBody)
     371    {
     372        pResp->pvBody      = RTMemAlloc(cbBody);
     373        AssertPtrReturn(pResp->pvBody, VERR_NO_MEMORY);
     374        pResp->cbBodyAlloc = cbBody;
     375    }
     376    else
     377    {
     378        pResp->cbBodyAlloc = 0;
     379    }
     380
     381    pResp->cbBodyUsed = 0;
     382
     383    return rc;
     384}
     385
     386/**
     387 * Initializes a HTTP server response.
     388 *
     389 * @returns VBox status code.
     390 * @param   pResp               HTTP server response to initialize.
     391 */
     392RTR3DECL(int) RTHttpServerResponseInit(PRTHTTPSERVERRESP pResp)
     393{
     394    return RTHttpServerResponseInitEx(pResp, 0 /* cbBody */);
     395}
     396
     397/**
     398 * Destroys a formerly initialized HTTP server response.
     399 *
     400 * @param   pResp               Pointer to HTTP server response to destroy.
     401 */
     402RTR3DECL(void) RTHttpServerResponseDestroy(PRTHTTPSERVERRESP pResp)
     403{
     404    if (!pResp)
     405        return;
     406
     407    pResp->enmSts = RTHTTPSTATUS_INTERNAL_NOT_SET;
     408
     409    RTHttpHeaderListDestroy(pResp->hHdrLst);
     410
     411    if (pResp->pvBody)
     412    {
     413        Assert(pResp->cbBodyAlloc);
     414
     415        RTMemFree(pResp->pvBody);
     416        pResp->pvBody = NULL;
     417    }
     418
     419    pResp->cbBodyAlloc = 0;
     420    pResp->cbBodyUsed  = 0;
     421}
     422
    357423
    358424/*********************************************************************************************************************************
     
    522588    int rc;
    523589
     590    /* If a low-level GET request handler is defined, call it and return. */
     591    RTHTTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnGetRequest, pReq);
     592
    524593    RTFSOBJINFO fsObj;
    525594    RT_ZERO(fsObj); /* Shut up MSVC. */
    526     RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnQueryInfo, pReq->pszUrl, &fsObj);
     595
     596    char *pszMIMEHint = NULL;
     597
     598    RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnQueryInfo, pReq->pszUrl, &fsObj, &pszMIMEHint);
    527599    if (RT_FAILURE(rc))
    528600        return rc;
    529601
    530     uint64_t uID = 0; /* Ditto. */
    531     RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnOpen, pReq->pszUrl, &uID);
     602    void *pvHandle;
     603    RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnOpen, pReq->pszUrl, &pvHandle);
    532604
    533605    if (RT_SUCCESS(rc))
     
    545617            char szVal[16];
    546618
     619            /* Note: For directories fsObj.cbObject contains the actual size (in bytes)
     620             *       of the body data for the directory listing. */
     621
    547622            ssize_t cch = RTStrPrintf2(szVal, sizeof(szVal), "%RU64", fsObj.cbObject);
    548623            AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW);
     
    555630            AssertRCBreak(rc);
    556631
    557             const char *pszMIME = rtHttpServerGuessMIMEType(RTPathSuffix(pReq->pszUrl));
    558             rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIME, strlen(pszMIME), RTHTTPHEADERLISTADD_F_BACK);
     632            if (pszMIMEHint == NULL)
     633            {
     634                const char *pszMIME = rtHttpServerGuessMIMEType(RTPathSuffix(pReq->pszUrl));
     635                rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIME, strlen(pszMIME), RTHTTPHEADERLISTADD_F_BACK);
     636            }
     637            else
     638            {
     639                rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIMEHint, strlen(pszMIMEHint), RTHTTPHEADERLISTADD_F_BACK);
     640                RTStrFree(pszMIMEHint);
     641                pszMIMEHint = NULL;
     642            }
    559643            AssertRCReturn(rc, rc);
    560644
     
    569653            while (cbToRead)
    570654            {
    571                 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnRead, uID, pvBuf, RT_MIN(cbBuf, cbToRead), &cbRead);
     655                RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnRead, pvHandle, pvBuf, RT_MIN(cbBuf, cbToRead), &cbRead);
    572656                if (RT_FAILURE(rc))
    573657                    break;
     
    590674        int rc2 = rc; /* Save rc. */
    591675
    592         RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnClose, uID);
     676        RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnClose, pvHandle);
    593677
    594678        if (RT_FAILURE(rc2)) /* Restore original rc on failure. */
     
    611695    LogFlowFuncEnter();
    612696
     697    /* If a low-level HEAD request handler is defined, call it and return. */
     698    RTHTTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnHeadRequest, pReq);
     699
    613700    int rc;
    614701
    615702    RTFSOBJINFO fsObj;
    616703    RT_ZERO(fsObj); /* Shut up MSVC. */
    617     RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnQueryInfo, pReq->pszUrl, &fsObj);
     704
     705    char *pszMIMEHint = NULL;
     706
     707    RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnQueryInfo, pReq->pszUrl, &fsObj, &pszMIMEHint);
    618708    if (RT_SUCCESS(rc))
    619709    {
  • trunk/src/VBox/Runtime/tools/RTHttpServer.cpp

    r87004 r87016  
    6969    /** The absolute path of the HTTP server's root directory. */
    7070    char szPathRootAbs[RTPATH_MAX];
    71     /** The relative current working directory (CWD) to szRootDir. */
    72     char szCWD[RTPATH_MAX];
     71    RTFMODE      fMode;
    7372    union
    7473    {
    75         RTFILE File;
    76         RTDIR Dir;
     74        RTFILE   File;
     75        RTVFSDIR Dir;
    7776    } h;
     77    /** Cached response data. */
     78    RTHTTPSERVERRESP Resp;
    7879} HTTPSERVERDATA;
    7980typedef HTTPSERVERDATA *PHTTPSERVERDATA;
     
    289290        }
    290291
     292        /* Skip dot directories. */
     293        if (RTDirEntryExIsStdDotLink(pDirEntry))
     294            continue;
     295
    291296        *ppszEntry = RTStrDup(pDirEntry->szName);
    292297        AssertPtrReturn(*ppszEntry, VERR_NO_MEMORY);
     
    305310
    306311static int dirEntryWrite(char *pszBuf, size_t cbBuf,
    307                          const char *pszEntry, const PRTFSOBJINFO pInfo, size_t *pcbWritten)
    308 {
    309     RT_NOREF(pInfo);
    310 
    311     ssize_t cch = RTStrPrintf2(pszBuf, cbBuf, "201: %s\r\n", pszEntry);
     312                         const char *pszEntry, const PRTFSOBJINFO pObjInfo, size_t *pcbWritten)
     313{
     314    char szModTime[32];
     315    if (RTTimeSpecToString(&pObjInfo->ModificationTime, szModTime, sizeof(szModTime)) == NULL)
     316        return VERR_BUFFER_UNDERFLOW;
     317
     318    int rc = VINF_SUCCESS;
     319
     320    ssize_t cch = RTStrPrintf2(pszBuf, cbBuf, "201: %s %RU64 %s %s\r\n",
     321                               pszEntry, pObjInfo->cbObject, szModTime,
     322                               /** @todo Very crude; only files and directories are supported for now. */
     323                               RTFS_IS_FILE(pObjInfo->Attr.fMode) ? "FILE" : "DIRECTORY");
    312324    if (cch <= 0)
    313         return VERR_BUFFER_OVERFLOW;
    314 
    315     /*
    316     Content-type:
    317     Last-Modified:
    318     Content-Length:
    319     */
    320 
    321     *pcbWritten = (size_t)cch;
    322 
    323     return VINF_SUCCESS;
    324 }
    325 
    326 static DECLCALLBACK(int) onGetRequest(PRTHTTPCALLBACKDATA pData, PRTHTTPSERVERREQ pReq)
    327 {
    328     PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
    329     Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
    330 
    331     /* Construct absolute path. */
    332     char *pszPathAbs = NULL;
    333     if (RTStrAPrintf(&pszPathAbs, "%s/%s", pThis->szPathRootAbs, pReq->pszUrl) <= 0)
    334         return VERR_NO_MEMORY;
    335 
    336     RTVFSDIR hVfsDir;
    337     int rc = dirOpen(pszPathAbs, &hVfsDir);
     325        rc = VERR_BUFFER_OVERFLOW;
     326
    338327    if (RT_SUCCESS(rc))
    339328    {
    340         pReq->pvBody      = RTMemAlloc(_4K);
    341         AssertPtrReturn(pReq->pvBody, VERR_NO_MEMORY); /** @todo Leaks stuff. */
    342         pReq->cbBodyAlloc = _4K;
    343         pReq->cbBodyUsed  =  0;
    344 
    345         char *pszEntry  = NULL;
    346         RTFSOBJINFO fsObjInfo;
    347 
    348         while (RT_SUCCESS(rc = dirRead(hVfsDir, &pszEntry, &fsObjInfo)))
    349         {
    350             char *pszBody = (char *)pReq->pvBody;
    351 
    352             size_t cbWritten;
    353             rc = dirEntryWrite(&pszBody[pReq->cbBodyUsed], pReq->cbBodyAlloc - pReq->cbBodyUsed, pszEntry, &fsObjInfo, &cbWritten);
    354             if (rc == VERR_BUFFER_OVERFLOW)
    355             {
    356                 pReq->cbBodyAlloc *= 2; /** @todo Improve this. */
    357                 pReq->pvBody       = RTMemRealloc(pReq->pvBody, pReq->cbBodyAlloc);
    358                 AssertPtrBreakStmt(pReq->pvBody, rc = VERR_NO_MEMORY);
    359 
    360                 pszBody = (char *)pReq->pvBody;
    361 
    362                 rc = dirEntryWrite(&pszBody[pReq->cbBodyUsed], pReq->cbBodyAlloc - pReq->cbBodyUsed, pszEntry, &fsObjInfo, &cbWritten);
    363             }
    364 
    365             if (RT_SUCCESS(rc))
    366                 pReq->cbBodyUsed += cbWritten;
    367 
    368             RTStrFree(pszEntry);
    369 
    370             if (RT_FAILURE(rc))
    371                 break;
    372         }
    373 
    374         if (rc == VERR_NO_MORE_FILES) /* All entries consumed? */
    375             rc = VINF_SUCCESS;
    376 
    377         dirClose(hVfsDir);
    378     }
    379 
    380     RTStrFree(pszPathAbs);
     329        *pcbWritten = (size_t)cch;
     330    }
     331
    381332    return rc;
    382333}
    383334
    384 static DECLCALLBACK(int) onHeadRequest(PRTHTTPCALLBACKDATA pData, PRTHTTPSERVERREQ pReq)
    385 {
    386     RT_NOREF(pData, pReq);
    387 
    388     return VINF_SUCCESS;
    389 }
    390 
    391 DECLCALLBACK(int) onOpen(PRTHTTPCALLBACKDATA pData, const char *pszUrl, uint64_t *pidObj)
    392 {
    393     PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
    394     Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
    395 
     335/**
     336 * Resolves (and validates) a given URL to an absolute (local) path.
     337 *
     338 * @returns VBox status code.
     339 * @param   pThis               HTTP server instance data.
     340 * @param   pszUrl              URL to resolve.
     341 * @param   ppszPathAbs         Where to store the resolved absolute path on success.
     342 *                              Needs to be free'd with RTStrFree().
     343 */
     344static int pathResolve(PHTTPSERVERDATA pThis, const char *pszUrl, char **ppszPathAbs)
     345{
    396346    /* Construct absolute path. */
    397347    char *pszPathAbs = NULL;
     
    399349        return VERR_NO_MEMORY;
    400350
    401     int rc = RTFileOpen(&pThis->h.File, pszPathAbs,
    402                         RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    403     if (RT_SUCCESS(rc))
    404         *pidObj = 42;
    405 
    406     RTStrFree(pszPathAbs);
    407     return rc;
    408 }
    409 
    410 DECLCALLBACK(int) onRead(PRTHTTPCALLBACKDATA pData, uint64_t idObj, void *pvBuf, size_t cbBuf, size_t *pcbRead)
     351#ifdef VBOX_STRICT
     352    RTFSOBJINFO objInfo;
     353    int rc2 = RTPathQueryInfo(pszPathAbs, &objInfo, RTFSOBJATTRADD_NOTHING);
     354    AssertRCReturn(rc, rc);
     355    AssertReturn(!RTFS_IS_SYMLINK(objInfo.Attr.fMode), VERR_NOT_SUPPORTED);
     356#endif
     357
     358    *ppszPathAbs = pszPathAbs;
     359
     360    return VINF_SUCCESS;
     361}
     362
     363DECLCALLBACK(int) onOpen(PRTHTTPCALLBACKDATA pData, const char *pszUrl, void **ppvHandle)
    411364{
    412365    PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
    413366    Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
    414367
    415     AssertReturn(idObj == 42, VERR_NOT_FOUND);
    416 
    417     return RTFileRead(pThis->h.File, pvBuf, cbBuf, pcbRead);
    418 }
    419 
    420 DECLCALLBACK(int) onClose(PRTHTTPCALLBACKDATA pData, uint64_t idObj)
     368    char *pszPathAbs = NULL;
     369    int rc = pathResolve(pThis, pszUrl, &pszPathAbs);
     370    if (RT_SUCCESS(rc))
     371    {
     372        RTFSOBJINFO objInfo;
     373        rc = RTPathQueryInfo(pszPathAbs, &objInfo, RTFSOBJATTRADD_NOTHING);
     374        AssertRCReturn(rc, rc);
     375        if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
     376        {
     377            /* Nothing to do here;
     378             * The directory listing has been cached already in onQueryInfo(). */
     379        }
     380        else if (RTFS_IS_FILE(objInfo.Attr.fMode))
     381        {
     382            rc = RTFileOpen(&pThis->h.File, pszPathAbs,
     383                            RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     384        }
     385
     386        if (RT_SUCCESS(rc))
     387        {
     388            pThis->fMode = objInfo.Attr.fMode;
     389
     390             uint64_t *puHandle = (uint64_t *)RTMemAlloc(sizeof(uint64_t));
     391             *puHandle  = 42; /** @todo Fudge. */
     392             *ppvHandle = puHandle;
     393        }
     394
     395        RTStrFree(pszPathAbs);
     396    }
     397    return rc;
     398}
     399
     400DECLCALLBACK(int) onRead(PRTHTTPCALLBACKDATA pData, void *pvHandle, void *pvBuf, size_t cbBuf, size_t *pcbRead)
    421401{
    422402    PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
    423403    Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
    424404
    425     AssertReturn(idObj == 42, VERR_NOT_FOUND);
    426 
    427     int rc = RTFileClose(pThis->h.File);
    428     if (RT_SUCCESS(rc))
    429         pThis->h.File = NIL_RTFILE;
    430 
    431     return rc;
    432 }
    433 
    434 DECLCALLBACK(int) onQueryInfo(PRTHTTPCALLBACKDATA pData, const char *pszUrl, PRTFSOBJINFO pObjInfo)
     405    AssertReturn(*(uint64_t *)pvHandle == 42 /** @todo Fudge. */, VERR_NOT_FOUND);
     406
     407    if (RTFS_IS_DIRECTORY(pThis->fMode))
     408    {
     409        PRTHTTPSERVERRESP pResp = &pThis->Resp;
     410
     411        const size_t cbToCopy = RT_MIN(cbBuf, pResp->cbBodyUsed);
     412        memcpy(pvBuf, pResp->pvBody, cbToCopy);
     413        Assert(pResp->cbBodyUsed >= cbToCopy);
     414        pResp->cbBodyUsed -= cbToCopy;
     415
     416        *pcbRead = cbToCopy;
     417
     418        return VINF_SUCCESS;
     419    }
     420    else if (RTFS_IS_FILE(pThis->fMode))
     421        return RTFileRead(pThis->h.File, pvBuf, cbBuf, pcbRead);
     422
     423    return VERR_NOT_IMPLEMENTED; /* Never reached. */
     424}
     425
     426DECLCALLBACK(int) onClose(PRTHTTPCALLBACKDATA pData, void *pvHandle)
    435427{
    436428    PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
    437429    Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
    438430
    439     /* Construct absolute path. */
     431    AssertReturn(*(uint64_t *)pvHandle == 42 /** @todo Fudge. */, VERR_NOT_FOUND);
     432
     433    int rc;
     434
     435    if (RTFS_IS_FILE(pThis->fMode))
     436    {
     437        rc = RTFileClose(pThis->h.File);
     438        if (RT_SUCCESS(rc))
     439            pThis->h.File = NIL_RTFILE;
     440    }
     441    else
     442        rc = VINF_SUCCESS;
     443
     444    RTMemFree(pvHandle);
     445    pvHandle = NULL;
     446
     447    return rc;
     448}
     449
     450DECLCALLBACK(int) onQueryInfo(PRTHTTPCALLBACKDATA pData,
     451                              const char *pszUrl, PRTFSOBJINFO pObjInfo, char **ppszMIMEHint)
     452{
     453    PHTTPSERVERDATA pThis = (PHTTPSERVERDATA)pData->pvUser;
     454    Assert(pData->cbUser == sizeof(HTTPSERVERDATA));
     455
    440456    char *pszPathAbs = NULL;
    441     if (RTStrAPrintf(&pszPathAbs, "%s/%s", pThis->szPathRootAbs, pszUrl) <= 0)
    442         return VERR_NO_MEMORY;
    443 
    444     RTFILE hFile;
    445     int rc = RTFileOpen(&hFile, pszPathAbs,
    446                         RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     457    int rc = pathResolve(pThis, pszUrl, &pszPathAbs);
    447458    if (RT_SUCCESS(rc))
    448459    {
    449         rc = RTFileQueryInfo(hFile, pObjInfo, RTFSOBJATTRADD_NOTHING);
    450 
    451         RTFileClose(hFile);
     460        RTFSOBJINFO objInfo;
     461        rc = RTPathQueryInfo(pszPathAbs, &objInfo, RTFSOBJATTRADD_NOTHING);
     462        if (RT_SUCCESS(rc))
     463        {
     464            if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
     465            {
     466                PRTHTTPSERVERRESP pResp = &pThis->Resp;
     467
     468                RTVFSDIR hVfsDir;
     469                rc = dirOpen(pszPathAbs, &hVfsDir);
     470                if (RT_SUCCESS(rc))
     471                {
     472                    RTHttpServerResponseDestroy(pResp);
     473                    RTHttpServerResponseInitEx(pResp, _4K);
     474
     475                    /*
     476                     * Write body header.
     477                     */
     478                    ssize_t cch = RTStrPrintf2((char *)pResp->pvBody, pResp->cbBodyAlloc,
     479                                               "300: file://%s\r\n"
     480                                               "200: filename content-length last-modified file-type\r\n",
     481                                               pszUrl);
     482                    Assert(cch);
     483
     484                    pResp->cbBodyUsed = strlen((char *)pResp->pvBody);
     485
     486                    /*
     487                     * Write body entries.
     488                     */
     489                    char       *pszEntry = NULL;
     490                    RTFSOBJINFO fsObjInfo;
     491                    while (RT_SUCCESS(rc = dirRead(hVfsDir, &pszEntry, &fsObjInfo)))
     492                    {
     493                        char *pszBody = (char *)pResp->pvBody;
     494
     495                        size_t cbWritten;
     496                        rc = dirEntryWrite(&pszBody[pResp->cbBodyUsed], pResp->cbBodyAlloc - pResp->cbBodyUsed, pszEntry, &fsObjInfo, &cbWritten);
     497                        if (rc == VERR_BUFFER_OVERFLOW)
     498                        {
     499                            pResp->cbBodyAlloc *= 2; /** @todo Improve this. */
     500                            pResp->pvBody       = RTMemRealloc(pResp->pvBody, pResp->cbBodyAlloc);
     501                            AssertPtrBreakStmt(pResp->pvBody, rc = VERR_NO_MEMORY);
     502
     503                            pszBody = (char *)pResp->pvBody;
     504
     505                            rc = dirEntryWrite(&pszBody[pResp->cbBodyUsed], pResp->cbBodyAlloc - pResp->cbBodyUsed, pszEntry, &fsObjInfo, &cbWritten);
     506                        }
     507
     508                        if (RT_SUCCESS(rc))
     509                            pResp->cbBodyUsed += cbWritten;
     510
     511                        RTStrFree(pszEntry);
     512
     513                        if (RT_FAILURE(rc))
     514                            break;
     515                    }
     516
     517                    if (rc == VERR_NO_MORE_FILES) /* All entries consumed? */
     518                        rc = VINF_SUCCESS;
     519
     520                    dirClose(hVfsDir);
     521
     522                    if (RT_SUCCESS(rc))
     523                    {
     524                        rc = RTStrAPrintf(ppszMIMEHint, "text/plain");
     525                        if (RT_SUCCESS(rc))
     526                            pObjInfo->cbObject = pResp->cbBodyUsed;
     527                    }
     528                }
     529            }
     530            else if (RTFS_IS_FILE(objInfo.Attr.fMode))
     531            {
     532                RTFILE hFile;
     533                rc = RTFileOpen(&hFile, pszPathAbs,
     534                                RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     535                if (RT_SUCCESS(rc))
     536                {
     537                    rc = RTFileQueryInfo(hFile, pObjInfo, RTFSOBJATTRADD_NOTHING);
     538
     539                    RTFileClose(hFile);
     540                }
     541            }
     542        }
     543
     544        RTStrFree(pszPathAbs);
    452545    }
    453546
     
    542635    }
    543636
    544     /* Initialize CWD. */
    545     RTStrPrintf2(g_HttpServerData.szCWD, sizeof(g_HttpServerData.szCWD), "/");
    546 
    547637    /* Install signal handler. */
    548638    rc = signalHandlerInstall();
     
    559649        Callbacks.pfnClose         = onClose;
    560650        Callbacks.pfnQueryInfo     = onQueryInfo;
    561         Callbacks.pfnOnGetRequest  = onGetRequest;
    562         Callbacks.pfnOnHeadRequest = onHeadRequest;
    563651
    564652        g_HttpServerData.h.File = NIL_RTFILE;
    565         g_HttpServerData.h.Dir  = NIL_RTDIR;
     653        g_HttpServerData.h.Dir  = NIL_RTVFSDIR;
     654
     655        rc = RTHttpServerResponseInit(&g_HttpServerData.Resp);
     656        AssertRC(rc);
    566657
    567658        RTHTTPSERVER hHTTPServer;
Note: See TracChangeset for help on using the changeset viewer.

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