Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/web/net/clients/crw_js_injection_network_client.h" | 5 #import "ios/web/net/clients/crw_js_injection_network_client.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/objc_property_releaser.h" | |
| 12 #include "base/mac/scoped_nsobject.h" | 11 #include "base/mac/scoped_nsobject.h" |
| 13 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 14 #import "ios/net/crn_http_url_response.h" | 13 #import "ios/net/crn_http_url_response.h" |
| 15 #import "ios/third_party/blink/src/html_tokenizer.h" | 14 #import "ios/third_party/blink/src/html_tokenizer.h" |
| 16 | 15 |
| 16 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
|
Eugene But (OOO till 7-30)
2016/08/19 16:34:50
We don't need network clients code with WKWebView.
| |
| 17 #error "This file requires ARC support." | |
| 18 #endif | |
| 19 | |
| 17 // CRWJSInjectionNetworkClient injects an external script tag reference for | 20 // CRWJSInjectionNetworkClient injects an external script tag reference for |
| 18 // crweb.js into HTML and XHTML documents. To do this correctly, three data | 21 // crweb.js into HTML and XHTML documents. To do this correctly, three data |
| 19 // points are needed: where to inject the script tag, what encoding the content | 22 // points are needed: where to inject the script tag, what encoding the content |
| 20 // is in (ASCII compatible, UTF32, UTF16 and big or little endian) and the byte | 23 // is in (ASCII compatible, UTF32, UTF16 and big or little endian) and the byte |
| 21 // length of the injection tag itself. | 24 // length of the injection tag itself. |
| 22 // | 25 // |
| 23 // The content encoding is handled first. As data is received, | 26 // The content encoding is handled first. As data is received, |
| 24 // CRWJSInjectionNetworkClient will look at the beginning few bytes of the | 27 // CRWJSInjectionNetworkClient will look at the beginning few bytes of the |
| 25 // content for either a byte-order mark or an XML declaration. If present, they | 28 // content for either a byte-order mark or an XML declaration. If present, they |
| 26 // will be matched to a known set of patterns to determine the encoding. If not | 29 // will be matched to a known set of patterns to determine the encoding. If not |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 base::scoped_nsobject<NSMutableDictionary> all_headers_mutable; | 142 base::scoped_nsobject<NSMutableDictionary> all_headers_mutable; |
| 140 all_headers_mutable.reset([all_headers mutableCopy]); | 143 all_headers_mutable.reset([all_headers mutableCopy]); |
| 141 [all_headers_mutable setObject:content_length_value forKey:kContentLength]; | 144 [all_headers_mutable setObject:content_length_value forKey:kContentLength]; |
| 142 | 145 |
| 143 CRNHTTPURLResponse* update_response = | 146 CRNHTTPURLResponse* update_response = |
| 144 [[CRNHTTPURLResponse alloc] initWithURL:[response URL] | 147 [[CRNHTTPURLResponse alloc] initWithURL:[response URL] |
| 145 statusCode:[response statusCode] | 148 statusCode:[response statusCode] |
| 146 HTTPVersion:[response cr_HTTPVersion] | 149 HTTPVersion:[response cr_HTTPVersion] |
| 147 headerFields:all_headers_mutable]; | 150 headerFields:all_headers_mutable]; |
| 148 | 151 |
| 149 return [update_response autorelease]; | 152 return update_response; |
| 150 } | 153 } |
| 151 } // namespace | 154 } // namespace |
| 152 | 155 |
| 153 @interface CRWJSInjectionNetworkClient () { | 156 @interface CRWJSInjectionNetworkClient () { |
| 154 // The CRNHTTPURLResponse that is held until it is determined if the content | 157 // The CRNHTTPURLResponse that is held until it is determined if the content |
| 155 // will have JavaScript injected. | 158 // will have JavaScript injected. |
| 156 base::scoped_nsobject<CRNHTTPURLResponse> _pendingResponse; | 159 base::scoped_nsobject<CRNHTTPURLResponse> _pendingResponse; |
| 157 | 160 |
| 158 // An array of data that is buffered until a determination is made about | 161 // An array of data that is buffered until a determination is made about |
| 159 // injecting JavaScript. | 162 // injecting JavaScript. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 [static_cast<NSHTTPURLResponse*>(response) allHeaderFields])); | 294 [static_cast<NSHTTPURLResponse*>(response) allHeaderFields])); |
| 292 DCHECK([CRWJSInjectionNetworkClient canHandleResponse:response]); | 295 DCHECK([CRWJSInjectionNetworkClient canHandleResponse:response]); |
| 293 | 296 |
| 294 // If response does not come with Content-Length header field (i.e. the | 297 // If response does not come with Content-Length header field (i.e. the |
| 295 // Transfer-Encoding header field has value 'chunked'), response does not have | 298 // Transfer-Encoding header field has value 'chunked'), response does not have |
| 296 // to be updated. | 299 // to be updated. |
| 297 if ([response expectedContentLength] == -1) { | 300 if ([response expectedContentLength] == -1) { |
| 298 [super didReceiveResponse:response]; | 301 [super didReceiveResponse:response]; |
| 299 } else { | 302 } else { |
| 300 // Client calls [super didReceiveResponse:] in sendPendingResponse. | 303 // Client calls [super didReceiveResponse:] in sendPendingResponse. |
| 301 _pendingResponse.reset([static_cast<CRNHTTPURLResponse*>(response) retain]); | 304 _pendingResponse.reset(static_cast<CRNHTTPURLResponse*>(response)); |
| 302 } | 305 } |
| 303 } | 306 } |
| 304 | 307 |
| 305 - (void)didFinishLoading { | 308 - (void)didFinishLoading { |
| 306 [self recordHistogramResult]; | 309 [self recordHistogramResult]; |
| 307 [self sendPendingResponse]; | 310 [self sendPendingResponse]; |
| 308 [self sendPendingData]; | 311 [self sendPendingData]; |
| 309 [super didFinishLoading]; | 312 [super didFinishLoading]; |
| 310 } | 313 } |
| 311 | 314 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 } | 346 } |
| 344 | 347 |
| 345 - (NSData*)jsInjectionContent { | 348 - (NSData*)jsInjectionContent { |
| 346 DCHECK(_proceedWithInjection); | 349 DCHECK(_proceedWithInjection); |
| 347 if (_jsInjectionContent) | 350 if (_jsInjectionContent) |
| 348 return _jsInjectionContent; | 351 return _jsInjectionContent; |
| 349 | 352 |
| 350 NSString* jsContentString = [NSString | 353 NSString* jsContentString = [NSString |
| 351 stringWithFormat:kJSContentTemplate, [[NSUUID UUID] UUIDString]]; | 354 stringWithFormat:kJSContentTemplate, [[NSUUID UUID] UUIDString]]; |
| 352 _jsInjectionContent.reset( | 355 _jsInjectionContent.reset( |
| 353 [[jsContentString dataUsingEncoding:_contentEncoding] retain]); | 356 [jsContentString dataUsingEncoding:_contentEncoding]); |
| 354 | 357 |
| 355 return _jsInjectionContent; | 358 return _jsInjectionContent; |
| 356 } | 359 } |
| 357 | 360 |
| 358 - (void)sendInjectedResponseIfNeeded { | 361 - (void)sendInjectedResponseIfNeeded { |
| 359 if (!_proceedWithInjection) | 362 if (!_proceedWithInjection) |
| 360 return; | 363 return; |
| 361 | 364 |
| 362 NSData* firstData = [_pendingData firstObject]; | 365 NSData* firstData = [_pendingData firstObject]; |
| 363 NSUInteger dataLength = [firstData length]; | 366 NSUInteger dataLength = [firstData length]; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 386 } | 389 } |
| 387 | 390 |
| 388 - (void)sendPendingResponse { | 391 - (void)sendPendingResponse { |
| 389 if (!_pendingResponse) | 392 if (!_pendingResponse) |
| 390 return; | 393 return; |
| 391 | 394 |
| 392 if (_proceedWithInjection) { | 395 if (_proceedWithInjection) { |
| 393 NSUInteger additionalLength = [[self jsInjectionContent] length]; | 396 NSUInteger additionalLength = [[self jsInjectionContent] length]; |
| 394 CRNHTTPURLResponse* responseToSend = | 397 CRNHTTPURLResponse* responseToSend = |
| 395 ResponseWithUpdatedContentSize(_pendingResponse, additionalLength); | 398 ResponseWithUpdatedContentSize(_pendingResponse, additionalLength); |
| 396 _pendingResponse.reset([responseToSend retain]); | 399 _pendingResponse.reset(responseToSend); |
| 397 } | 400 } |
| 398 | 401 |
| 399 [super didReceiveResponse:_pendingResponse]; | 402 [super didReceiveResponse:_pendingResponse]; |
| 400 _pendingResponse.reset(); | 403 _pendingResponse.reset(); |
| 401 } | 404 } |
| 402 | 405 |
| 403 - (void)sendPendingData { | 406 - (void)sendPendingData { |
| 404 if (![_pendingData count]) | 407 if (![_pendingData count]) |
| 405 return; | 408 return; |
| 406 | 409 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 } | 630 } |
| 628 } | 631 } |
| 629 | 632 |
| 630 // There is an early exit case right at the end of the start-tag from the | 633 // There is an early exit case right at the end of the start-tag from the |
| 631 // WebCore::HTMLTokenizer::nextToken(), so double check to see if we hit | 634 // WebCore::HTMLTokenizer::nextToken(), so double check to see if we hit |
| 632 // the limit. | 635 // the limit. |
| 633 [self checkIfByteLimitPassed:provider]; | 636 [self checkIfByteLimitPassed:provider]; |
| 634 } | 637 } |
| 635 | 638 |
| 636 @end | 639 @end |
| OLD | NEW |