Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2007, 2011 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 <WebKit/WebDataSourcePrivate.h>
     37 #import <wtf/Assertions.h>
     38 
     39 using namespace std;
     40 
     41 @interface NSURL (DRTExtras)
     42 - (NSString *)_drt_descriptionSuitableForTestResult;
     43 @end
     44 
     45 @interface NSError (DRTExtras)
     46 - (NSString *)_drt_descriptionSuitableForTestResult;
     47 @end
     48 
     49 @interface NSURLResponse (DRTExtras)
     50 - (NSString *)_drt_descriptionSuitableForTestResult;
     51 @end
     52 
     53 @interface NSURLRequest (DRTExtras)
     54 - (NSString *)_drt_descriptionSuitableForTestResult;
     55 @end
     56 
     57 @implementation NSError (DRTExtras)
     58 - (NSString *)_drt_descriptionSuitableForTestResult
     59 {
     60     NSString *str = [NSString stringWithFormat:@"<NSError domain %@, code %d", [self domain], [self code]];
     61     NSURL *failingURL;
     62 
     63     if ((failingURL = [[self userInfo] objectForKey:@"NSErrorFailingURLKey"]))
     64         str = [str stringByAppendingFormat:@", failing URL \"%@\"", [failingURL _drt_descriptionSuitableForTestResult]];
     65 
     66     str = [str stringByAppendingFormat:@">"];
     67 
     68     return str;
     69 }
     70 
     71 @end
     72 
     73 @implementation NSURL (DRTExtras)
     74 
     75 - (NSString *)_drt_descriptionSuitableForTestResult
     76 {
     77     if (![self isFileURL])
     78         return [self absoluteString];
     79 
     80     WebDataSource *dataSource = [mainFrame dataSource];
     81     if (!dataSource)
     82         dataSource = [mainFrame provisionalDataSource];
     83 
     84     NSString *basePath = [[[[dataSource request] URL] path] stringByDeletingLastPathComponent];
     85 
     86     return [[self path] substringFromIndex:[basePath length] + 1];
     87 }
     88 
     89 @end
     90 
     91 @implementation NSURLResponse (DRTExtras)
     92 
     93 - (NSString *)_drt_descriptionSuitableForTestResult
     94 {
     95     int statusCode = 0;
     96     if ([self isKindOfClass:[NSHTTPURLResponse class]])
     97         statusCode = [(NSHTTPURLResponse *)self statusCode];
     98     return [NSString stringWithFormat:@"<NSURLResponse %@, http status code %i>", [[self URL] _drt_descriptionSuitableForTestResult], statusCode];
     99 }
    100 
    101 @end
    102 
    103 @implementation NSURLRequest (DRTExtras)
    104 
    105 - (NSString *)_drt_descriptionSuitableForTestResult
    106 {
    107     NSString *httpMethod = [self HTTPMethod];
    108     if (!httpMethod)
    109         httpMethod = @"(none)";
    110     return [NSString stringWithFormat:@"<NSURLRequest URL %@, main document URL %@, http method %@>", [[self URL] _drt_descriptionSuitableForTestResult], [[self mainDocumentURL] _drt_descriptionSuitableForTestResult], httpMethod];
    111 }
    112 
    113 @end
    114 
    115 @implementation ResourceLoadDelegate
    116 
    117 - webView: (WebView *)wv identifierForInitialRequest: (NSURLRequest *)request fromDataSource: (WebDataSource *)dataSource
    118 {
    119     ASSERT([[dataSource webFrame] dataSource] || [[dataSource webFrame] provisionalDataSource]);
    120 
    121     if (!done && gLayoutTestController->dumpResourceLoadCallbacks())
    122         return [[request URL] _drt_descriptionSuitableForTestResult];
    123 
    124     return @"<unknown>";
    125 }
    126 
    127 -(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
    128 {
    129     if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
    130         NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [request _drt_descriptionSuitableForTestResult],
    131             [redirectResponse _drt_descriptionSuitableForTestResult]];
    132         printf("%s\n", [string UTF8String]);
    133     }
    134 
    135     if (!done && !gLayoutTestController->deferMainResourceDataLoad()) {
    136         [dataSource _setDeferMainResourceDataLoad:false];
    137     }
    138 
    139     if (!done && gLayoutTestController->willSendRequestReturnsNull())
    140         return nil;
    141 
    142     if (!done && gLayoutTestController->willSendRequestReturnsNullOnRedirect() && redirectResponse) {
    143         printf("Returning null for this redirect\n");
    144         return nil;
    145     }
    146 
    147     NSURL *url = [request URL];
    148     NSString *host = [url host];
    149     if (host
    150         && (NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"http"] || NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"https"])
    151         && NSOrderedSame != [host compare:@"127.0.0.1"]
    152         && NSOrderedSame != [host compare:@"255.255.255.255"] // used in some tests that expect to get back an error
    153         && NSOrderedSame != [host caseInsensitiveCompare:@"localhost"]) {
    154         printf("Blocked access to external URL %s\n", [[url absoluteString] cStringUsingEncoding:NSUTF8StringEncoding]);
    155         return nil;
    156     }
    157 
    158     if (disallowedURLs && CFSetContainsValue(disallowedURLs, url))
    159         return nil;
    160 
    161     NSMutableURLRequest *newRequest = [request mutableCopy];
    162     const set<string>& clearHeaders = gLayoutTestController->willSendRequestClearHeaders();
    163     for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header) {
    164         NSString *nsHeader = [[NSString alloc] initWithUTF8String:header->c_str()];
    165         [newRequest setValue:nil forHTTPHeaderField:nsHeader];
    166         [nsHeader release];
    167     }
    168     const std::string& destination = gLayoutTestController->redirectionDestinationForURL([[url absoluteString] UTF8String]);
    169     if (destination.length())
    170         [newRequest setURL:[NSURL URLWithString:[NSString stringWithUTF8String:destination.data()]]];
    171 
    172     return [newRequest autorelease];
    173 }
    174 
    175 - (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
    176 {
    177     if (!gLayoutTestController->handlesAuthenticationChallenges()) {
    178         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet", identifier];
    179         printf("%s\n", [string UTF8String]);
    180 
    181         [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
    182         return;
    183     }
    184 
    185     const char* user = gLayoutTestController->authenticationUsername().c_str();
    186     NSString *nsUser = [NSString stringWithFormat:@"%s", user ? user : ""];
    187 
    188     const char* password = gLayoutTestController->authenticationPassword().c_str();
    189     NSString *nsPassword = [NSString stringWithFormat:@"%s", password ? password : ""];
    190 
    191     NSString *string = [NSString stringWithFormat:@"%@ - didReceiveAuthenticationChallenge - Responding with %@:%@", identifier, nsUser, nsPassword];
    192     printf("%s\n", [string UTF8String]);
    193 
    194     [[challenge sender] useCredential:[NSURLCredential credentialWithUser:nsUser password:nsPassword persistence:NSURLCredentialPersistenceForSession]
    195                               forAuthenticationChallenge:challenge];
    196 }
    197 
    198 - (void)webView:(WebView *)wv resource:(id)identifier didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
    199 {
    200 }
    201 
    202 -(void)webView: (WebView *)wv resource:identifier didReceiveResponse: (NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
    203 {
    204     if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
    205         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveResponse %@", identifier, [response _drt_descriptionSuitableForTestResult]];
    206         printf("%s\n", [string UTF8String]);
    207     }
    208     if (!done && gLayoutTestController->dumpResourceResponseMIMETypes())
    209         printf("%s has MIME type %s\n", [[[[response URL] relativePath] lastPathComponent] UTF8String], [[response MIMEType] UTF8String]);
    210 }
    211 
    212 -(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (NSInteger)length fromDataSource:(WebDataSource *)dataSource
    213 {
    214 }
    215 
    216 -(void)webView: (WebView *)wv resource:identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
    217 {
    218     if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
    219         NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoading", identifier];
    220         printf("%s\n", [string UTF8String]);
    221     }
    222 }
    223 
    224 -(void)webView: (WebView *)wv resource:identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
    225 {
    226     if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
    227         NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadingWithError: %@", identifier, [error _drt_descriptionSuitableForTestResult]];
    228         printf("%s\n", [string UTF8String]);
    229     }
    230 }
    231 
    232 - (void)webView: (WebView *)wv plugInFailedWithError:(NSError *)error dataSource:(WebDataSource *)dataSource
    233 {
    234     // The call to -display here simulates the "Plug-in not found" sheet that Safari shows.
    235     // It is used for platform/mac/plugins/update-widget-from-style-recalc.html
    236     [wv display];
    237 }
    238 
    239 -(NSCachedURLResponse *) webView: (WebView *)wv resource:(id)identifier willCacheResponse:(NSCachedURLResponse *)response fromDataSource:(WebDataSource *)dataSource
    240 {
    241     if (!done && gLayoutTestController->dumpWillCacheResponse()) {
    242         NSString *string = [NSString stringWithFormat:@"%@ - willCacheResponse: called", identifier];
    243         printf("%s\n", [string UTF8String]);
    244     }
    245     return response;
    246 }
    247 
    248 -(BOOL)webView: (WebView*)webView shouldPaintBrokenImageForURL:(NSURL*)imageURL
    249 {
    250     // Only log the message when shouldPaintBrokenImage() returns NO; this avoids changing results of layout tests with failed
    251     // images, e.g., security/block-test-no-port.html.
    252     if (!done && gLayoutTestController->dumpResourceLoadCallbacks() && !gLayoutTestController->shouldPaintBrokenImage()) {
    253         NSString *string = [NSString stringWithFormat:@"%@ - shouldPaintBrokenImage: NO", [imageURL _drt_descriptionSuitableForTestResult]];
    254         printf("%s\n", [string UTF8String]);
    255     }
    256 
    257     return gLayoutTestController->shouldPaintBrokenImage();
    258 }
    259 @end
    260