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