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