cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From victo...@apache.org
Subject [1/2] cordova-plugin-file-transfer git commit: CB-8761 [wp8]: Copy cookies from WebBrowser
Date Tue, 28 Apr 2015 00:18:01 GMT
Repository: cordova-plugin-file-transfer
Updated Branches:
  refs/heads/CB-8860cordova-plugin-file-transfer dfd2c4514 -> 4f7e1566b


CB-8761 [wp8]: Copy cookies from WebBrowser

On other platforms, the cookies from the browser that apply to the
request are automatically included. On WP8, that's not the case.

This commit will copy the cookies from the WebBrowser control, if the
scheme and host of the WebBrowser match that of the HttpWebRequest. For
users who host their web components remotely, and perform
uploads/downloads from the same server using cookie based
authentication, this fix enables that scenario on WP8, and brings it up
to parity with iOS, Android, and others.

Fixes https://issues.apache.org/jira/browse/CB-8761

CB-8761 [wp8]: Cleanup per comments

github close #74


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/commit/75d55dda
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/tree/75d55dda
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/diff/75d55dda

Branch: refs/heads/CB-8860cordova-plugin-file-transfer
Commit: 75d55ddaaa184f8d48b3ecaf2071fe858596359c
Parents: dfd2c45
Author: Dan Polivy <dan@cellartracker.com>
Authored: Fri Mar 27 00:19:56 2015 -0700
Committer: sgrebnov <v-segreb@microsoft.com>
Committed: Sat Apr 25 15:03:23 2015 -0700

----------------------------------------------------------------------
 src/wp/FileTransfer.cs | 92 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/75d55dda/src/wp/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/src/wp/FileTransfer.cs b/src/wp/FileTransfer.cs
index 1ddfc28..e1f9fb0 100644
--- a/src/wp/FileTransfer.cs
+++ b/src/wp/FileTransfer.cs
@@ -12,6 +12,7 @@
 	limitations under the License.
 */
 
+using Microsoft.Phone.Controls;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -21,6 +22,7 @@ using System.Runtime.Serialization;
 using System.Windows;
 using System.Security;
 using System.Diagnostics;
+using System.Threading.Tasks;
 
 namespace WPCordovaClassLib.Cordova.Commands
 {
@@ -86,6 +88,10 @@ namespace WPCordovaClassLib.Cordova.Commands
 
         private static Dictionary<string, DownloadRequestState> InProcDownloads = new
Dictionary<string,DownloadRequestState>();
 
+        // Private instance of the main WebBrowser instance
+        // NOTE: Any access to this object needs to occur on the UI thread via the Dispatcher
+        private WebBrowser browser;
+
         /// <summary>
         /// Uploading response info
         /// </summary>
@@ -210,6 +216,80 @@ namespace WPCordovaClassLib.Cordova.Commands
         }
 
         /// <summary>
+        /// Helper method to copy all relevant cookies from the WebBrowser control into a
header on
+        /// the HttpWebRequest
+        /// </summary>
+        /// <param name="browser">The source browser to copy the cookies from</param>
+        /// <param name="webRequest">The destination HttpWebRequest to add the cookie
header to</param>
+        /// <returns>Nothing</returns>
+        private async Task CopyCookiesFromWebBrowser(HttpWebRequest webRequest)
+        {
+            var tcs = new TaskCompletionSource<object>();
+
+            // Accessing WebBrowser needs to happen on the UI thread
+            Deployment.Current.Dispatcher.BeginInvoke(() =>
+            {
+                // Get the WebBrowser control
+                if (this.browser == null)
+                {
+                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+                    if (frame != null)
+                    {
+                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+                        if (page != null)
+                        {
+                            CordovaView cView = page.FindName("CordovaView") as CordovaView;
+                            if (cView != null)
+                            {
+                                this.browser = cView.Browser;
+                            }
+                        }
+                    }
+                }
+
+                try
+                {
+                    // Only copy the cookies if the scheme and host match (to avoid any issues
with secure/insecure cookies)
+                    // NOTE: since the returned CookieCollection appears to munge the original
cookie's domain value in favor of the actual Source domain,
+                    // we can't know for sure whether the cookies would be applicable to
any other hosts, so best to play it safe and skip for now.
+                    if (this.browser != null && this.browser.Source.IsAbsoluteUri
== true &&
+                        this.browser.Source.Scheme == webRequest.RequestUri.Scheme &&
this.browser.Source.Host == webRequest.RequestUri.Host)
+                    {
+                        string cookieHeader = "";
+                        string requestPath = webRequest.RequestUri.PathAndQuery;
+                        CookieCollection cookies = this.browser.GetCookies();
+
+                        // Iterate over the cookies and add to the header
+                        foreach (Cookie cookie in cookies)
+                        {
+                            // Check that the path is allowed, first
+                            // NOTE: Path always seems to be empty for now, even if the cookie
has a path set by the server.
+                            if (cookie.Path.Length == 0 || requestPath.IndexOf(cookie.Path,
StringComparison.InvariantCultureIgnoreCase) == 0)
+                            {
+                                cookieHeader += cookie.Name + "=" + cookie.Value + "; ";
+                            }
+                        }
+
+                        // Finally, set the header if we found any cookies
+                        if (cookieHeader.Length > 0)
+                        {
+                            webRequest.Headers["Cookie"] = cookieHeader;
+                        }
+                    }
+                }
+                catch (Exception)
+                {
+                    // Swallow the exception
+                }
+
+                // Complete the task
+                tcs.SetResult(Type.Missing);
+            });
+
+            await tcs.Task;
+        }
+
+        /// <summary>
         /// Upload options
         /// </summary>
         //private TransferOptions uploadOptions;
@@ -224,7 +304,7 @@ namespace WPCordovaClassLib.Cordova.Commands
         /// </summary>
         /// <param name="options">Upload options</param>
         /// exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName,
mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-        public void upload(string options)
+        public async void upload(string options)
         {
             options = options.Replace("{}", ""); // empty objects screw up the Deserializer
             string callbackId = "";
@@ -283,6 +363,10 @@ namespace WPCordovaClassLib.Cordova.Commands
                 webRequest.ContentType = "multipart/form-data; boundary=" + Boundary;
                 webRequest.Method = uploadOptions.Method;
 
+                // Associate cookies with the request
+                // This is an async call, so we need to await it in order to preserve proper
control flow
+                await CopyCookiesFromWebBrowser(webRequest);
+
                 if (!string.IsNullOrEmpty(uploadOptions.Headers))
                 {
                     Dictionary<string, string> headers = parseHeaders(uploadOptions.Headers);
@@ -341,7 +425,7 @@ namespace WPCordovaClassLib.Cordova.Commands
             return null;
         }
 
-        public void download(string options)
+        public async void download(string options)
         {
             TransferOptions downloadOptions = null;
             HttpWebRequest webRequest = null;
@@ -475,6 +559,10 @@ namespace WPCordovaClassLib.Cordova.Commands
                 state.request = webRequest;
                 InProcDownloads[downloadOptions.Id] = state;
 
+                // Associate cookies with the request
+                // This is an async call, so we need to await it in order to preserve proper
control flow
+                await CopyCookiesFromWebBrowser(webRequest);
+
                 if (!string.IsNullOrEmpty(downloadOptions.Headers))
                 {
                     Dictionary<string, string> headers = parseHeaders(downloadOptions.Headers);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message