Prevent app list doodle from being pinch-to-zoomed.
[chromium-blink-merge.git] / ios / web / web_state / ui / crw_static_file_web_view.mm
blobe40a0af5369ecc83effcbd0755730b19c2d628cd
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.
5 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
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"
14 namespace {
15 NSString* const kStaticFileUserAgent = @"UIWebViewForStaticFileContent";
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_;
27 // Whether the User-Agent is the allowed user agent.
28 + (BOOL)isStaticFileUserAgent:(NSString*)userAgent;
29 @end
31 @implementation CRWStaticFileWebView
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;
64 - (void)dealloc {
65   if (requestTracker_.get())
66     requestTracker_->Close();
67   [super dealloc];
70 + (BOOL)isStaticFileRequest:(NSURLRequest*)request {
71   NSString* userAgent = [request allHTTPHeaderFields][@"User-Agent"];
72   if (userAgent) {
73     return [CRWStaticFileWebView isStaticFileUserAgent:userAgent];
74   }
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]];
86 + (BOOL)isStaticFileUserAgent:(NSString*)userAgent {
87   return [userAgent hasPrefix:kStaticFileUserAgent];
90 #pragma mark -
91 #pragma mark UIWebView
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];
103 #pragma mark -
104 #pragma mark CRWRequestTrackerDelegate
106 - (BOOL)isForStaticFileRequests {
107   return YES;
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"));
118 // The following delegate functions are not expected to be called since
119 // the page is intended to be a static HTML page.
121 - (void)updatedSSLStatus:(const web::SSLStatus&)sslStatus
122               forPageUrl:(const GURL&)url
123                 userInfo:(id)userInfo {
124   NOTREACHED();
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();
135 - (void)updatedProgress:(float)progress {
136   NOTREACHED();
139 - (void)certificateUsed:(net::X509Certificate*)certificate
140                 forHost:(const std::string&)host
141                  status:(net::CertStatus)status {
142   NOTREACHED();
145 - (void)clearCertificates {
146   NOTREACHED();
149 @end