| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/web/web_state/ui/crw_static_file_web_view.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "ios/web/net/request_group_util.h" |
| 9 #include "ios/web/net/request_tracker_impl.h" |
| 10 #include "ios/web/public/browser_state.h" |
| 11 #import "ios/web/ui_web_view_util.h" |
| 12 #include "net/http/http_response_headers.h" |
| 13 |
| 14 namespace { |
| 15 NSString* const kStaticFileUserAgent = @"UIWebViewForStaticFileContent"; |
| 16 } |
| 17 |
| 18 @interface CRWStaticFileWebView () { |
| 19 // Saves the user agent in order to set it on future requests. |
| 20 base::scoped_nsobject<NSString> userAgent_; |
| 21 // Saves the identification assigned to this web view for request |
| 22 // tracking. This identifiation is required for terminating request |
| 23 // tracking. |
| 24 scoped_refptr<web::RequestTrackerImpl> requestTracker_; |
| 25 } |
| 26 |
| 27 // Whether the User-Agent is the allowed user agent. |
| 28 + (BOOL)isStaticFileUserAgent:(NSString*)userAgent; |
| 29 @end |
| 30 |
| 31 @implementation CRWStaticFileWebView |
| 32 |
| 33 - (instancetype)initWithFrame:(CGRect)frame |
| 34 browserState:(web::BrowserState*)browserState { |
| 35 // Register the user agent before instantiating the UIWebView. |
| 36 NSString* requestGroupID = nil; |
| 37 NSString* userAgent = kStaticFileUserAgent; |
| 38 if (browserState) { |
| 39 requestGroupID = web::GenerateNewRequestGroupID(); |
| 40 userAgent = web::AddRequestGroupIDToUserAgent(userAgent, requestGroupID); |
| 41 } |
| 42 web::RegisterUserAgentForUIWebView(userAgent); |
| 43 self = [super initWithFrame:frame]; |
| 44 if (self) { |
| 45 DCHECK(!browserState || [requestGroupID length]); |
| 46 if (browserState) { |
| 47 userAgent_.reset([userAgent copy]); |
| 48 // If |browserState| is not nullptr, associate this UIWebView with the |
| 49 // given |requestGroupID| which cannot be nil or zero-length. |
| 50 // RequestTracker keeps track of requests to this requestGroupID until |
| 51 // this UIWebView is deallocated. UIWebViews not associated with a |
| 52 // requestGroupID will issue requests in the global request context. |
| 53 base::scoped_nsobject<NSString> requestGroupIDCopy([requestGroupID copy]); |
| 54 requestTracker_ = web::RequestTrackerImpl::CreateTrackerForRequestGroupID( |
| 55 requestGroupIDCopy, |
| 56 browserState, |
| 57 browserState->GetRequestContext(), |
| 58 self); |
| 59 } |
| 60 } |
| 61 return self; |
| 62 } |
| 63 |
| 64 - (void)dealloc { |
| 65 if (requestTracker_.get()) |
| 66 requestTracker_->Close(); |
| 67 [super dealloc]; |
| 68 } |
| 69 |
| 70 + (BOOL)isStaticFileRequest:(NSURLRequest*)request { |
| 71 NSString* userAgent = [request allHTTPHeaderFields][@"User-Agent"]; |
| 72 if (userAgent) { |
| 73 return [CRWStaticFileWebView isStaticFileUserAgent:userAgent]; |
| 74 } |
| 75 |
| 76 // If a request originated from another file:/// page, the User-Agent |
| 77 // will not be there. To be safe, check that the request is for image |
| 78 // resources only. |
| 79 // TODO(pkl): This current test to allow nil User-Agent and images to |
| 80 // be loaded. A more air-tight implementation should inline images as |
| 81 // "data" instead. See crbug.com/228603 |
| 82 NSString* suffix = [[request URL] pathExtension]; |
| 83 return [@[ @"png", @"jpg", @"jpeg" ] containsObject:[suffix lowercaseString]]; |
| 84 } |
| 85 |
| 86 + (BOOL)isStaticFileUserAgent:(NSString*)userAgent { |
| 87 return [userAgent hasPrefix:kStaticFileUserAgent]; |
| 88 } |
| 89 |
| 90 #pragma mark - |
| 91 #pragma mark UIWebView |
| 92 |
| 93 // On iOS 6.0, UIWebView does not set the user agent for static file requests. |
| 94 // The solution consists of overriding |loadRequest:| and setting the user agent |
| 95 // before loading the request. |
| 96 - (void)loadRequest:(NSURLRequest*)request { |
| 97 base::scoped_nsobject<NSMutableURLRequest> mutableRequest( |
| 98 (NSMutableURLRequest*)[request mutableCopy]); |
| 99 [mutableRequest setValue:userAgent_ forHTTPHeaderField:@"User-Agent"]; |
| 100 [super loadRequest:mutableRequest]; |
| 101 } |
| 102 |
| 103 #pragma mark - |
| 104 #pragma mark CRWRequestTrackerDelegate |
| 105 |
| 106 - (BOOL)isForStaticFileRequests { |
| 107 return YES; |
| 108 } |
| 109 |
| 110 - (void)handleResponseHeaders:(net::HttpResponseHeaders*)headers |
| 111 requestUrl:(const GURL&)requestUrl { |
| 112 std::string mimeType; |
| 113 DCHECK(headers->GetMimeType(&mimeType) && mimeType == "text/html"); |
| 114 DCHECK(!headers->HasHeader("X-Auto-Login")); |
| 115 DCHECK(!headers->HasHeader("content-disposition")); |
| 116 } |
| 117 |
| 118 // The following delegate functions are not expected to be called since |
| 119 // the page is intended to be a static HTML page. |
| 120 |
| 121 - (void)updatedSSLStatus:(const web::SSLStatus&)sslStatus |
| 122 forPageUrl:(const GURL&)url |
| 123 userInfo:(id)userInfo { |
| 124 NOTREACHED(); |
| 125 } |
| 126 |
| 127 - (void)presentSSLError:(const net::SSLInfo&)info |
| 128 forSSLStatus:(const web::SSLStatus&)status |
| 129 onUrl:(const GURL&)url |
| 130 recoverable:(BOOL)recoverable |
| 131 callback:(SSLErrorCallback)shouldContinue { |
| 132 NOTREACHED(); |
| 133 } |
| 134 |
| 135 - (void)updatedProgress:(float)progress { |
| 136 NOTREACHED(); |
| 137 } |
| 138 |
| 139 - (void)certificateUsed:(net::X509Certificate*)certificate |
| 140 forHost:(const std::string&)host |
| 141 status:(net::CertStatus)status { |
| 142 NOTREACHED(); |
| 143 } |
| 144 |
| 145 - (void)clearCertificates { |
| 146 NOTREACHED(); |
| 147 } |
| 148 |
| 149 @end |
| OLD | NEW |