VirtualBox

Changeset 73888 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 25, 2018 1:26:05 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124605
Message:

IPRT/http: Added a couple functions for adding headers. Issues with resetting headers and out-of-memory in the existing function. bugref:9167

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/http-curl.cpp

    r73886 r73888  
    329329
    330330    if (pThis->pHeaders)
     331    {
    331332        curl_slist_free_all(pThis->pHeaders);
     333        pThis->pHeaders = NULL;
     334    }
    332335
    333336    rtHttpUnsetCaFile(pThis);
     
    335338
    336339    if (pThis->pszRedirLocation)
     340    {
    337341        RTStrFree(pThis->pszRedirLocation);
     342        pThis->pszRedirLocation = NULL;
     343    }
    338344
    339345    RTStrFree(pThis->pszProxyHost);
     346    pThis->pszProxyHost = NULL;
    340347    RTStrFree(pThis->pszProxyUsername);
     348    pThis->pszProxyUsername = NULL;
    341349    if (pThis->pszProxyPassword)
    342350    {
    343351        RTMemWipeThoroughly(pThis->pszProxyPassword, strlen(pThis->pszProxyPassword), 2);
    344352        RTStrFree(pThis->pszProxyPassword);
     353        pThis->pszProxyPassword = NULL;
    345354    }
    346355
     
    18771886
    18781887
     1888/**
     1889 * Helper for RTHttpSetHeaders and RTHttpAppendHeader that unsets the user agent
     1890 * if it is now in one of the headers.
     1891 */
     1892static void rtHttpUpdateUserAgentHeader(PRTHTTPINTERNAL pThis)
     1893{
     1894    if (   pThis->fHaveUserAgentHeader
     1895        && pThis->fHaveSetUserAgent)
     1896    {
     1897        int rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_USERAGENT, (char *)NULL);
     1898        Assert(CURL_SUCCESS(rcCurl)); NOREF(rcCurl);
     1899        pThis->fHaveSetUserAgent = false;
     1900    }
     1901}
     1902
     1903
    18791904RTR3DECL(int) RTHttpSetHeaders(RTHTTP hHttp, size_t cHeaders, const char * const *papszHeaders)
    18801905{
     
    18821907    RTHTTP_VALID_RETURN(pThis);
    18831908
     1909    /*
     1910     * Drop old headers and reset state.
     1911     */
     1912    if (pThis->pHeaders)
     1913    {
     1914        curl_slist_free_all(pThis->pHeaders);
     1915        pThis->pHeaders = NULL;
     1916        curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPHEADER, pThis->pHeaders);
     1917    }
    18841918    pThis->fHaveUserAgentHeader = false;
     1919
     1920    /*
     1921     * We're done if no headers specified.
     1922     */
    18851923    if (!cHeaders)
    1886     {
    1887         if (pThis->pHeaders)
    1888             curl_slist_free_all(pThis->pHeaders);
    1889         pThis->pHeaders = 0;
    18901924        return VINF_SUCCESS;
    1891     }
    1892 
     1925
     1926    /*
     1927     * Convert the headers into a curl string list, checkig each string for User-Agent.
     1928     */
    18931929    struct curl_slist *pHeaders = NULL;
    18941930    for (size_t i = 0; i < cHeaders; i++)
    18951931    {
    1896         pHeaders = curl_slist_append(pHeaders, papszHeaders[i]);
     1932        struct curl_slist *pNewHeaders = curl_slist_append(pHeaders, papszHeaders[i]);
     1933        if (pNewHeaders)
     1934            pHeaders = pNewHeaders;
     1935        else
     1936        {
     1937            if (pHeaders)
     1938                curl_slist_free_all(pHeaders);
     1939            return VERR_NO_MEMORY;
     1940        }
     1941
    18971942        if (strncmp(papszHeaders[i], RT_STR_TUPLE("User-Agent:")) == 0)
    18981943            pThis->fHaveUserAgentHeader = true;
    18991944    }
    19001945
    1901     pThis->pHeaders = pHeaders;
    19021946    int rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPHEADER, pHeaders);
    19031947    if (CURL_FAILURE(rcCurl))
     1948    {
     1949        curl_slist_free_all(pHeaders);
    19041950        return VERR_INVALID_PARAMETER;
    1905 
    1906     /*
    1907      * Unset the user agent if it's in one of the headers.
    1908      */
    1909     if (   pThis->fHaveUserAgentHeader
    1910         && pThis->fHaveSetUserAgent)
    1911     {
    1912         rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_USERAGENT, (char *)NULL);
    1913         Assert(CURL_SUCCESS(rcCurl));
    1914         pThis->fHaveSetUserAgent = false;
    1915     }
     1951    }
     1952    pThis->pHeaders = pHeaders;
     1953
     1954    rtHttpUpdateUserAgentHeader(pThis);
    19161955
    19171956    return VINF_SUCCESS;
     1957}
     1958
     1959
     1960RTR3DECL(int) RTHttpAppendRawHeader(RTHTTP hHttp, const char *pszHeader)
     1961{
     1962    PRTHTTPINTERNAL pThis = hHttp;
     1963    RTHTTP_VALID_RETURN(pThis);
     1964
     1965    /*
     1966     * Append it to the header list, checking for User-Agent and such.
     1967     */
     1968    struct curl_slist *pHeaders = pThis->pHeaders;
     1969    struct curl_slist *pNewHeaders = curl_slist_append(pHeaders, pszHeader);
     1970    if (pNewHeaders)
     1971        pHeaders = pNewHeaders;
     1972    else
     1973        return VERR_NO_MEMORY;
     1974
     1975    if (strncmp(pszHeader, RT_STR_TUPLE("User-Agent:")) == 0)
     1976        pThis->fHaveUserAgentHeader = true;
     1977
     1978    /*
     1979     * If this is the first header, we need to tell curl.
     1980     */
     1981    if (!pThis->pHeaders)
     1982    {
     1983        int rcCurl = curl_easy_setopt(pThis->pCurl, CURLOPT_HTTPHEADER, pHeaders);
     1984        if (CURL_FAILURE(rcCurl))
     1985        {
     1986            curl_slist_free_all(pHeaders);
     1987            return VERR_INVALID_PARAMETER;
     1988        }
     1989        pThis->pHeaders = pHeaders;
     1990    }
     1991    else
     1992        Assert(pThis->pHeaders == pHeaders);
     1993
     1994    rtHttpUpdateUserAgentHeader(pThis);
     1995
     1996    return VINF_SUCCESS;
     1997}
     1998
     1999
     2000RTR3DECL(int) RTHttpAppendHeader(RTHTTP hHttp, const char *pszField, const char *pszValue, uint32_t fFlags)
     2001{
     2002
     2003    /*
     2004     * Currently we don't any encoding here, so we just glue the two strings together.
     2005     */
     2006    AssertPtr(pszField);
     2007    size_t const cchField = strlen(pszField);
     2008    AssertReturn(cchField > 0, VERR_INVALID_PARAMETER);
     2009    AssertReturn(pszField[cchField - 1] != ':', VERR_INVALID_PARAMETER);
     2010    AssertReturn(!RT_C_IS_SPACE(pszField[cchField - 1]), VERR_INVALID_PARAMETER);
     2011#ifdef RT_STRICT
     2012    for (size_t i = 0; i < cchField; i++)
     2013    {
     2014        char const ch = pszField[i];
     2015        Assert(RT_C_IS_PRINT(ch) && ch != ':');
     2016    }
     2017#endif
     2018
     2019    AssertPtr(pszValue);
     2020    size_t const cchValue = strlen(pszValue);
     2021
     2022    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
     2023
     2024    /*
     2025     * Allocate a temporary buffer, construct the raw header string in it,
     2026     * then use RTHttpAppendRawHeader to do the grunt work.
     2027     */
     2028    size_t const cbNeeded = cchField + 2 + cchValue + 1;
     2029    char *pszHeaderFree = NULL;
     2030    char *pszHeader;
     2031    if (cbNeeded < _2K)
     2032        pszHeader = (char *)alloca(cbNeeded);
     2033    else
     2034        pszHeaderFree = pszHeader = (char *)RTMemTmpAlloc(cbNeeded);
     2035    if (!pszHeader)
     2036        return VERR_NO_TMP_MEMORY;
     2037
     2038    memcpy(pszHeader, pszField, cchField);
     2039    pszHeader[cchField]     = ':';
     2040    pszHeader[cchField + 1] = ' ';
     2041    memcpy(&pszHeader[cchField + 2], pszValue, cchValue);
     2042    pszHeader[cbNeeded - 1] = '\0';
     2043
     2044    int rc = RTHttpAppendRawHeader(hHttp, pszHeader);
     2045
     2046    if (pszHeaderFree)
     2047        RTMemTmpFree(pszHeaderFree);
     2048    return rc;
    19182049}
    19192050
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