1 /* 2 * Copyright (C) 2007, 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 * 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 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #import "config.h" 30 #import "ResourceLoadDelegate.h" 31 32 #import "DumpRenderTree.h" 33 #import "LayoutTestController.h" 34 #import <WebKit/WebKit.h> 35 #import <WebKit/WebTypesInternal.h> 36 #import <wtf/Assertions.h> 37 38 @interface NSURL (DRTExtras) 39 - (NSString *)_drt_descriptionSuitableForTestResult; 40 @end 41 42 @interface NSError (DRTExtras) 43 - (NSString *)_drt_descriptionSuitableForTestResult; 44 @end 45 46 @interface NSURLResponse (DRTExtras) 47 - (NSString *)_drt_descriptionSuitableForTestResult; 48 @end 49 50 @interface NSURLRequest (DRTExtras) 51 - (NSString *)_drt_descriptionSuitableForTestResult; 52 @end 53 54 @implementation NSError (DRTExtras) 55 - (NSString *)_drt_descriptionSuitableForTestResult 56 { 57 NSString *str = [NSString stringWithFormat:@"<NSError domain %@, code %d", [self domain], [self code]]; 58 NSURL *failingURL; 59 60 if ((failingURL = [[self userInfo] objectForKey:@"NSErrorFailingURLKey"])) 61 str = [str stringByAppendingFormat:@", failing URL \"%@\"", [failingURL _drt_descriptionSuitableForTestResult]]; 62 63 str = [str stringByAppendingFormat:@">"]; 64 65 return str; 66 } 67 68 @end 69 70 @implementation NSURL (DRTExtras) 71 72 - (NSString *)_drt_descriptionSuitableForTestResult 73 { 74 if (![self isFileURL]) 75 return [self absoluteString]; 76 77 WebDataSource *dataSource = [mainFrame dataSource]; 78 if (!dataSource) 79 dataSource = [mainFrame provisionalDataSource]; 80 81 NSString *basePath = [[[[dataSource request] URL] path] stringByDeletingLastPathComponent]; 82 83 return [[self path] substringFromIndex:[basePath length] + 1]; 84 } 85 86 @end 87 88 @implementation NSURLResponse (DRTExtras) 89 90 - (NSString *)_drt_descriptionSuitableForTestResult 91 { 92 int statusCode = 0; 93 if ([self isKindOfClass:[NSHTTPURLResponse class]]) 94 statusCode = [(NSHTTPURLResponse *)self statusCode]; 95 return [NSString stringWithFormat:@"<NSURLResponse %@, http status code %i>", [[self URL] _drt_descriptionSuitableForTestResult], statusCode]; 96 } 97 98 @end 99 100 @implementation NSURLRequest (DRTExtras) 101 102 - (NSString *)_drt_descriptionSuitableForTestResult 103 { 104 NSString *httpMethod = [self HTTPMethod]; 105 if (!httpMethod) 106 httpMethod = @"(none)"; 107 return [NSString stringWithFormat:@"<NSURLRequest URL %@, main document URL %@, http method %@>", [[self URL] _drt_descriptionSuitableForTestResult], [[self mainDocumentURL] _drt_descriptionSuitableForTestResult], httpMethod]; 108 } 109 110 @end 111 112 @implementation ResourceLoadDelegate 113 114 - webView: (WebView *)wv identifierForInitialRequest: (NSURLRequest *)request fromDataSource: (WebDataSource *)dataSource 115 { 116 ASSERT([[dataSource webFrame] dataSource] || [[dataSource webFrame] provisionalDataSource]); 117 118 if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) 119 return [[request URL] _drt_descriptionSuitableForTestResult]; 120 121 return @"<unknown>"; 122 } 123 124 -(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource 125 { 126 if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) { 127 NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [newRequest _drt_descriptionSuitableForTestResult], 128 [redirectResponse _drt_descriptionSuitableForTestResult]]; 129 printf("%s\n", [string UTF8String]); 130 } 131 132 if (!done && gLayoutTestController->willSendRequestReturnsNull()) 133 return nil; 134 135 if (!done && gLayoutTestController->willSendRequestReturnsNullOnRedirect() && redirectResponse) { 136 printf("Returning null for this redirect\n"); 137 return nil; 138 } 139 140 NSURL *url = [newRequest URL]; 141 NSString *host = [url host]; 142 if (host 143 && (NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"http"] || NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"https"]) 144 && NSOrderedSame != [host compare:@"127.0.0.1"] 145 && NSOrderedSame != [host compare:@"255.255.255.255"] // used in some tests that expect to get back an error 146 && NSOrderedSame != [host caseInsensitiveCompare:@"localhost"]) { 147 printf("Blocked access to external URL %s\n", [[url absoluteString] cStringUsingEncoding:NSUTF8StringEncoding]); 148 return nil; 149 } 150 151 if (disallowedURLs && CFSetContainsValue(disallowedURLs, url)) 152 return nil; 153 154 return newRequest; 155 } 156 157 - (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource 158 { 159 if (!gLayoutTestController->handlesAuthenticationChallenges()) 160 return; 161 162 const char* user = gLayoutTestController->authenticationUsername().c_str(); 163 NSString *nsUser = [NSString stringWithFormat:@"%s", user ? user : ""]; 164 165 const char* password = gLayoutTestController->authenticationPassword().c_str(); 166 NSString *nsPassword = [NSString stringWithFormat:@"%s", password ? password : ""]; 167 168 NSString *string = [NSString stringWithFormat:@"%@ - didReceiveAuthenticationChallenge - Responding with %@:%@", identifier, nsUser, nsPassword]; 169 printf("%s\n", [string UTF8String]); 170 171 [[challenge sender] useCredential:[NSURLCredential credentialWithUser:nsUser password:nsPassword persistence:NSURLCredentialPersistenceForSession] 172 forAuthenticationChallenge:challenge]; 173 } 174 175 - (void)webView:(WebView *)wv resource:(id)identifier didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource 176 { 177 } 178 179 -(void)webView: (WebView *)wv resource:identifier didReceiveResponse: (NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource 180 { 181 if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) { 182 NSString *string = [NSString stringWithFormat:@"%@ - didReceiveResponse %@", identifier, [response _drt_descriptionSuitableForTestResult]]; 183 printf("%s\n", [string UTF8String]); 184 } 185 if (!done && gLayoutTestController->dumpResourceResponseMIMETypes()) 186 printf("%s has MIME type %s\n", [[[[response URL] relativePath] lastPathComponent] UTF8String], [[response MIMEType] UTF8String]); 187 } 188 189 -(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (NSInteger)length fromDataSource:(WebDataSource *)dataSource 190 { 191 } 192 193 -(void)webView: (WebView *)wv resource:identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource 194 { 195 if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) { 196 NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoading", identifier]; 197 printf("%s\n", [string UTF8String]); 198 } 199 } 200 201 -(void)webView: (WebView *)wv resource:identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource 202 { 203 if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) { 204 NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadingWithError: %@", identifier, [error _drt_descriptionSuitableForTestResult]]; 205 printf("%s\n", [string UTF8String]); 206 } 207 } 208 209 - (void)webView: (WebView *)wv plugInFailedWithError:(NSError *)error dataSource:(WebDataSource *)dataSource 210 { 211 // The call to -display here simulates the "Plug-in not found" sheet that Safari shows. 212 // It is used for platform/mac/plugins/update-widget-from-style-recalc.html 213 [wv display]; 214 } 215 216 -(NSCachedURLResponse *) webView: (WebView *)wv resource:(id)identifier willCacheResponse:(NSCachedURLResponse *)response fromDataSource:(WebDataSource *)dataSource 217 { 218 if (!done && gLayoutTestController->dumpWillCacheResponse()) { 219 NSString *string = [NSString stringWithFormat:@"%@ - willCacheResponse: called", identifier]; 220 printf("%s\n", [string UTF8String]); 221 } 222 return response; 223 } 224 225 @end 226