diff options
author | kkhorimoto <kkhorimoto@google.com> | 2015-05-26 13:28:21 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-26 20:28:59 +0000 |
commit | 555f740c0f81262c44a5b1e48f1d56af7f6baca9 (patch) | |
tree | 7ecfc986723a2c0b173ce3b221fa632f53cd9c6d | |
parent | ee92e3890448e5d0fa00634d18308f0adb079211 (diff) | |
download | chromium_src-555f740c0f81262c44a5b1e48f1d56af7f6baca9.zip chromium_src-555f740c0f81262c44a5b1e48f1d56af7f6baca9.tar.gz chromium_src-555f740c0f81262c44a5b1e48f1d56af7f6baca9.tar.bz2 |
Created HttpResponseHeadersUtil.
Since the net stack is not an option with WKWebView, generate headers
from the WKNavigationResponse and pass them to the web state. Among
other things, this will enable the web state to have an accurate MIME
type.
BUG=478058
Review URL: https://codereview.chromium.org/1126843002
Cr-Commit-Position: refs/heads/master@{#331422}
-rw-r--r-- | ios/net/http_response_headers_util.h | 28 | ||||
-rw-r--r-- | ios/net/http_response_headers_util.mm | 46 | ||||
-rw-r--r-- | ios/net/http_response_headers_util_unittest.mm | 57 | ||||
-rw-r--r-- | ios/net/ios_net.gyp | 2 | ||||
-rw-r--r-- | ios/net/ios_net_unittests.gyp | 1 | ||||
-rw-r--r-- | ios/web/web_state/ui/crw_wk_web_view_web_controller.mm | 14 | ||||
-rw-r--r-- | ios/web/web_state/web_state_impl.h | 3 |
7 files changed, 151 insertions, 0 deletions
diff --git a/ios/net/http_response_headers_util.h b/ios/net/http_response_headers_util.h new file mode 100644 index 0000000..4bc0019 --- /dev/null +++ b/ios/net/http_response_headers_util.h @@ -0,0 +1,28 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_NET_HTTP_RESPONSE_HEADERS_UTIL_H_ +#define IOS_NET_HTTP_RESPONSE_HEADERS_UTIL_H_ + +#include "base/memory/scoped_ptr.h" +#include "net/http/http_response_headers.h" + +@class NSHTTPURLResponse; + +namespace net { + +// Placeholder status description since the actual text from the headers is not +// available. +extern const std::string kDummyHttpStatusDescription; + +// Constructs a net::HttpResponseHeaders from |response|. +// Note: The HTTP version and the status code description are not accessible +// from NSHTTPURLResponse, so HTTP/1.0 and kDummyHttpStatusDescription will +// be used in the status line instead. +scoped_refptr<HttpResponseHeaders> CreateHeadersFromNSHTTPURLResponse( + NSHTTPURLResponse* response); + +} // namespace net + +#endif // IOS_NET_HTTP_RESPONSE_HEADERS_UTIL_H_ diff --git a/ios/net/http_response_headers_util.mm b/ios/net/http_response_headers_util.mm new file mode 100644 index 0000000..64d86b5 --- /dev/null +++ b/ios/net/http_response_headers_util.mm @@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/net/http_response_headers_util.h" + +#include <Foundation/Foundation.h> + +#include "base/logging.h" +#include "base/strings/sys_string_conversions.h" + +namespace { +// String format used to create the http status line from the status code and +// its localized description. +NSString* const kHttpStatusLineFormat = @"HTTP %ld %s"; +// String format used to pass the header name/value pairs to the +// HttpResponseHeaders. +NSString* const kHeaderLineFormat = @"%@: %@"; +} + +namespace net { + +const std::string kDummyHttpStatusDescription = "DummyStatusDescription"; + +scoped_refptr<HttpResponseHeaders> CreateHeadersFromNSHTTPURLResponse( + NSHTTPURLResponse* response) { + DCHECK(response); + // Create the status line and initialize the headers. + NSInteger status_code = response.statusCode; + std::string status_line = base::SysNSStringToUTF8([NSString + stringWithFormat:kHttpStatusLineFormat, static_cast<long>(status_code), + kDummyHttpStatusDescription.c_str()]); + scoped_refptr<HttpResponseHeaders> http_headers( + new HttpResponseHeaders(status_line)); + // Iterate through |response|'s headers and add them to |http_headers|. + [response.allHeaderFields + enumerateKeysAndObjectsUsingBlock:^(NSString* header_name, + NSString* value, BOOL*) { + NSString* header_line = + [NSString stringWithFormat:kHeaderLineFormat, header_name, value]; + http_headers->AddHeader(base::SysNSStringToUTF8(header_line)); + }]; + return http_headers.Pass(); +} + +} // namespae net diff --git a/ios/net/http_response_headers_util_unittest.mm b/ios/net/http_response_headers_util_unittest.mm new file mode 100644 index 0000000..27dfcb8 --- /dev/null +++ b/ios/net/http_response_headers_util_unittest.mm @@ -0,0 +1,57 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/net/http_response_headers_util.h" + +#import <Foundation/Foundation.h> + +#include <algorithm> + +#include "base/mac/scoped_nsobject.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/sys_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +// Returns true if all the information in |http_response| is present in +// |http_response_headers|. +bool AreHeadersEqual(NSHTTPURLResponse* http_response, + HttpResponseHeaders* http_response_headers) { + if (!http_response || !http_response_headers) + return false; + if (http_response.statusCode != http_response_headers->response_code()) + return false; + __block bool all_headers_present = true; + [http_response.allHeaderFields + enumerateKeysAndObjectsUsingBlock:^(NSString* header_name, + NSString* header_value, BOOL* stop) { + std::string value; + http_response_headers->GetNormalizedHeader( + base::SysNSStringToUTF8(header_name), &value); + all_headers_present = (value == base::SysNSStringToUTF8(header_value)); + *stop = !all_headers_present; + }]; + return all_headers_present; +} + +// Tests that HttpResponseHeaders created from NSHTTPURLResponses successfully +// copy over the status code and the header names and values. +TEST(HttpResponseHeadersUtilTest, CreateHeadersFromNSHTTPURLResponse) { + base::scoped_nsobject<NSHTTPURLResponse> http_response( + [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"test.com"] + statusCode:200 + HTTPVersion:@"HTTP/1.1" + headerFields:@{ + @"headerName1" : @"headerValue1", + @"headerName2" : @"headerValue2", + @"headerName3" : @"headerValue3", + }]); + scoped_refptr<HttpResponseHeaders> http_response_headers = + CreateHeadersFromNSHTTPURLResponse(http_response); + EXPECT_TRUE( + AreHeadersEqual(http_response.get(), http_response_headers.get())); +} + +} // namespace net. diff --git a/ios/net/ios_net.gyp b/ios/net/ios_net.gyp index 6208ce9..bd2e153 100644 --- a/ios/net/ios_net.gyp +++ b/ios/net/ios_net.gyp @@ -44,6 +44,8 @@ 'crn_http_url_response.mm', 'http_protocol_logging.h', 'http_protocol_logging.mm', + 'http_response_headers_util.h', + 'http_response_headers_util.mm', 'nsurlrequest_util.h', 'nsurlrequest_util.mm', 'protocol_handler_util.h', diff --git a/ios/net/ios_net_unittests.gyp b/ios/net/ios_net_unittests.gyp index 8818b33..98d2410 100644 --- a/ios/net/ios_net_unittests.gyp +++ b/ios/net/ios_net_unittests.gyp @@ -26,6 +26,7 @@ 'cookies/cookie_creation_time_manager_unittest.mm', 'cookies/cookie_store_ios_unittest.mm', 'cookies/system_cookie_util_unittest.mm', + 'http_response_headers_util_unittest.mm', 'nsurlrequest_util_unittest.mm', 'protocol_handler_util_unittest.mm', 'url_scheme_util_unittest.mm', diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm index c08ccab..7922cd6 100644 --- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm +++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm @@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/strings/sys_string_conversions.h" #include "base/values.h" +#import "ios/net/http_response_headers_util.h" #import "ios/web/crw_network_activity_indicator_manager.h" #import "ios/web/navigation/crw_session_controller.h" #include "ios/web/navigation/web_load_params.h" @@ -946,6 +947,19 @@ NSString* const kScriptImmediateName = @"crwebinvokeimmediate"; decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler: (void (^)(WKNavigationResponsePolicy))handler { + if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { + // Create HTTP headers from the response. + // TODO(kkhorimoto): Due to the limited interface of NSHTTPURLResponse, some + // data in the HttpResponseHeaders generated here is inexact. Once + // UIWebView is no longer supported, update WebState's implementation so + // that the Content-Language and the MIME type can be set without using this + // imperfect conversion. + scoped_refptr<net::HttpResponseHeaders> HTTPHeaders = + net::CreateHeadersFromNSHTTPURLResponse( + static_cast<NSHTTPURLResponse*>(navigationResponse.response)); + self.webStateImpl->OnHttpResponseHeadersReceived( + HTTPHeaders.get(), net::GURLWithNSURL(navigationResponse.response.URL)); + } if (navigationResponse.isForMainFrame) self.documentMIMEType = navigationResponse.response.MIMEType; handler(navigationResponse.canShowMIMEType ? WKNavigationResponsePolicyAllow : diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index b8695ec..067f96a 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h @@ -164,6 +164,9 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate { const base::string16& GetTitle() const; // Gets the HTTP response headers associated with the current page. + // NOTE: For a WKWebView-based WebState, these headers are generated via + // net::CreateHeadersFromNSHTTPURLResponse(); see comments in + // http_response_headers_util.h for limitations. net::HttpResponseHeaders* GetHttpResponseHeaders() const; // Called when HTTP response headers are received. |