Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: ios/web/navigation/crw_session_controller.mm

Issue 2698773002: [iOS] Refactoring web CRWSessionController user agent code. (Closed)
Patch Set: Fix unit tests and rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 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/navigation/crw_session_controller.h" 5 #import "ios/web/navigation/crw_session_controller.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 @property(nonatomic, readwrite, assign) NSInteger previousNavigationIndex; 104 @property(nonatomic, readwrite, assign) NSInteger previousNavigationIndex;
105 105
106 // Removes all entries after currentNavigationIndex_. 106 // Removes all entries after currentNavigationIndex_.
107 - (void)clearForwardItems; 107 - (void)clearForwardItems;
108 // Discards the transient entry, if any. 108 // Discards the transient entry, if any.
109 - (void)discardTransientItem; 109 - (void)discardTransientItem;
110 // Create a new autoreleased session entry. 110 // Create a new autoreleased session entry.
111 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url 111 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url
112 referrer:(const web::Referrer&)referrer 112 referrer:(const web::Referrer&)referrer
113 transition:(ui::PageTransition)transition 113 transition:(ui::PageTransition)transition
114 useDesktopUserAgent:(BOOL)useDesktopUserAgent 114 initiationType:
115 rendererInitiated:(BOOL)rendererInitiated; 115 (web::NavigationInitiationType)initiationType;
116 // Returns YES if the PageTransition for the underlying navigationItem at 116 // Returns YES if the PageTransition for the underlying navigationItem at
117 // |index| in |entries_| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK. 117 // |index| in |entries_| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK.
118 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index; 118 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index;
119 // Returns a NavigationItemList containing the NavigationItems from |entries|. 119 // Returns a NavigationItemList containing the NavigationItems from |entries|.
120 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries; 120 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries;
121 @end 121 @end
122 122
123 @implementation CRWSessionController 123 @implementation CRWSessionController
124 124
125 @synthesize currentNavigationIndex = _currentNavigationIndex; 125 @synthesize currentNavigationIndex = _currentNavigationIndex;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 } 305 }
306 306
307 // See NavigationController::GetVisibleEntry for the motivation for this 307 // See NavigationController::GetVisibleEntry for the motivation for this
308 // distinction. 308 // distinction.
309 - (CRWSessionEntry*)visibleEntry { 309 - (CRWSessionEntry*)visibleEntry {
310 if (_transientEntry) 310 if (_transientEntry)
311 return _transientEntry.get(); 311 return _transientEntry.get();
312 // Only return the pending_entry for new (non-history), browser-initiated 312 // Only return the pending_entry for new (non-history), browser-initiated
313 // navigations in order to prevent URL spoof attacks. 313 // navigations in order to prevent URL spoof attacks.
314 web::NavigationItemImpl* pendingItem = [_pendingEntry navigationItemImpl]; 314 web::NavigationItemImpl* pendingItem = [_pendingEntry navigationItemImpl];
315 bool safeToShowPending = pendingItem && 315
316 !pendingItem->is_renderer_initiated() && 316 if (pendingItem) {
317 _pendingItemIndex == -1; 317 bool isUserInitiated = pendingItem->NavigationInitiationType() ==
318 if (safeToShowPending) { 318 web::NavigationInitiationType::USER_INITIATED;
319 return _pendingEntry.get(); 319 bool safeToShowPending = isUserInitiated && _pendingItemIndex == -1;
320
321 if (safeToShowPending)
322 return _pendingEntry.get();
320 } 323 }
324
321 return [self lastCommittedEntry]; 325 return [self lastCommittedEntry];
322 } 326 }
323 327
324 - (CRWSessionEntry*)pendingEntry { 328 - (CRWSessionEntry*)pendingEntry {
325 return _pendingEntry.get(); 329 return _pendingEntry.get();
326 } 330 }
327 331
328 - (CRWSessionEntry*)transientEntry { 332 - (CRWSessionEntry*)transientEntry {
329 return _transientEntry.get(); 333 return _transientEntry.get();
330 } 334 }
331 335
332 - (CRWSessionEntry*)lastCommittedEntry { 336 - (CRWSessionEntry*)lastCommittedEntry {
333 if (_currentNavigationIndex == -1) 337 if (_currentNavigationIndex == -1)
334 return nil; 338 return nil;
335 return [_entries objectAtIndex:_currentNavigationIndex]; 339 return [_entries objectAtIndex:_currentNavigationIndex];
336 } 340 }
337 341
338 // Returns the previous entry in the session list, or nil if there isn't any. 342 // Returns the previous entry in the session list, or nil if there isn't any.
339 - (CRWSessionEntry*)previousEntry { 343 - (CRWSessionEntry*)previousEntry {
340 if ((_previousNavigationIndex < 0) || (![_entries count])) 344 if ((_previousNavigationIndex < 0) || (![_entries count]))
341 return nil; 345 return nil;
342 return [_entries objectAtIndex:_previousNavigationIndex]; 346 return [_entries objectAtIndex:_previousNavigationIndex];
343 } 347 }
344 348
345 - (void)addPendingItem:(const GURL&)url 349 - (void)addPendingItem:(const GURL&)url
346 referrer:(const web::Referrer&)ref 350 referrer:(const web::Referrer&)ref
347 transition:(ui::PageTransition)trans 351 transition:(ui::PageTransition)trans
348 rendererInitiated:(BOOL)rendererInitiated { 352 initiationType:(web::NavigationInitiationType)initiationType {
349 [self discardTransientItem]; 353 [self discardTransientItem];
350 _pendingItemIndex = -1; 354 _pendingItemIndex = -1;
351 355
352 // Don't create a new entry if it's already the same as the current entry, 356 // Don't create a new entry if it's already the same as the current entry,
353 // allowing this routine to be called multiple times in a row without issue. 357 // allowing this routine to be called multiple times in a row without issue.
354 // Note: CRWSessionController currently has the responsibility to distinguish 358 // Note: CRWSessionController currently has the responsibility to distinguish
355 // between new navigations and history stack navigation, hence the inclusion 359 // between new navigations and history stack navigation, hence the inclusion
356 // of specific transiton type logic here, in order to make it reliable with 360 // of specific transiton type logic here, in order to make it reliable with
357 // real-world observed behavior. 361 // real-world observed behavior.
358 // TODO(crbug.com/676129): Fix the way changes are detected/reported elsewhere 362 // TODO(crbug.com/676129): Fix the way changes are detected/reported elsewhere
359 // in the web layer so that this hack can be removed. 363 // in the web layer so that this hack can be removed.
360 // Remove the workaround code from -presentSafeBrowsingWarningForResource:. 364 // Remove the workaround code from -presentSafeBrowsingWarningForResource:.
361 CRWSessionEntry* currentEntry = self.currentEntry; 365 CRWSessionEntry* currentEntry = self.currentEntry;
362 if (currentEntry) { 366 if (currentEntry) {
363 web::NavigationItem* item = [currentEntry navigationItem]; 367 web::NavigationItem* item = [currentEntry navigationItem];
364 if (item->GetURL() == url && 368
365 (!PageTransitionCoreTypeIs(trans, ui::PAGE_TRANSITION_FORM_SUBMIT) || 369 BOOL hasSameURL = item->GetURL() == url;
366 PageTransitionCoreTypeIs(item->GetTransitionType(), 370 BOOL isPendingTransitionFormSubmit =
367 ui::PAGE_TRANSITION_FORM_SUBMIT))) { 371 PageTransitionCoreTypeIs(trans, ui::PAGE_TRANSITION_FORM_SUBMIT);
372 BOOL isCurrentTransitionFormSubmit = PageTransitionCoreTypeIs(
373 item->GetTransitionType(), ui::PAGE_TRANSITION_FORM_SUBMIT);
374 BOOL shouldCreatePendingItem =
375 !hasSameURL ||
376 (isPendingTransitionFormSubmit && !isCurrentTransitionFormSubmit);
377
378 if (!shouldCreatePendingItem) {
368 // Send the notification anyway, to preserve old behavior. It's unknown 379 // Send the notification anyway, to preserve old behavior. It's unknown
369 // whether anything currently relies on this, but since both this whole 380 // whether anything currently relies on this, but since both this whole
370 // hack and the content facade will both be going away, it's not worth 381 // hack and the content facade will both be going away, it's not worth
371 // trying to unwind. 382 // trying to unwind.
372 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { 383 if (_navigationManager && _navigationManager->GetFacadeDelegate()) {
373 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); 384 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending();
374 } 385 }
375 return; 386 return;
376 } 387 }
377 } 388 }
378 389
379 BOOL useDesktopUserAgent =
380 _useDesktopUserAgentForNextPendingItem ||
381 (self.currentEntry.navigationItem &&
382 self.currentEntry.navigationItem->IsOverridingUserAgent());
383 _useDesktopUserAgentForNextPendingItem = NO;
384 _pendingEntry.reset([self sessionEntryWithURL:url 390 _pendingEntry.reset([self sessionEntryWithURL:url
385 referrer:ref 391 referrer:ref
386 transition:trans 392 transition:trans
387 useDesktopUserAgent:useDesktopUserAgent 393 initiationType:initiationType]);
388 rendererInitiated:rendererInitiated]);
389 394
390 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { 395 if (_navigationManager && _navigationManager->GetFacadeDelegate()) {
391 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); 396 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending();
392 } 397 }
393 } 398 }
394 399
395 - (void)updatePendingItem:(const GURL&)url { 400 - (void)updatePendingItem:(const GURL&)url {
396 // If there is no pending entry, navigation is probably happening within the 401 // If there is no pending entry, navigation is probably happening within the
397 // session history. Don't modify the entry list. 402 // session history. Don't modify the entry list.
398 if (!_pendingEntry) 403 if (!_pendingEntry)
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (_navigationManager && item) 476 if (_navigationManager && item)
472 _navigationManager->OnNavigationItemCommitted(); 477 _navigationManager->OnNavigationItemCommitted();
473 DCHECK_EQ(_pendingItemIndex, -1); 478 DCHECK_EQ(_pendingItemIndex, -1);
474 } 479 }
475 480
476 - (void)addTransientItemWithURL:(const GURL&)URL { 481 - (void)addTransientItemWithURL:(const GURL&)URL {
477 _transientEntry.reset([self 482 _transientEntry.reset([self
478 sessionEntryWithURL:URL 483 sessionEntryWithURL:URL
479 referrer:web::Referrer() 484 referrer:web::Referrer()
480 transition:ui::PAGE_TRANSITION_CLIENT_REDIRECT 485 transition:ui::PAGE_TRANSITION_CLIENT_REDIRECT
481 useDesktopUserAgent:NO 486 initiationType:web::NavigationInitiationType::USER_INITIATED]);
482 rendererInitiated:NO]);
483 487
484 web::NavigationItem* navigationItem = [_transientEntry navigationItem]; 488 web::NavigationItem* navigationItem = [_transientEntry navigationItem];
485 DCHECK(navigationItem); 489 DCHECK(navigationItem);
486 navigationItem->SetTimestamp( 490 navigationItem->SetTimestamp(
487 _timeSmoother.GetSmoothedTime(base::Time::Now())); 491 _timeSmoother.GetSmoothedTime(base::Time::Now()));
488 } 492 }
489 493
490 - (void)pushNewItemWithURL:(const GURL&)URL 494 - (void)pushNewItemWithURL:(const GURL&)URL
491 stateObject:(NSString*)stateObject 495 stateObject:(NSString*)stateObject
492 transition:(ui::PageTransition)transition { 496 transition:(ui::PageTransition)transition {
493 DCHECK(![self pendingEntry]); 497 DCHECK(![self pendingEntry]);
494 DCHECK([self currentEntry]); 498 DCHECK([self currentEntry]);
495 web::NavigationItem* item = [self currentEntry].navigationItem; 499 web::NavigationItem* currentItem = [self currentEntry].navigationItem;
496 CHECK( 500 CHECK(web::history_state_util::IsHistoryStateChangeValid(
497 web::history_state_util::IsHistoryStateChangeValid(item->GetURL(), URL)); 501 currentItem->GetURL(), URL));
498 web::Referrer referrer(item->GetURL(), web::ReferrerPolicyDefault); 502 web::Referrer referrer(currentItem->GetURL(), web::ReferrerPolicyDefault);
499 bool overrideUserAgent = 503
500 self.currentEntry.navigationItem->IsOverridingUserAgent();
501 base::scoped_nsobject<CRWSessionEntry> pushedEntry([self 504 base::scoped_nsobject<CRWSessionEntry> pushedEntry([self
502 sessionEntryWithURL:URL 505 sessionEntryWithURL:URL
503 referrer:referrer 506 referrer:referrer
504 transition:transition 507 transition:transition
505 useDesktopUserAgent:overrideUserAgent 508 initiationType:web::NavigationInitiationType::USER_INITIATED]);
506 rendererInitiated:NO]); 509
507 web::NavigationItemImpl* pushedItem = [pushedEntry navigationItemImpl]; 510 web::NavigationItemImpl* pushedItem = [pushedEntry navigationItemImpl];
511 pushedItem->SetIsOverridingUserAgent(currentItem->IsOverridingUserAgent());
508 pushedItem->SetSerializedStateObject(stateObject); 512 pushedItem->SetSerializedStateObject(stateObject);
509 pushedItem->SetIsCreatedFromPushState(true); 513 pushedItem->SetIsCreatedFromPushState(true);
510 web::SSLStatus& sslStatus = [self currentEntry].navigationItem->GetSSL(); 514 web::SSLStatus& sslStatus = [self currentEntry].navigationItem->GetSSL();
511 pushedEntry.get().navigationItem->GetSSL() = sslStatus; 515 pushedEntry.get().navigationItem->GetSSL() = sslStatus;
512 516
513 [self clearForwardItems]; 517 [self clearForwardItems];
514 // Add the new entry at the end. 518 // Add the new entry at the end.
515 [_entries addObject:pushedEntry]; 519 [_entries addObject:pushedEntry];
516 _previousNavigationIndex = _currentNavigationIndex; 520 _previousNavigationIndex = _currentNavigationIndex;
517 self.currentNavigationIndex = [_entries count] - 1; 521 self.currentNavigationIndex = [_entries count] - 1;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 670
667 NSInteger index = _currentNavigationIndex; 671 NSInteger index = _currentNavigationIndex;
668 // This will return the first session entry if all other entries are 672 // This will return the first session entry if all other entries are
669 // redirects, regardless of the transition state of the first entry. 673 // redirects, regardless of the transition state of the first entry.
670 while (index > 0 && [self isRedirectTransitionForItemAtIndex:index]) { 674 while (index > 0 && [self isRedirectTransitionForItemAtIndex:index]) {
671 --index; 675 --index;
672 } 676 }
673 return [_entries objectAtIndex:index]; 677 return [_entries objectAtIndex:index];
674 } 678 }
675 679
676 - (void)useDesktopUserAgentForNextPendingItem {
677 if (_pendingEntry)
678 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true);
679 else
680 _useDesktopUserAgentForNextPendingItem = YES;
681 }
682
683 - (NSInteger)indexOfItem:(const web::NavigationItem*)item { 680 - (NSInteger)indexOfItem:(const web::NavigationItem*)item {
684 web::NavigationItemList items = self.items; 681 web::NavigationItemList items = self.items;
685 for (NSInteger i = 0; i < static_cast<NSInteger>(items.size()); ++i) { 682 for (NSInteger i = 0; i < static_cast<NSInteger>(items.size()); ++i) {
686 if (items[i] == item) 683 if (items[i] == item)
687 return i; 684 return i;
688 } 685 }
689 return NSNotFound; 686 return NSNotFound;
690 } 687 }
691 688
692 #pragma mark - 689 #pragma mark -
693 #pragma mark Private methods 690 #pragma mark Private methods
694 691
695 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url 692 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url
696 referrer:(const web::Referrer&)referrer 693 referrer:(const web::Referrer&)referrer
697 transition:(ui::PageTransition)transition 694 transition:(ui::PageTransition)transition
698 useDesktopUserAgent:(BOOL)useDesktopUserAgent 695 initiationType:
699 rendererInitiated:(BOOL)rendererInitiated { 696 (web::NavigationInitiationType)initiationType {
700 GURL loaded_url(url); 697 GURL loaded_url(url);
701 BOOL urlWasRewritten = NO; 698 BOOL urlWasRewritten = NO;
702 if (_navigationManager) { 699 if (_navigationManager) {
703 std::unique_ptr<std::vector<web::BrowserURLRewriter::URLRewriter>> 700 std::unique_ptr<std::vector<web::BrowserURLRewriter::URLRewriter>>
704 transientRewriters = _navigationManager->GetTransientURLRewriters(); 701 transientRewriters = _navigationManager->GetTransientURLRewriters();
705 if (transientRewriters) { 702 if (transientRewriters) {
706 urlWasRewritten = web::BrowserURLRewriter::RewriteURLWithWriters( 703 urlWasRewritten = web::BrowserURLRewriter::RewriteURLWithWriters(
707 &loaded_url, _browserState, *transientRewriters.get()); 704 &loaded_url, _browserState, *transientRewriters.get());
708 } 705 }
709 } 706 }
710 if (!urlWasRewritten) { 707 if (!urlWasRewritten) {
711 web::BrowserURLRewriter::GetInstance()->RewriteURLIfNecessary( 708 web::BrowserURLRewriter::GetInstance()->RewriteURLIfNecessary(
712 &loaded_url, _browserState); 709 &loaded_url, _browserState);
713 } 710 }
711
714 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); 712 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl());
715 item->SetOriginalRequestURL(loaded_url); 713 item->SetOriginalRequestURL(loaded_url);
716 item->SetURL(loaded_url); 714 item->SetURL(loaded_url);
717 item->SetReferrer(referrer); 715 item->SetReferrer(referrer);
718 item->SetTransitionType(transition); 716 item->SetTransitionType(transition);
719 item->SetIsOverridingUserAgent(useDesktopUserAgent); 717 item->SetNavigationInitiationType(initiationType);
720 item->set_is_renderer_initiated(rendererInitiated);
721 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; 718 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)];
722 } 719 }
723 720
724 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index { 721 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index {
725 ui::PageTransition transition = 722 ui::PageTransition transition =
726 [_entries[index] navigationItem]->GetTransitionType(); 723 [_entries[index] navigationItem]->GetTransitionType();
727 return (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) ? YES : NO; 724 return (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) ? YES : NO;
728 } 725 }
729 726
730 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries { 727 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries {
731 web::NavigationItemList list(entries.count); 728 web::NavigationItemList list(entries.count);
732 for (size_t index = 0; index < entries.count; ++index) 729 for (size_t index = 0; index < entries.count; ++index)
733 list[index] = [entries[index] navigationItem]; 730 list[index] = [entries[index] navigationItem];
734 return list; 731 return list;
735 } 732 }
736 733
737 @end 734 @end
OLDNEW
« no previous file with comments | « ios/web/navigation/crw_session_controller.h ('k') | ios/web/navigation/crw_session_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698