Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #import "config.h"
     27 #import "ResourceResponse.h"
     28 
     29 #if !USE(CFNETWORK)
     30 
     31 #import "HTTPParsers.h"
     32 #import "WebCoreURLResponse.h"
     33 #import "WebCoreSystemInterface.h"
     34 #import <Foundation/Foundation.h>
     35 #import <wtf/StdLibExtras.h>
     36 #import <limits>
     37 #include <wtf/text/CString.h>
     38 
     39 @interface NSURLResponse (FoundationSecretsWebCoreKnowsAbout)
     40 - (NSTimeInterval)_calculatedExpiration;
     41 @end
     42 
     43 #ifdef BUILDING_ON_TIGER
     44 typedef int NSInteger;
     45 #endif
     46 
     47 namespace WebCore {
     48 
     49 static NSString* const commonHeaderFields[] = {
     50     @"Age", @"Cache-Control", @"Date", @"Etag", @"Expires", @"Last-Modified", @"Pragma"
     51 };
     52 static const int numCommonHeaderFields = sizeof(commonHeaderFields) / sizeof(AtomicString*);
     53 
     54 NSURLResponse *ResourceResponse::nsURLResponse() const
     55 {
     56     if (!m_nsResponse && !m_isNull) {
     57         // Work around a mistake in the NSURLResponse class.
     58         // The init function takes an NSInteger, even though the accessor returns a long long.
     59         // For values that won't fit in an NSInteger, pass -1 instead.
     60         NSInteger expectedContentLength;
     61         if (m_expectedContentLength < 0 || m_expectedContentLength > std::numeric_limits<NSInteger>::max())
     62             expectedContentLength = -1;
     63         else
     64             expectedContentLength = static_cast<NSInteger>(m_expectedContentLength);
     65         const_cast<ResourceResponse*>(this)->m_nsResponse.adoptNS([[NSURLResponse alloc] initWithURL:m_url MIMEType:m_mimeType expectedContentLength:expectedContentLength textEncodingName:m_textEncodingName]);
     66     }
     67     return m_nsResponse.get();
     68 }
     69 
     70 void ResourceResponse::platformLazyInit(InitLevel initLevel)
     71 {
     72     if (m_initLevel >= initLevel)
     73         return;
     74 
     75     if (m_isNull) {
     76         ASSERT(!m_nsResponse);
     77         return;
     78     }
     79 
     80     if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) {
     81         NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     82 
     83         m_httpHeaderFields.clear();
     84         m_url = [m_nsResponse.get() URL];
     85         m_mimeType = [m_nsResponse.get() MIMEType];
     86         m_expectedContentLength = [m_nsResponse.get() expectedContentLength];
     87         m_textEncodingName = [m_nsResponse.get() textEncodingName];
     88 
     89         // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
     90         unsigned textEncodingNameLength = m_textEncodingName.length();
     91         if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
     92             m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);
     93 
     94         m_suggestedFilename = [m_nsResponse.get() suggestedFilename];
     95 
     96         if ([m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
     97             NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
     98 
     99             m_httpStatusCode = [httpResponse statusCode];
    100 
    101             NSDictionary *headers = [httpResponse allHeaderFields];
    102 
    103             for (int i = 0; i < numCommonHeaderFields; i++) {
    104                 if (NSString* headerValue = [headers objectForKey:commonHeaderFields[i]])
    105                     m_httpHeaderFields.set([commonHeaderFields[i] UTF8String], headerValue);
    106             }
    107         } else
    108             m_httpStatusCode = 0;
    109 
    110         [pool drain];
    111     }
    112 
    113     if (m_initLevel < AllFields && initLevel >= AllFields && [m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
    114         NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    115 
    116         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
    117 
    118         RetainPtr<NSString> httpStatusLine(AdoptNS, wkCopyNSURLResponseStatusLine(m_nsResponse.get()));
    119         if (httpStatusLine)
    120             m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(httpStatusLine.get());
    121         else
    122             m_httpStatusText = "OK";
    123 
    124         NSDictionary *headers = [httpResponse allHeaderFields];
    125         NSEnumerator *e = [headers keyEnumerator];
    126         while (NSString *name = [e nextObject])
    127             m_httpHeaderFields.set(name, [headers objectForKey:name]);
    128 
    129         [pool drain];
    130     }
    131 
    132     m_initLevel = initLevel;
    133 }
    134 
    135 
    136 bool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b)
    137 {
    138     return a.nsURLResponse() == b.nsURLResponse();
    139 }
    140 
    141 } // namespace WebCore
    142 
    143 #endif // !USE(CFNETWORK)
    144