WKErrors need the PeerCertificateChain for certificate errors
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Mar 2011 21:25:27 +0000 (21:25 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Mar 2011 21:25:27 +0000 (21:25 +0000)
<rdar://problem/8951784>
https://bugs.webkit.org/show_bug.cgi?id=56592

Reviewed by Anders Carlsson.

* Shared/WebCoreArgumentCoders.h:
Special case encoding/decoding of ResourceErrors for the mac.

* Shared/mac/PlatformCertificateInfo.h:
* Shared/mac/PlatformCertificateInfo.mm:
(WebKit::PlatformCertificateInfo::PlatformCertificateInfo):
Add constructor that take the PeerCertificateChain as CFArrayRef.

* Shared/mac/WebCoreArgumentCodersMac.mm:
(CoreIPC::encodeResourceError):
(CoreIPC::decodeResourceError):
Add encode/decode for ResourceError using the underlying NSError
and encoding/decoding as much of the userInfo as we know how to.
Right now this includes all string values and the PeerCertificateChain.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@81387 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebCoreArgumentCoders.h
Source/WebKit2/Shared/mac/PlatformCertificateInfo.h
Source/WebKit2/Shared/mac/PlatformCertificateInfo.mm
Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm

index 26cf290..4546f48 100644 (file)
@@ -1,3 +1,26 @@
+2011-03-17  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Anders Carlsson.
+
+        WKErrors need the PeerCertificateChain for certificate errors
+        <rdar://problem/8951784>
+        https://bugs.webkit.org/show_bug.cgi?id=56592
+
+        * Shared/WebCoreArgumentCoders.h:
+        Special case encoding/decoding of ResourceErrors for the mac.
+
+        * Shared/mac/PlatformCertificateInfo.h:
+        * Shared/mac/PlatformCertificateInfo.mm:
+        (WebKit::PlatformCertificateInfo::PlatformCertificateInfo):
+        Add constructor that take the PeerCertificateChain as CFArrayRef.
+
+        * Shared/mac/WebCoreArgumentCodersMac.mm:
+        (CoreIPC::encodeResourceError):
+        (CoreIPC::decodeResourceError):
+        Add encode/decode for ResourceError using the underlying NSError
+        and encoding/decoding as much of the userInfo as we know how to.
+        Right now this includes all string values and the PeerCertificateChain.
+
 2011-03-17  John Sullivan  <sullivan@apple.com>
 
         Reviewed by Adam Roben.
index 1679bb6..dd7626d 100644 (file)
@@ -277,14 +277,27 @@ template<> struct ArgumentCoder<WebCore::ResourceResponse> {
     }
 };
 
+#if PLATFORM(MAC)
+// These two functions are implemented in a platform specific manner.
+void encodeResourceError(ArgumentEncoder*, const WebCore::ResourceError&);
+bool decodeResourceError(ArgumentDecoder*, WebCore::ResourceError&);
+#endif
+
 template<> struct ArgumentCoder<WebCore::ResourceError> {
     static void encode(ArgumentEncoder* encoder, const WebCore::ResourceError& resourceError)
     {
+#if PLATFORM(MAC)
+        encodeResourceError(encoder, resourceError);
+#else
         encoder->encode(CoreIPC::In(resourceError.domain(), resourceError.errorCode(), resourceError.failingURL(), resourceError.localizedDescription()));
+#endif
     }
     
     static bool decode(ArgumentDecoder* decoder, WebCore::ResourceError& resourceError)
     {
+#if PLATFORM(MAC)
+        return decodeResourceError(decoder, resourceError);
+#else
         String domain;
         int errorCode;
         String failingURL;
@@ -293,10 +306,10 @@ template<> struct ArgumentCoder<WebCore::ResourceError> {
             return false;
         resourceError = WebCore::ResourceError(domain, errorCode, failingURL, localizedDescription);
         return true;
+#endif
     }
 };
 
-
 template<> struct ArgumentCoder<WebCore::WindowFeatures> {
     static void encode(ArgumentEncoder* encoder, const WebCore::WindowFeatures& windowFeatures)
     {
index be7eb36..7ef5b37 100644 (file)
@@ -40,6 +40,7 @@ class PlatformCertificateInfo {
 public:
     PlatformCertificateInfo();
     explicit PlatformCertificateInfo(const WebCore::ResourceResponse&);
+    explicit PlatformCertificateInfo(CFArrayRef certificateChain);
 
     CFArrayRef certificateChain() const { return m_certificateChain.get(); }
 
index 0c0b737..c7b5d0f 100644 (file)
@@ -44,6 +44,11 @@ PlatformCertificateInfo::PlatformCertificateInfo(const ResourceResponse& respons
 {
 }
 
+PlatformCertificateInfo::PlatformCertificateInfo(CFArrayRef certificateChain)
+    : m_certificateChain(certificateChain)
+{
+}
+
 void PlatformCertificateInfo::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
     // Special case no certificates, 
index a12e566..321cb40 100644 (file)
 #import "WebCoreArgumentCoders.h"
 
 #import "ArgumentCodersCF.h"
+#import "PlatformCertificateInfo.h"
 #import "WebKitSystemInterface.h"
 
+using namespace WebCore;
+using namespace WebKit;
+
 namespace CoreIPC {
 
-void encodeResourceRequest(ArgumentEncoder* encoder, const WebCore::ResourceRequest& resourceRequest)
+void encodeResourceRequest(ArgumentEncoder* encoder, const ResourceRequest& resourceRequest)
 {
     bool requestIsPresent = resourceRequest.nsURLRequest();
     encoder->encode(requestIsPresent);
@@ -43,14 +47,14 @@ void encodeResourceRequest(ArgumentEncoder* encoder, const WebCore::ResourceRequ
     encode(encoder, dictionary.get());
 }
 
-bool decodeResourceRequest(ArgumentDecoder* decoder, WebCore::ResourceRequest& resourceRequest)
+bool decodeResourceRequest(ArgumentDecoder* decoder, ResourceRequest& resourceRequest)
 {
     bool requestIsPresent;
     if (!decoder->decode(requestIsPresent))
         return false;
 
     if (!requestIsPresent) {
-        resourceRequest = WebCore::ResourceRequest();
+        resourceRequest = ResourceRequest();
         return true;
     }
 
@@ -62,11 +66,11 @@ bool decodeResourceRequest(ArgumentDecoder* decoder, WebCore::ResourceRequest& r
     if (!nsURLRequest)
         return false;
 
-    resourceRequest = WebCore::ResourceRequest(nsURLRequest);
+    resourceRequest = ResourceRequest(nsURLRequest);
     return true;
 }
 
-void encodeResourceResponse(ArgumentEncoder* encoder, const WebCore::ResourceResponse& resourceResponse)
+void encodeResourceResponse(ArgumentEncoder* encoder, const ResourceResponse& resourceResponse)
 {
     bool responseIsPresent = resourceResponse.nsURLResponse();
     encoder->encode(responseIsPresent);
@@ -78,14 +82,14 @@ void encodeResourceResponse(ArgumentEncoder* encoder, const WebCore::ResourceRes
     encode(encoder, dictionary.get());
 }
 
-bool decodeResourceResponse(ArgumentDecoder* decoder, WebCore::ResourceResponse& resourceResponse)
+bool decodeResourceResponse(ArgumentDecoder* decoder, ResourceResponse& resourceResponse)
 {
     bool responseIsPresent;
     if (!decoder->decode(responseIsPresent))
         return false;
 
     if (!responseIsPresent) {
-        resourceResponse = WebCore::ResourceResponse();
+        resourceResponse = ResourceResponse();
         return true;
     }
 
@@ -97,7 +101,93 @@ bool decodeResourceResponse(ArgumentDecoder* decoder, WebCore::ResourceResponse&
     if (!nsURLResponse)
         return false;
 
-    resourceResponse = WebCore::ResourceResponse(nsURLResponse);
+    resourceResponse = ResourceResponse(nsURLResponse);
+    return true;
+}
+
+static NSString* nsString(const String& string)
+{
+    return string.impl() ? [NSString stringWithCharacters:reinterpret_cast<const UniChar*>(string.characters()) length:string.length()] : @"";
+}
+
+void encodeResourceError(ArgumentEncoder* encoder, const ResourceError& resourceError)
+{
+    bool errorIsNull = resourceError.isNull();
+    encoder->encode(errorIsNull);
+
+    if (errorIsNull)
+        return;
+
+    NSError *nsError = resourceError.nsError();
+
+    String domain = [nsError domain];
+    encoder->encode(domain);
+    
+    int64_t code = [nsError code];
+    encoder->encode(code);
+
+    HashMap<String, String> stringUserInfoMap;
+
+    NSDictionary* userInfo = [nsError userInfo];
+    for (NSString *key in userInfo) {
+        id value = [userInfo objectForKey:key];
+        if (![value isKindOfClass:[NSString class]])
+            continue;
+
+        stringUserInfoMap.set(key, (NSString *)value);
+        continue;
+    }
+    encoder->encode(stringUserInfoMap);
+
+    id peerCertificateChain = [userInfo objectForKey:@"NSErrorPeerCertificateChainKey"];
+    ASSERT(!peerCertificateChain || [peerCertificateChain isKindOfClass:[NSArray class]]);
+    encoder->encode(PlatformCertificateInfo((CFArrayRef)peerCertificateChain));
+}
+
+bool decodeResourceError(ArgumentDecoder* decoder, ResourceError& resourceError)
+{
+    bool errorIsNull;
+    if (!decoder->decode(errorIsNull))
+        return false;
+    
+    if (errorIsNull) {
+        resourceError = ResourceError();
+        return true;
+    }
+
+    String domain;
+    if (!decoder->decode(domain))
+        return false;
+
+    int64_t code;
+    if (!decoder->decode(code))
+        return false;
+
+    HashMap<String, String> stringUserInfoMap;
+    if (!decoder->decode(stringUserInfoMap))
+        return false;
+
+    PlatformCertificateInfo certificate;
+    if (!decoder->decode(certificate))
+        return false;
+
+    NSUInteger userInfoSize = stringUserInfoMap.size();
+    if (certificate.certificateChain())
+        userInfoSize++;
+
+    NSMutableDictionary* userInfo = [NSMutableDictionary dictionaryWithCapacity:userInfoSize];
+    
+    HashMap<String, String>::const_iterator it = stringUserInfoMap.begin();
+    HashMap<String, String>::const_iterator end = stringUserInfoMap.end();
+    for (; it != end; ++it)
+        [userInfo setObject:nsString(it->second) forKey:nsString(it->first)];
+
+    if (certificate.certificateChain())
+        [userInfo setObject:(NSArray *)certificate.certificateChain() forKey:@"NSErrorPeerCertificateChainKey"];
+
+    NSError *nsError = [[NSError alloc] initWithDomain:nsString(domain) code:code userInfo:userInfo];
+
+    resourceError = ResourceError(nsError);
     return true;
 }