Home | History | Annotate | Download | only in network
      1 /*
      2  * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
      3  * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "platform/network/ResourceRequest.h"
     29 
     30 namespace WebCore {
     31 
     32 double ResourceRequest::s_defaultTimeoutInterval = INT_MAX;
     33 
     34 PassOwnPtr<ResourceRequest> ResourceRequest::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
     35 {
     36     OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest());
     37     request->setURL(data->m_url);
     38     request->setCachePolicy(data->m_cachePolicy);
     39     request->setTimeoutInterval(data->m_timeoutInterval);
     40     request->setFirstPartyForCookies(data->m_firstPartyForCookies);
     41     request->setHTTPMethod(AtomicString(data->m_httpMethod));
     42     request->setPriority(data->m_priority, data->m_intraPriorityValue);
     43 
     44     request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
     45 
     46     request->setHTTPBody(data->m_httpBody);
     47     request->setAllowStoredCredentials(data->m_allowStoredCredentials);
     48     request->setReportUploadProgress(data->m_reportUploadProgress);
     49     request->setHasUserGesture(data->m_hasUserGesture);
     50     request->setDownloadToFile(data->m_downloadToFile);
     51     request->setRequestorID(data->m_requestorID);
     52     request->setRequestorProcessID(data->m_requestorProcessID);
     53     request->setAppCacheHostID(data->m_appCacheHostID);
     54     request->setTargetType(data->m_targetType);
     55     request->m_referrerPolicy = data->m_referrerPolicy;
     56     return request.release();
     57 }
     58 
     59 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequest::copyData() const
     60 {
     61     OwnPtr<CrossThreadResourceRequestData> data = adoptPtr(new CrossThreadResourceRequestData());
     62     data->m_url = url().copy();
     63     data->m_cachePolicy = cachePolicy();
     64     data->m_timeoutInterval = timeoutInterval();
     65     data->m_firstPartyForCookies = firstPartyForCookies().copy();
     66     data->m_httpMethod = httpMethod().string().isolatedCopy();
     67     data->m_httpHeaders = httpHeaderFields().copyData();
     68     data->m_priority = priority();
     69     data->m_intraPriorityValue = m_intraPriorityValue;
     70 
     71     if (m_httpBody)
     72         data->m_httpBody = m_httpBody->deepCopy();
     73     data->m_allowStoredCredentials = m_allowStoredCredentials;
     74     data->m_reportUploadProgress = m_reportUploadProgress;
     75     data->m_hasUserGesture = m_hasUserGesture;
     76     data->m_downloadToFile = m_downloadToFile;
     77     data->m_requestorID = m_requestorID;
     78     data->m_requestorProcessID = m_requestorProcessID;
     79     data->m_appCacheHostID = m_appCacheHostID;
     80     data->m_targetType = m_targetType;
     81     data->m_referrerPolicy = m_referrerPolicy;
     82     return data.release();
     83 }
     84 
     85 bool ResourceRequest::isEmpty() const
     86 {
     87     return m_url.isEmpty();
     88 }
     89 
     90 bool ResourceRequest::isNull() const
     91 {
     92     return m_url.isNull();
     93 }
     94 
     95 const KURL& ResourceRequest::url() const
     96 {
     97     return m_url;
     98 }
     99 
    100 void ResourceRequest::setURL(const KURL& url)
    101 {
    102     m_url = url;
    103 }
    104 
    105 void ResourceRequest::removeCredentials()
    106 {
    107     if (m_url.user().isEmpty() && m_url.pass().isEmpty())
    108         return;
    109 
    110     m_url.setUser(String());
    111     m_url.setPass(String());
    112 }
    113 
    114 ResourceRequestCachePolicy ResourceRequest::cachePolicy() const
    115 {
    116     return m_cachePolicy;
    117 }
    118 
    119 void ResourceRequest::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
    120 {
    121     m_cachePolicy = cachePolicy;
    122 }
    123 
    124 double ResourceRequest::timeoutInterval() const
    125 {
    126     return m_timeoutInterval;
    127 }
    128 
    129 void ResourceRequest::setTimeoutInterval(double timeoutInterval)
    130 {
    131     m_timeoutInterval = timeoutInterval;
    132 }
    133 
    134 const KURL& ResourceRequest::firstPartyForCookies() const
    135 {
    136     return m_firstPartyForCookies;
    137 }
    138 
    139 void ResourceRequest::setFirstPartyForCookies(const KURL& firstPartyForCookies)
    140 {
    141     m_firstPartyForCookies = firstPartyForCookies;
    142 }
    143 
    144 const AtomicString& ResourceRequest::httpMethod() const
    145 {
    146     return m_httpMethod;
    147 }
    148 
    149 void ResourceRequest::setHTTPMethod(const AtomicString& httpMethod)
    150 {
    151     m_httpMethod = httpMethod;
    152 }
    153 
    154 const HTTPHeaderMap& ResourceRequest::httpHeaderFields() const
    155 {
    156     return m_httpHeaderFields;
    157 }
    158 
    159 const AtomicString& ResourceRequest::httpHeaderField(const AtomicString& name) const
    160 {
    161     return m_httpHeaderFields.get(name);
    162 }
    163 
    164 const AtomicString& ResourceRequest::httpHeaderField(const char* name) const
    165 {
    166     return m_httpHeaderFields.get(name);
    167 }
    168 
    169 void ResourceRequest::setHTTPHeaderField(const AtomicString& name, const AtomicString& value)
    170 {
    171     m_httpHeaderFields.set(name, value);
    172 }
    173 
    174 void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& value)
    175 {
    176     setHTTPHeaderField(AtomicString(name), value);
    177 }
    178 
    179 void ResourceRequest::clearHTTPAuthorization()
    180 {
    181     m_httpHeaderFields.remove("Authorization");
    182 }
    183 
    184 void ResourceRequest::clearHTTPReferrer()
    185 {
    186     m_httpHeaderFields.remove("Referer");
    187     m_referrerPolicy = ReferrerPolicyDefault;
    188 }
    189 
    190 void ResourceRequest::clearHTTPOrigin()
    191 {
    192     m_httpHeaderFields.remove("Origin");
    193 }
    194 
    195 void ResourceRequest::clearHTTPUserAgent()
    196 {
    197     m_httpHeaderFields.remove("User-Agent");
    198 }
    199 
    200 FormData* ResourceRequest::httpBody() const
    201 {
    202     return m_httpBody.get();
    203 }
    204 
    205 void ResourceRequest::setHTTPBody(PassRefPtr<FormData> httpBody)
    206 {
    207     m_httpBody = httpBody;
    208 }
    209 
    210 bool ResourceRequest::allowStoredCredentials() const
    211 {
    212     return m_allowStoredCredentials;
    213 }
    214 
    215 void ResourceRequest::setAllowStoredCredentials(bool allowCredentials)
    216 {
    217     m_allowStoredCredentials = allowCredentials;
    218 }
    219 
    220 ResourceLoadPriority ResourceRequest::priority() const
    221 {
    222     return m_priority;
    223 }
    224 
    225 void ResourceRequest::setPriority(ResourceLoadPriority priority, int intraPriorityValue)
    226 {
    227     m_priority = priority;
    228     m_intraPriorityValue = intraPriorityValue;
    229 }
    230 
    231 void ResourceRequest::addHTTPHeaderField(const AtomicString& name, const AtomicString& value)
    232 {
    233     HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value);
    234     if (!result.isNewEntry)
    235         result.storedValue->value = result.storedValue->value + ',' + value;
    236 }
    237 
    238 void ResourceRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
    239 {
    240     HTTPHeaderMap::const_iterator end = headerFields.end();
    241     for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
    242         addHTTPHeaderField(it->key, it->value);
    243 }
    244 
    245 void ResourceRequest::clearHTTPHeaderField(const AtomicString& name)
    246 {
    247     m_httpHeaderFields.remove(name);
    248 }
    249 
    250 bool equalIgnoringHeaderFields(const ResourceRequest& a, const ResourceRequest& b)
    251 {
    252     if (a.url() != b.url())
    253         return false;
    254 
    255     if (a.cachePolicy() != b.cachePolicy())
    256         return false;
    257 
    258     if (a.timeoutInterval() != b.timeoutInterval())
    259         return false;
    260 
    261     if (a.firstPartyForCookies() != b.firstPartyForCookies())
    262         return false;
    263 
    264     if (a.httpMethod() != b.httpMethod())
    265         return false;
    266 
    267     if (a.allowStoredCredentials() != b.allowStoredCredentials())
    268         return false;
    269 
    270     if (a.priority() != b.priority())
    271         return false;
    272 
    273     if (a.referrerPolicy() != b.referrerPolicy())
    274         return false;
    275 
    276     FormData* formDataA = a.httpBody();
    277     FormData* formDataB = b.httpBody();
    278 
    279     if (!formDataA)
    280         return !formDataB;
    281     if (!formDataB)
    282         return !formDataA;
    283 
    284     if (*formDataA != *formDataB)
    285         return false;
    286 
    287     return true;
    288 }
    289 
    290 bool ResourceRequest::compare(const ResourceRequest& a, const ResourceRequest& b)
    291 {
    292     if (!equalIgnoringHeaderFields(a, b))
    293         return false;
    294 
    295     if (a.httpHeaderFields() != b.httpHeaderFields())
    296         return false;
    297 
    298     return true;
    299 }
    300 
    301 bool ResourceRequest::isConditional() const
    302 {
    303     return (m_httpHeaderFields.contains("If-Match")
    304         || m_httpHeaderFields.contains("If-Modified-Since")
    305         || m_httpHeaderFields.contains("If-None-Match")
    306         || m_httpHeaderFields.contains("If-Range")
    307         || m_httpHeaderFields.contains("If-Unmodified-Since"));
    308 }
    309 
    310 
    311 static const AtomicString& cacheControlHeaderString()
    312 {
    313     DEFINE_STATIC_LOCAL(const AtomicString, cacheControlHeader, ("cache-control", AtomicString::ConstructFromLiteral));
    314     return cacheControlHeader;
    315 }
    316 
    317 static const AtomicString& pragmaHeaderString()
    318 {
    319     DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma", AtomicString::ConstructFromLiteral));
    320     return pragmaHeader;
    321 }
    322 
    323 bool ResourceRequest::cacheControlContainsNoCache()
    324 {
    325     if (!m_cacheControlHeader.parsed)
    326         m_cacheControlHeader = parseCacheControlDirectives(m_httpHeaderFields.get(cacheControlHeaderString()), m_httpHeaderFields.get(pragmaHeaderString()));
    327     return m_cacheControlHeader.containsNoCache;
    328 }
    329 
    330 bool ResourceRequest::cacheControlContainsNoStore()
    331 {
    332     if (!m_cacheControlHeader.parsed)
    333         m_cacheControlHeader = parseCacheControlDirectives(m_httpHeaderFields.get(cacheControlHeaderString()), m_httpHeaderFields.get(pragmaHeaderString()));
    334     return m_cacheControlHeader.containsNoStore;
    335 }
    336 
    337 bool ResourceRequest::hasCacheValidatorFields()
    338 {
    339     DEFINE_STATIC_LOCAL(const AtomicString, lastModifiedHeader, ("last-modified", AtomicString::ConstructFromLiteral));
    340     DEFINE_STATIC_LOCAL(const AtomicString, eTagHeader, ("etag", AtomicString::ConstructFromLiteral));
    341     return !m_httpHeaderFields.get(lastModifiedHeader).isEmpty() || !m_httpHeaderFields.get(eTagHeader).isEmpty();
    342 }
    343 
    344 double ResourceRequest::defaultTimeoutInterval()
    345 {
    346     return s_defaultTimeoutInterval;
    347 }
    348 
    349 void ResourceRequest::setDefaultTimeoutInterval(double timeoutInterval)
    350 {
    351     s_defaultTimeoutInterval = timeoutInterval;
    352 }
    353 
    354 void ResourceRequest::initialize(const KURL& url, ResourceRequestCachePolicy cachePolicy)
    355 {
    356     m_url = url;
    357     m_cachePolicy = cachePolicy;
    358     m_timeoutInterval = s_defaultTimeoutInterval;
    359     m_httpMethod = "GET";
    360     m_allowStoredCredentials = true;
    361     m_reportUploadProgress = false;
    362     m_reportRawHeaders = false;
    363     m_hasUserGesture = false;
    364     m_downloadToFile = false;
    365     m_priority = ResourceLoadPriorityLow;
    366     m_intraPriorityValue = 0;
    367     m_requestorID = 0;
    368     m_requestorProcessID = 0;
    369     m_appCacheHostID = 0;
    370     m_targetType = TargetIsUnspecified;
    371     m_referrerPolicy = ReferrerPolicyDefault;
    372 }
    373 
    374 // This is used by the loader to control the number of issued parallel load requests.
    375 unsigned initializeMaximumHTTPConnectionCountPerHost()
    376 {
    377     // The chromium network stack already handles limiting the number of
    378     // parallel requests per host, so there's no need to do it here.  Therefore,
    379     // this is set to a high value that should never be hit in practice.
    380     return 10000;
    381 }
    382 
    383 }
    384