This patch adds internal APIs to support request intercept.
Plus, adds APIs for remote inspect.
Signed-off-by: yh106.jung <yh106.jung@samsung.com>
[DllImport(Libraries.ChromiumEwk)]
internal static extern void ewk_context_notify_low_memory(IntPtr context);
-
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void DownloadStartCallback(string url, IntPtr userData);
[DllImport(Libraries.ChromiumEwk)]
internal static extern void ewk_context_did_start_download_callback_set(IntPtr context, DownloadStartCallback callback, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InterceptRequestCallback(IntPtr context, IntPtr request, IntPtr userData);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern void ewk_context_intercept_request_callback_set(IntPtr context, InterceptRequestCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ internal static extern uint ewk_context_inspector_server_start(IntPtr context, uint port);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_context_inspector_server_stop(IntPtr context);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ChromiumEwk
+ {
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal static extern bool ewk_intercept_request_ignore(IntPtr request);
+
+ [DllImport(Libraries.ChromiumEwk)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ internal unsafe static extern bool ewk_intercept_request_response_set(IntPtr request, string headers, byte* body, uint length);
+
+ [DllImport(Libraries.ChromiumEwk, EntryPoint = "ewk_intercept_request_url_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr _ewk_intercept_request_url_get(IntPtr request);
+
+ internal static string ewk_intercept_request_url_get(IntPtr request)
+ {
+ IntPtr ptr = _ewk_intercept_request_url_get(request);
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ }
+}
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElmSharp", "..\ElmSharp\ElmSharp.csproj", "{2F66C9E2-BE24-4096-96DA-F86CCFBBB059}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{B1B8B7CA-5E39-42BA-90EF-4F4DDA51F37C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{7C6A8E2F-7DF0-4994-8230-FB1234F3DF4C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
{2F66C9E2-BE24-4096-96DA-F86CCFBBB059}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F66C9E2-BE24-4096-96DA-F86CCFBBB059}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F66C9E2-BE24-4096-96DA-F86CCFBBB059}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1B8B7CA-5E39-42BA-90EF-4F4DDA51F37C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1B8B7CA-5E39-42BA-90EF-4F4DDA51F37C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1B8B7CA-5E39-42BA-90EF-4F4DDA51F37C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1B8B7CA-5E39-42BA-90EF-4F4DDA51F37C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C6A8E2F-7DF0-4994-8230-FB1234F3DF4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C6A8E2F-7DF0-4994-8230-FB1234F3DF4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C6A8E2F-7DF0-4994-8230-FB1234F3DF4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C6A8E2F-7DF0-4994-8230-FB1234F3DF4C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D2305D88-057A-4565-9162-906A79DEF26B}
+ EndGlobalSection
EndGlobal
private CookieManager _cookieManager;
private Interop.ChromiumEwk.DownloadStartCallback _downloadStartCallback;
-
+ private Interop.ChromiumEwk.InterceptRequestCallback _interceptRequestCallback;
+
/// <summary>
/// The delegate for handling download request.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public delegate void DownloadRequestDelegate(string url);
+ /// <summary>
+ /// The delegate for intercepting and handling a resource request.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ /// <param name="interceptor"> The object which can handle a intercepted request. </param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public delegate void InterceptRequestDelegate(RequestInterceptor interceptor);
+
internal Context(IntPtr handle)
{
_handle = handle;
};
Interop.ChromiumEwk.ewk_context_did_start_download_callback_set(_handle, _downloadStartCallback, IntPtr.Zero);
}
+
+ /// <summary>
+ /// Sets the delegate function for intercepting a resource request.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ /// <param name="interceptRequestCb"> The delegate function for intercepting a resource request. </param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void SetInterceptRequestDelegate(InterceptRequestDelegate interceptRequestCb)
+ {
+ _interceptRequestCallback = (IntPtr context, IntPtr request, IntPtr userData) =>
+ {
+ interceptRequestCb(new RequestInterceptor(request));
+ };
+ Interop.ChromiumEwk.ewk_context_intercept_request_callback_set(_handle, _interceptRequestCallback, IntPtr.Zero);
+
+ }
+
+ /// <summary>
+ /// Starts the inspector server.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ /// <param name="port"> The port number. </param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public uint StartInspectorServer(uint port)
+ {
+ return Interop.ChromiumEwk.ewk_context_inspector_server_start(_handle, port);
+ }
+
+ /// <summary>
+ /// Stops the inspector server.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void StopInspectorServer()
+ {
+ Interop.ChromiumEwk.ewk_context_inspector_server_stop(_handle);
+ }
}
}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Text;
+
+namespace Tizen.WebView
+{
+ /// <summary>
+ /// This class provides methods and properties to handle a interpected request.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class RequestInterceptor {
+ private const string ResponseHeaderTemplate =
+ "HTTP/1.1 {0} {1}\r\n" +
+ "Content-Type: {2}; charset={3}\r\n" +
+ "Content-Length: {4}\r\n";
+
+ private IntPtr _handle;
+
+ internal RequestInterceptor(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// The URL of the request.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Uri Url
+ {
+ get
+ {
+ return new Uri(Interop.ChromiumEwk.ewk_intercept_request_url_get(_handle));
+ }
+ }
+
+ /// <summary>
+ /// Sets headers and data for the response.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ /// <param name="mimeType"> Response's mime type. </param>
+ /// <param name="encoding"> Response's character encoding. </param>
+ /// <param name="statusCode"> HTTP response status code. </param>
+ /// <param name="reasonPhrase"> HTTP response reason phrase. </param>
+ /// <param name="responseHeaders"> Headers Map from HTTP header field names to field values. </param>
+ /// <param name="data"> The streiam that provides the response's data. </param>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="data"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when the native operation failed to set response.</exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void SetResponse(string mimeType, string encoding, int statusCode, string reasonPhrase, IDictionary<string, string> responseHeaders, Stream data)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException(nameof(data));
+ }
+
+ byte[] body;
+ using (MemoryStream ms = new MemoryStream())
+ {
+ data.CopyTo(ms);
+ body = ms.ToArray();
+
+ var headers = String.Format(ResponseHeaderTemplate, statusCode, reasonPhrase, mimeType, encoding, body.Length);
+ if (responseHeaders != null)
+ {
+ foreach(var header in responseHeaders)
+ {
+ headers += $"{header.Key}: {header.Value}\r\n";
+ }
+ }
+ headers += "\r\n";
+
+ unsafe
+ {
+ fixed (byte* bodyPtr = body)
+ {
+ var ret = Interop.ChromiumEwk.ewk_intercept_request_response_set(_handle, headers, bodyPtr, (uint)body.Length);
+ if (!ret)
+ {
+ throw new InvalidOperationException("Failed to set response.");
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Ignores the request, so WebView will load it.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Ignore()
+ {
+ Interop.ChromiumEwk.ewk_intercept_request_ignore(_handle);
+ }
+ }
+}