Commit 8e2d4d4e authored by Jason Williams's avatar Jason Williams
Browse files

Refresh CSRF tokens and retry when we have issues

If you reboot a device the CSRF token could change and you need to issue a GET before issuing your POST/PUT/DELETE.

Also, POST/PUT/DELETE can set a new CSRF token which we didn't account for previously.
parent c064be9b
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -26,9 +26,10 @@ namespace Microsoft.Tools.WindowsDevicePortal
        /// Submits the http delete request to the specified uri.
        /// </summary>
        /// <param name="uri">The uri to which the delete request will be issued.</param>
        /// <param name="allowRetry">Allow the Post to be retried after issuing a Get call. Currently used for CSRF failures.</param>
        /// <returns>Task tracking HTTP completion</returns>
#pragma warning disable 1998
        private async Task<Stream> Delete(Uri uri)
        private async Task<Stream> Delete(Uri uri, bool allowRetry = true)
        {
            IBuffer dataBuffer = null;

@@ -56,9 +57,19 @@ namespace Microsoft.Tools.WindowsDevicePortal
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        // If this isn't a retry and it failed due to a bad CSRF
                        // token, issue a GET to refresh the token and then retry.
                        if (allowRetry && response.StatusCode == HttpStatusCode.Forbidden && response.ReasonPhrase.Equals("CSRF Token Invalid"))
                        {
                            await this.GetOperatingSystemInformation();
                            return await this.Delete(uri, false);
                        }

                        throw new DevicePortalException(response);
                    }

                    this.RetrieveCsrfToken(response);

                    if (response.Content != null)
                    {
                        using (IHttpContent messageContent = response.Content)
+13 −1
Original line number Diff line number Diff line
@@ -28,12 +28,14 @@ namespace Microsoft.Tools.WindowsDevicePortal
        /// <param name="uri">The uri to which the post request will be issued.</param>
        /// <param name="requestStream">Optional stream containing data for the request body.</param>
        /// <param name="requestStreamContentType">The type of that request body data.</param>
        /// <param name="allowRetry">Allow the Post to be retried after issuing a Get call. Currently used for CSRF failures.</param>
        /// <returns>Task tracking the completion of the POST request</returns>
#pragma warning disable 1998
        private async Task<Stream> Post(
            Uri uri,
            Stream requestStream = null,
            string requestStreamContentType = null)
            string requestStreamContentType = null,
            bool allowRetry = true)
        {
            HttpStreamContent requestContent = null;
            IBuffer dataBuffer = null;
@@ -69,9 +71,19 @@ namespace Microsoft.Tools.WindowsDevicePortal
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        // If this isn't a retry and it failed due to a bad CSRF
                        // token, issue a GET to refresh the token and then retry.
                        if (allowRetry && response.StatusCode == HttpStatusCode.Forbidden && response.ReasonPhrase.Equals("CSRF Token Invalid"))
                        {
                            await this.GetOperatingSystemInformation();
                            return await this.Post(uri, requestStream, requestStreamContentType, false);
                        }

                        throw new DevicePortalException(response);
                    }

                    this.RetrieveCsrfToken(response);

                    if (response.Content != null)
                    {
                        using (IHttpContent messageContent = response.Content)
+13 −1
Original line number Diff line number Diff line
@@ -27,11 +27,13 @@ namespace Microsoft.Tools.WindowsDevicePortal
        /// </summary>
        /// <param name="uri">The uri to which the put request will be issued.</param>
        /// <param name="body">The HTTP content comprising the body of the request.</param>
        /// <param name="allowRetry">Allow the Post to be retried after issuing a Get call. Currently used for CSRF failures.</param>
        /// <returns>Task tracking the PUT completion.</returns>
#pragma warning disable 1998
        private async Task<Stream> Put(
            Uri uri,
            IHttpContent body = null)
            IHttpContent body = null,
            bool allowRetry = true)
        {
            IBuffer dataBuffer = null;

@@ -60,9 +62,19 @@ namespace Microsoft.Tools.WindowsDevicePortal
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        // If this isn't a retry and it failed due to a bad CSRF
                        // token, issue a GET to refresh the token and then retry.
                        if (allowRetry && response.StatusCode == HttpStatusCode.Forbidden && response.ReasonPhrase.Equals("CSRF Token Invalid"))
                        {
                            await this.GetOperatingSystemInformation();
                            return await this.Put(uri, body, false);
                        }

                        throw new DevicePortalException(response);
                    }

                    this.RetrieveCsrfToken(response);

                    if (response.Content != null)
                    {
                        using (IHttpContent messageContent = response.Content)
+13 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

@@ -20,8 +21,9 @@ namespace Microsoft.Tools.WindowsDevicePortal
        /// Submits the http delete request to the specified uri.
        /// </summary>
        /// <param name="uri">The uri to which the delete request will be issued.</param>
        /// <param name="allowRetry">Allow the Post to be retried after issuing a Get call. Currently used for CSRF failures.</param>
        /// <returns>Task tracking HTTP completion</returns>
        private async Task<Stream> Delete(Uri uri)
        private async Task<Stream> Delete(Uri uri, bool allowRetry = true)
        {
            MemoryStream dataStream = null;

@@ -42,9 +44,19 @@ namespace Microsoft.Tools.WindowsDevicePortal
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        // If this isn't a retry and it failed due to a bad CSRF
                        // token, issue a GET to refresh the token and then retry.
                        if (allowRetry && response.StatusCode == HttpStatusCode.Forbidden && response.ReasonPhrase.Equals("CSRF Token Invalid"))
                        {
                            await this.GetOperatingSystemInformation();
                            return await this.Delete(uri, false);
                        }

                        throw new DevicePortalException(response);
                    }

                    this.RetrieveCsrfToken(response);

                    if (response.Content != null)
                    {
                        using (HttpContent content = response.Content)
+14 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

@@ -22,11 +23,13 @@ namespace Microsoft.Tools.WindowsDevicePortal
        /// <param name="uri">The uri to which the post request will be issued.</param>
        /// <param name="requestStream">Optional stream containing data for the request body.</param>
        /// <param name="requestStreamContentType">The type of that request body data.</param>
        /// <param name="allowRetry">Allow the Post to be retried after issuing a Get call. Currently used for CSRF failures.</param>
        /// <returns>Task tracking the completion of the POST request</returns>
        private async Task<Stream> Post(
            Uri uri,
            Stream requestStream = null,
            string requestStreamContentType = null)
            string requestStreamContentType = null,
            bool allowRetry = true)
        {
            StreamContent requestContent = null;
            MemoryStream responseDataStream = null;
@@ -55,9 +58,19 @@ namespace Microsoft.Tools.WindowsDevicePortal
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        // If this isn't a retry and it failed due to a bad CSRF
                        // token, issue a GET to refresh the token and then retry.
                        if (allowRetry && response.StatusCode == HttpStatusCode.Forbidden && response.ReasonPhrase.Equals("CSRF Token Invalid"))
                        {
                            await this.GetOperatingSystemInformation();
                            return await this.Post(uri, requestStream, requestStreamContentType, false);
                        }

                        throw new DevicePortalException(response);
                    }

                    this.RetrieveCsrfToken(response);

                    if (response.Content != null)
                    {
                        using (HttpContent responseContent = response.Content)
Loading