/// <summary> /// On failure check if we need to reauthenticate and try again /// </summary> /// <param name="ye">The WebException that occured</param> /// <returns>Whether we should retry the request</returns> private async Task <bool> TryReauthenticationAsync(YouMailException ye, bool fForce) { bool fTryAgain = false; // If we get a forbidden response, then we might need to try again if (fForce || ye.StatusCode == HttpStatusCode.Forbidden) { // Only one client tries to re-authenticate if (0 == Interlocked.CompareExchange(ref _fHadTriedAuthentication, 1, 0)) { TraceLog(TraceLevelPriority.High, "Reauthenticating"); try { await PrivateLoginAsync().ConfigureAwait(false); } catch { // We didn't login, remove the auth token. AuthToken = null; _authenticationFailed = true; throw; } finally { // Set the event for other clients to start working... _authEvent.Set(); } } else { TraceLog(TraceLevelPriority.Normal, "Reauthentication in progress, waiting...."); // Wait until we have a new authentication token. await _authEvent.WaitOneAsync(); } fTryAgain = true; } return(fTryAgain); }
/// <summary> /// Get the data for the message /// </summary> /// <param name="URL"></param> /// <returns></returns> public async Task <Stream> GetMessageDataAsync(string URL) { Stream returnValue = null; bool fRetry = false; YouMailException weRetry = null; HttpResponseMessage response = null; try { AddPendingOp(); if (await LoginWaitAsync()) { try { if (IsConnected) { response = await GetMessageDownloadResponseAsync(URL); EnsureYouMailResponse(response); } } catch (WebException we) { weRetry = ConvertException(we); if (weRetry != null) { if (weRetry.StatusCode == HttpStatusCode.Forbidden) { fRetry = true; } else { throw weRetry; } } else { throw; } } catch (YouMailException re) { weRetry = re; if (weRetry.StatusCode == HttpStatusCode.Forbidden) { fRetry = true; } else { throw; } } if (fRetry) { if (await TryReauthenticationAsync(weRetry, false)) { TraceLog(TraceLevelPriority.Normal, "Getting message: {0}", URL); response = await GetMessageDownloadResponseAsync(URL); } } returnValue = response.GetResponseStream(); } return(returnValue); } finally { RemovePendingOp(); } }
/// <summary> /// Call a YouMail API /// </summary> /// <param name="URL">The Url for the API</param> /// <param name="data">optional data string to give as an HTTP POST or PUT</param> /// <param name="verb">Specify the verb to use for the WebRequest</param> /// <returns>an HttpWebResponse to the API</returns> protected async Task <HttpResponseMessage> YouMailApiAsync( string URL, HttpContent data, HttpMethod verb, bool auth = true, IList <KeyValuePair <string, string> > extraHeaders = null, string forceProtocol = null) { #if WINDOWS_UWP if (!IsConnected) { await LogApiCallAsync(URL, data, verb, auth); return(null); } #endif bool fForce = false; bool fRetryAuthentication = false; YouMailException weRetry = null; HttpResponseMessage response = null; if (!auth || !string.IsNullOrEmpty(_auth)) { try { bool redirect; do { redirect = false; response = await CreateYouMailApiResponseAsync(URL, data, verb, auth, extraHeaders, forceProtocol).ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.MovedPermanently || response.StatusCode == HttpStatusCode.Redirect || response.StatusCode == HttpStatusCode.RedirectKeepVerb) { // Grab the queryString from the previous URL and copy it over string queryString = string.Empty; int queryStringndex = URL.IndexOf('?'); if (queryStringndex > 0) { queryString = URL.Substring(queryStringndex); } URL = response.Headers.Location.ToString() + queryString; // The protocol should be part of the URL now, so send an empty one. forceProtocol = string.Empty; redirect = true; } }while (redirect); EnsureYouMailResponse(response); } catch (WebException we) { YouMailException yme = ConvertException(we); if (yme != null) { if (yme.StatusCode == HttpStatusCode.Forbidden && auth) { weRetry = yme; fRetryAuthentication = true; } else { throw yme; } } else { throw; } } catch (YouMailException re) { if (re.StatusCode == HttpStatusCode.Forbidden && auth) { weRetry = re; fRetryAuthentication = true; } else { throw; } } } else { fForce = fRetryAuthentication = true; } if (fRetryAuthentication && auth) { if (await TryReauthenticationAsync(weRetry, fForce).ConfigureAwait(false)) { try { // We can retry the request now bool redirect; do { redirect = false; response = await CreateYouMailApiResponseAsync(URL, data, verb, auth, extraHeaders, forceProtocol).ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.MovedPermanently || response.StatusCode == HttpStatusCode.Redirect || response.StatusCode == HttpStatusCode.RedirectKeepVerb) { URL = response.Headers.Location.ToString(); // The protocol should be part of the URL now, so send an empty one. forceProtocol = string.Empty; redirect = true; } }while (redirect); EnsureYouMailResponse(response); } catch (WebException we) { // Convert the WebException to a YouMailException var yme = ConvertException(we); if (yme != null) { throw yme; } throw we; } } } return(response); }