[M120 Migration]URL of _Ewk_Error set wrong
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / browser / navigation_throttle_efl.cc
1 // Copyright 2019 Samsung Electronics. 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 #include "browser/navigation_throttle_efl.h"
6
7 #include "base/functional/bind.h"
8 #include "common/navigation_policy_params.h"
9 #include "common/web_contents_utils.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/navigation_handle.h"
12 #include "eweb_view.h"
13 #include "third_party/blink/public/platform/web_string.h"
14 #include "third_party/blink/public/web/web_navigation_type.h"
15
16 #if BUILDFLAG(IS_TIZEN_TV)
17 #include "common/application_type.h"
18 #endif
19
20 namespace content {
21
22 static blink::WebNavigationType GetNavigationTypeFromPageTransition(
23     const ui::PageTransition& transition,
24     bool is_reload) {
25   switch (ui::PageTransitionStripQualifier(transition)) {
26     case ui::PAGE_TRANSITION_LINK:
27       if (transition & ui::PAGE_TRANSITION_FORWARD_BACK)
28         return blink::kWebNavigationTypeBackForward;
29       if (transition & ui::PAGE_TRANSITION_FROM_API)
30         return blink::kWebNavigationTypeOther;
31       return blink::kWebNavigationTypeLinkClicked;
32     case ui::PAGE_TRANSITION_FORM_SUBMIT:
33       return ((transition & ui::PAGE_TRANSITION_FORWARD_BACK) || is_reload)
34                  ? blink::kWebNavigationTypeFormResubmittedBackForward
35                  : blink::kWebNavigationTypeFormSubmitted;
36     case ui::PAGE_TRANSITION_RELOAD:
37       return blink::kWebNavigationTypeReload;
38     default:
39       return blink::kWebNavigationTypeOther;
40   }
41   NOTREACHED();
42   return blink::kWebNavigationTypeOther;
43 }
44
45 NavigationThrottleEfl::NavigationThrottleEfl(
46     NavigationHandle* navigation_handle)
47     : NavigationThrottle(navigation_handle), weak_factory_(this) {}
48
49 NavigationThrottleEfl::~NavigationThrottleEfl() = default;
50
51 NavigationThrottle::ThrottleCheckResult
52 NavigationThrottleEfl::WillStartRequest() {
53   return HandleNavigation(false /* is_redirect */);
54 }
55
56 NavigationThrottle::ThrottleCheckResult
57 NavigationThrottleEfl::WillRedirectRequest() {
58   return HandleNavigation(true /* is_redirect */);
59 }
60
61 NavigationThrottle::ThrottleCheckResult
62 NavigationThrottleEfl::WillFailRequest() {
63   auto* handle = navigation_handle();
64   auto* web_view =
65       web_contents_utils::WebViewFromWebContents(handle->GetWebContents());
66   if (handle->IsInMainFrame() && web_view) {
67     int error_code = handle->GetNetErrorCode();
68     web_view->InvokeLoadError(handle->GetURL(), error_code,
69                               error_code == net::ERR_ABORTED);
70     // If app invoke load error page callback, means app want to display error
71     // page by itself. Provide detail error info and get customer error page
72     // from app side.
73     if (web_view->IsLoadErrorPageCallbackSet()) {
74       const char* error_page = web_view->InvokeViewLoadErrorPageCallback(
75           handle->GetURL(), error_code, error_code == net::ERR_ABORTED);
76       if (error_page) {
77         LOG(ERROR) << "Already get customer error page";
78         // Currently return result with action NavigationThrottle::CANCEL, error
79         // code and error_page.
80         // TODO: Consider NavigationThrottle::CANCEL is suitable in here or not.
81         return content::NavigationThrottle::ThrottleCheckResult(
82             content::NavigationThrottle::CANCEL, handle->GetNetErrorCode(),
83             absl::make_optional(error_page));
84       }
85     }
86 #if BUILDFLAG(IS_TIZEN_TV)
87     // In VD tizen, WebBrowser will load error page by itself.
88     if (IsWebBrowser())
89       return NavigationThrottle::CANCEL_AND_IGNORE;
90 #endif
91   }
92   return NavigationThrottle::PROCEED;
93 }
94
95 const char* NavigationThrottleEfl::GetNameForLogging() {
96   return "NavigationThrottleEfl";
97 }
98
99 NavigationThrottle::ThrottleCheckResult NavigationThrottleEfl::HandleNavigation(
100     bool is_redirect) {
101 #if BUILDFLAG(IS_TIZEN_TV)
102   if ((IsTIZENWRT() && navigation_handle()->GetURL().SchemeIsFileSystem()) ||
103       navigation_handle()->GetURL().SchemeIs(url::kDataScheme))
104     return NavigationThrottle::PROCEED;
105 #endif
106   if (ShouldHandleAsyncronously()) {
107     GetUIThreadTaskRunner({})->PostTask(
108         FROM_HERE, base::BindOnce(&NavigationThrottleEfl::HandleNavigationAsync,
109                                   weak_factory_.GetWeakPtr(),
110                                   GetNavigationPolicyParams(is_redirect)));
111     return NavigationThrottle::DEFER;
112   }
113   return HandleNavigationImpl(GetNavigationPolicyParams(is_redirect))
114              ? NavigationThrottle::CANCEL_AND_IGNORE
115              : NavigationThrottle::PROCEED;
116 }
117
118 void NavigationThrottleEfl::HandleNavigationAsync(
119     const NavigationPolicyParams& params) {
120   if (HandleNavigationImpl(params))
121     CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
122   else
123     Resume();
124 }
125
126 bool NavigationThrottleEfl::HandleNavigationImpl(
127     const NavigationPolicyParams& params) {
128   auto* web_view = web_contents_utils::WebViewFromWebContents(
129       navigation_handle()->GetWebContents());
130   if (!web_view)
131     return false;
132
133   bool handled = false;
134   web_view->InvokePolicyNavigationCallback(params, &handled);
135   return handled;
136 }
137
138 bool NavigationThrottleEfl::ShouldHandleAsyncronously() const {
139   // Ported from InterceptNavigationThrottle::ShouldCheckAsynchronously,
140   // see components/navigation_interception/intercept_navigation_throttle.cc
141   //
142   // Do not apply the async optimization for:
143   // - POST navigations, to ensure we aren't violating idempotency.
144   // - Subframe navigations, which aren't observed on Android, and should be
145   //   fast on other platforms.
146   // - non-http/s URLs, which are more likely to be intercepted.
147   return navigation_handle()->IsInMainFrame() &&
148          !navigation_handle()->IsPost() &&
149          navigation_handle()->GetURL().SchemeIsHTTPOrHTTPS();
150 }
151
152 NavigationPolicyParams NavigationThrottleEfl::GetNavigationPolicyParams(
153     bool is_redirect) const {
154   auto* handle = navigation_handle();
155   NavigationPolicyParams params;
156
157   params.url = handle->GetURL();
158   params.httpMethod = handle->IsPost() ? "POST" : "GET";
159   params.type = GetNavigationTypeFromPageTransition(
160       handle->GetPageTransition(), handle->GetReloadType() != ReloadType::NONE);
161   std::string auth;
162   handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kAuthorization,
163                                         &auth);
164   params.auth = blink::WebString::FromUTF8(auth);
165   std::string cookie;
166   handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kCookie,
167                                         &cookie);
168   params.cookie = cookie;
169   params.should_replace_current_entry = handle->DidReplaceEntry();
170   params.is_main_frame = handle->IsInMainFrame();
171   params.is_redirect = is_redirect;
172
173   return params;
174 }
175
176 }  // namespace content