Home | History | Annotate | Download | only in network
      1 /*
      2  * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
      3  * Copyright (C) 2009 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 #include "config.h"
     27 #include "ResourceRequestBase.h"
     28 #include "ResourceRequest.h"
     29 
     30 using namespace std;
     31 
     32 namespace WebCore {
     33 
     34 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
     35 {
     36     return *static_cast<const ResourceRequest*>(this);
     37 }
     38 
     39 auto_ptr<ResourceRequest> ResourceRequestBase::adopt(auto_ptr<CrossThreadResourceRequestData> data)
     40 {
     41     auto_ptr<ResourceRequest> request(new ResourceRequest());
     42     request->setURL(data->m_url);
     43     request->setCachePolicy(data->m_cachePolicy);
     44     request->setTimeoutInterval(data->m_timeoutInterval);
     45     request->setFirstPartyForCookies(data->m_firstPartyForCookies);
     46     request->setHTTPMethod(data->m_httpMethod);
     47 
     48     request->updateResourceRequest();
     49     request->m_httpHeaderFields.adopt(auto_ptr<CrossThreadHTTPHeaderMapData>(data->m_httpHeaders.release()));
     50 
     51     size_t encodingCount = data->m_responseContentDispositionEncodingFallbackArray.size();
     52     if (encodingCount > 0) {
     53         String encoding1 = data->m_responseContentDispositionEncodingFallbackArray[0];
     54         String encoding2;
     55         String encoding3;
     56         if (encodingCount > 1) {
     57             encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
     58             if (encodingCount > 2)
     59                 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
     60         }
     61         ASSERT(encodingCount <= 3);
     62         request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
     63     }
     64     request->setHTTPBody(data->m_httpBody);
     65     request->setAllowCookies(data->m_allowCookies);
     66     return request;
     67 }
     68 
     69 auto_ptr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
     70 {
     71     auto_ptr<CrossThreadResourceRequestData> data(new CrossThreadResourceRequestData());
     72     data->m_url = url().copy();
     73     data->m_cachePolicy = cachePolicy();
     74     data->m_timeoutInterval = timeoutInterval();
     75     data->m_firstPartyForCookies = firstPartyForCookies().copy();
     76     data->m_httpMethod = httpMethod().crossThreadString();
     77     data->m_httpHeaders.adopt(httpHeaderFields().copyData());
     78 
     79     data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
     80     size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
     81     for (size_t index = 0; index < encodingArraySize; ++index) {
     82         data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].crossThreadString());
     83     }
     84     if (m_httpBody)
     85         data->m_httpBody = m_httpBody->deepCopy();
     86     data->m_allowCookies = m_allowCookies;
     87     return data;
     88 }
     89 
     90 bool ResourceRequestBase::isEmpty() const
     91 {
     92     updateResourceRequest();
     93 
     94     return m_url.isEmpty();
     95 }
     96 
     97 bool ResourceRequestBase::isNull() const
     98 {
     99     updateResourceRequest();
    100 
    101     return m_url.isNull();
    102 }
    103 
    104 const KURL& ResourceRequestBase::url() const
    105 {
    106     updateResourceRequest();
    107 
    108     return m_url;
    109 }
    110 
    111 void ResourceRequestBase::setURL(const KURL& url)
    112 {
    113     updateResourceRequest();
    114 
    115     m_url = url;
    116 
    117     m_platformRequestUpdated = false;
    118 }
    119 
    120 void ResourceRequestBase::removeCredentials()
    121 {
    122     updateResourceRequest();
    123 
    124     m_url.setUser(String());
    125     m_url.setPass(String());
    126 
    127     m_platformRequestUpdated = false;
    128 }
    129 
    130 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
    131 {
    132     updateResourceRequest();
    133 
    134     return m_cachePolicy;
    135 }
    136 
    137 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
    138 {
    139     updateResourceRequest();
    140 
    141     m_cachePolicy = cachePolicy;
    142 
    143     if (url().protocolInHTTPFamily())
    144         m_platformRequestUpdated = false;
    145 }
    146 
    147 double ResourceRequestBase::timeoutInterval() const
    148 {
    149     updateResourceRequest();
    150 
    151     return m_timeoutInterval;
    152 }
    153 
    154 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
    155 {
    156     updateResourceRequest();
    157 
    158     m_timeoutInterval = timeoutInterval;
    159 
    160     if (url().protocolInHTTPFamily())
    161         m_platformRequestUpdated = false;
    162 }
    163 
    164 const KURL& ResourceRequestBase::firstPartyForCookies() const
    165 {
    166     updateResourceRequest();
    167 
    168     return m_firstPartyForCookies;
    169 }
    170 
    171 void ResourceRequestBase::setFirstPartyForCookies(const KURL& firstPartyForCookies)
    172 {
    173     updateResourceRequest();
    174 
    175     m_firstPartyForCookies = firstPartyForCookies;
    176 
    177     m_platformRequestUpdated = false;
    178 }
    179 
    180 const String& ResourceRequestBase::httpMethod() const
    181 {
    182     updateResourceRequest();
    183 
    184     return m_httpMethod;
    185 }
    186 
    187 void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
    188 {
    189     updateResourceRequest();
    190 
    191     m_httpMethod = httpMethod;
    192 
    193     if (url().protocolInHTTPFamily())
    194         m_platformRequestUpdated = false;
    195 }
    196 
    197 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
    198 {
    199     updateResourceRequest();
    200 
    201     return m_httpHeaderFields;
    202 }
    203 
    204 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
    205 {
    206     updateResourceRequest();
    207 
    208     return m_httpHeaderFields.get(name);
    209 }
    210 
    211 String ResourceRequestBase::httpHeaderField(const char* name) const
    212 {
    213     updateResourceRequest();
    214 
    215     return m_httpHeaderFields.get(name);
    216 }
    217 
    218 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
    219 {
    220     updateResourceRequest();
    221 
    222     m_httpHeaderFields.set(name, value);
    223 
    224     if (url().protocolInHTTPFamily())
    225         m_platformRequestUpdated = false;
    226 }
    227 
    228 void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
    229 {
    230     setHTTPHeaderField(AtomicString(name), value);
    231 }
    232 
    233 void ResourceRequestBase::clearHTTPReferrer()
    234 {
    235     updateResourceRequest();
    236 
    237     m_httpHeaderFields.remove("Referer");
    238 
    239     if (url().protocolInHTTPFamily())
    240         m_platformRequestUpdated = false;
    241 }
    242 
    243 void ResourceRequestBase::clearHTTPOrigin()
    244 {
    245     updateResourceRequest();
    246 
    247     m_httpHeaderFields.remove("Origin");
    248 
    249     if (url().protocolInHTTPFamily())
    250         m_platformRequestUpdated = false;
    251 }
    252 
    253 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
    254 {
    255     updateResourceRequest();
    256 
    257     m_responseContentDispositionEncodingFallbackArray.clear();
    258     if (!encoding1.isNull())
    259         m_responseContentDispositionEncodingFallbackArray.append(encoding1);
    260     if (!encoding2.isNull())
    261         m_responseContentDispositionEncodingFallbackArray.append(encoding2);
    262     if (!encoding3.isNull())
    263         m_responseContentDispositionEncodingFallbackArray.append(encoding3);
    264 
    265     if (url().protocolInHTTPFamily())
    266         m_platformRequestUpdated = false;
    267 }
    268 
    269 FormData* ResourceRequestBase::httpBody() const
    270 {
    271     updateResourceRequest();
    272 
    273     return m_httpBody.get();
    274 }
    275 
    276 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
    277 {
    278     updateResourceRequest();
    279 
    280     m_httpBody = httpBody;
    281 
    282     if (url().protocolInHTTPFamily())
    283         m_platformRequestUpdated = false;
    284 }
    285 
    286 bool ResourceRequestBase::allowCookies() const
    287 {
    288     updateResourceRequest();
    289 
    290     return m_allowCookies;
    291 }
    292 
    293 void ResourceRequestBase::setAllowCookies(bool allowCookies)
    294 {
    295     updateResourceRequest();
    296 
    297     m_allowCookies = allowCookies;
    298 
    299     if (url().protocolInHTTPFamily())
    300         m_platformRequestUpdated = false;
    301 }
    302 
    303 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value)
    304 {
    305     updateResourceRequest();
    306     pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);
    307     if (!result.second)
    308         result.first->second += "," + value;
    309 
    310     if (url().protocolInHTTPFamily())
    311         m_platformRequestUpdated = false;
    312 }
    313 
    314 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
    315 {
    316     HTTPHeaderMap::const_iterator end = headerFields.end();
    317     for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
    318         addHTTPHeaderField(it->first, it->second);
    319 }
    320 
    321 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
    322 {
    323     if (a.url() != b.url())
    324         return false;
    325 
    326     if (a.cachePolicy() != b.cachePolicy())
    327         return false;
    328 
    329     if (a.timeoutInterval() != b.timeoutInterval())
    330         return false;
    331 
    332     if (a.firstPartyForCookies() != b.firstPartyForCookies())
    333         return false;
    334 
    335     if (a.httpMethod() != b.httpMethod())
    336         return false;
    337 
    338     if (a.allowCookies() != b.allowCookies())
    339         return false;
    340 
    341     FormData* formDataA = a.httpBody();
    342     FormData* formDataB = b.httpBody();
    343 
    344     if (!formDataA)
    345         return !formDataB;
    346     if (!formDataB)
    347         return !formDataA;
    348 
    349     if (*formDataA != *formDataB)
    350         return false;
    351 
    352     return true;
    353 }
    354 
    355 bool operator==(const ResourceRequestBase& a, const ResourceRequestBase& b)
    356 {
    357     if (!equalIgnoringHeaderFields(a, b))
    358         return false;
    359 
    360     if (a.httpHeaderFields() != b.httpHeaderFields())
    361         return false;
    362 
    363     return true;
    364 }
    365 
    366 bool ResourceRequestBase::isConditional() const
    367 {
    368     return (m_httpHeaderFields.contains("If-Match") ||
    369             m_httpHeaderFields.contains("If-Modified-Since") ||
    370             m_httpHeaderFields.contains("If-None-Match") ||
    371             m_httpHeaderFields.contains("If-Range") ||
    372             m_httpHeaderFields.contains("If-Unmodified-Since"));
    373 }
    374 
    375 void ResourceRequestBase::updatePlatformRequest() const
    376 {
    377     if (m_platformRequestUpdated)
    378         return;
    379 
    380     const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
    381     m_platformRequestUpdated = true;
    382 }
    383 
    384 void ResourceRequestBase::updateResourceRequest() const
    385 {
    386     if (m_resourceRequestUpdated)
    387         return;
    388 
    389     const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
    390     m_resourceRequestUpdated = true;
    391 }
    392 
    393 #if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(ANDROID) && !PLATFORM(QT)
    394 unsigned initializeMaximumHTTPConnectionCountPerHost()
    395 {
    396     // This is used by the loader to control the number of issued parallel load requests.
    397     // Four seems to be a common default in HTTP frameworks.
    398     return 4;
    399 }
    400 #endif
    401 
    402 }
    403