Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #import "config.h"
     27 #import "WebCoreArgumentCoders.h"
     28 
     29 #import "ArgumentCodersCF.h"
     30 #import "PlatformCertificateInfo.h"
     31 #import "WebKitSystemInterface.h"
     32 
     33 using namespace WebCore;
     34 using namespace WebKit;
     35 
     36 namespace CoreIPC {
     37 
     38 void encodeResourceRequest(ArgumentEncoder* encoder, const ResourceRequest& resourceRequest)
     39 {
     40     bool requestIsPresent = resourceRequest.nsURLRequest();
     41     encoder->encode(requestIsPresent);
     42 
     43     if (!requestIsPresent)
     44         return;
     45 
     46     RetainPtr<CFDictionaryRef> dictionary(AdoptCF, WKNSURLRequestCreateSerializableRepresentation(resourceRequest.nsURLRequest(), CoreIPC::tokenNullTypeRef()));
     47     encode(encoder, dictionary.get());
     48 }
     49 
     50 bool decodeResourceRequest(ArgumentDecoder* decoder, ResourceRequest& resourceRequest)
     51 {
     52     bool requestIsPresent;
     53     if (!decoder->decode(requestIsPresent))
     54         return false;
     55 
     56     if (!requestIsPresent) {
     57         resourceRequest = ResourceRequest();
     58         return true;
     59     }
     60 
     61     RetainPtr<CFDictionaryRef> dictionary;
     62     if (!decode(decoder, dictionary))
     63         return false;
     64 
     65     NSURLRequest *nsURLRequest = WKNSURLRequestFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef());
     66     if (!nsURLRequest)
     67         return false;
     68 
     69     resourceRequest = ResourceRequest(nsURLRequest);
     70     return true;
     71 }
     72 
     73 void encodeResourceResponse(ArgumentEncoder* encoder, const ResourceResponse& resourceResponse)
     74 {
     75     bool responseIsPresent = resourceResponse.nsURLResponse();
     76     encoder->encode(responseIsPresent);
     77 
     78     if (!responseIsPresent)
     79         return;
     80 
     81     RetainPtr<CFDictionaryRef> dictionary(AdoptCF, WKNSURLResponseCreateSerializableRepresentation(resourceResponse.nsURLResponse(), CoreIPC::tokenNullTypeRef()));
     82     encode(encoder, dictionary.get());
     83 }
     84 
     85 bool decodeResourceResponse(ArgumentDecoder* decoder, ResourceResponse& resourceResponse)
     86 {
     87     bool responseIsPresent;
     88     if (!decoder->decode(responseIsPresent))
     89         return false;
     90 
     91     if (!responseIsPresent) {
     92         resourceResponse = ResourceResponse();
     93         return true;
     94     }
     95 
     96     RetainPtr<CFDictionaryRef> dictionary;
     97     if (!decode(decoder, dictionary))
     98         return false;
     99 
    100     NSURLResponse* nsURLResponse = WKNSURLResponseFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef());
    101     if (!nsURLResponse)
    102         return false;
    103 
    104     resourceResponse = ResourceResponse(nsURLResponse);
    105     return true;
    106 }
    107 
    108 static NSString* nsString(const String& string)
    109 {
    110     return string.impl() ? [NSString stringWithCharacters:reinterpret_cast<const UniChar*>(string.characters()) length:string.length()] : @"";
    111 }
    112 
    113 void encodeResourceError(ArgumentEncoder* encoder, const ResourceError& resourceError)
    114 {
    115     bool errorIsNull = resourceError.isNull();
    116     encoder->encode(errorIsNull);
    117 
    118     if (errorIsNull)
    119         return;
    120 
    121     NSError *nsError = resourceError.nsError();
    122 
    123     String domain = [nsError domain];
    124     encoder->encode(domain);
    125 
    126     int64_t code = [nsError code];
    127     encoder->encode(code);
    128 
    129     HashMap<String, String> stringUserInfoMap;
    130 
    131     NSDictionary* userInfo = [nsError userInfo];
    132     for (NSString *key in userInfo) {
    133         id value = [userInfo objectForKey:key];
    134         if (![value isKindOfClass:[NSString class]])
    135             continue;
    136 
    137         stringUserInfoMap.set(key, (NSString *)value);
    138         continue;
    139     }
    140     encoder->encode(stringUserInfoMap);
    141 
    142     id peerCertificateChain = [userInfo objectForKey:@"NSErrorPeerCertificateChainKey"];
    143     ASSERT(!peerCertificateChain || [peerCertificateChain isKindOfClass:[NSArray class]]);
    144     encoder->encode(PlatformCertificateInfo((CFArrayRef)peerCertificateChain));
    145 }
    146 
    147 bool decodeResourceError(ArgumentDecoder* decoder, ResourceError& resourceError)
    148 {
    149     bool errorIsNull;
    150     if (!decoder->decode(errorIsNull))
    151         return false;
    152 
    153     if (errorIsNull) {
    154         resourceError = ResourceError();
    155         return true;
    156     }
    157 
    158     String domain;
    159     if (!decoder->decode(domain))
    160         return false;
    161 
    162     int64_t code;
    163     if (!decoder->decode(code))
    164         return false;
    165 
    166     HashMap<String, String> stringUserInfoMap;
    167     if (!decoder->decode(stringUserInfoMap))
    168         return false;
    169 
    170     PlatformCertificateInfo certificate;
    171     if (!decoder->decode(certificate))
    172         return false;
    173 
    174     NSUInteger userInfoSize = stringUserInfoMap.size();
    175     if (certificate.certificateChain())
    176         userInfoSize++;
    177 
    178     NSMutableDictionary* userInfo = [NSMutableDictionary dictionaryWithCapacity:userInfoSize];
    179 
    180     HashMap<String, String>::const_iterator it = stringUserInfoMap.begin();
    181     HashMap<String, String>::const_iterator end = stringUserInfoMap.end();
    182     for (; it != end; ++it)
    183         [userInfo setObject:nsString(it->second) forKey:nsString(it->first)];
    184 
    185     if (certificate.certificateChain())
    186         [userInfo setObject:(NSArray *)certificate.certificateChain() forKey:@"NSErrorPeerCertificateChainKey"];
    187 
    188     NSError *nsError = [[NSError alloc] initWithDomain:nsString(domain) code:code userInfo:userInfo];
    189 
    190     resourceError = ResourceError(nsError);
    191     [nsError release];
    192     return true;
    193 }
    194 
    195 } // namespace CoreIPC
    196