/// <summary>
/// Executing API calls
/// </summary>
/// <param name="payLoad"></param>
/// <param name="httpRequest"></param>
/// <returns>A string containing the response from the remote host.</returns>
public string Execute(string payLoad, HttpWebRequest httpRequest)
{
int retriesConfigured = config.ContainsKey(BaseConstants.HttpConnectionRetryConfig) ?
Convert.ToInt32(config[BaseConstants.HttpConnectionRetryConfig]) : 0;
int retries = 0;
// Reset the request & response details
this.RequestDetails.Reset();
this.ResponseDetails.Reset();
// Store the request details
this.RequestDetails.Body = payLoad;
this.RequestDetails.Headers = httpRequest.Headers;
this.RequestDetails.Url = httpRequest.RequestUri.AbsoluteUri;
this.RequestDetails.Method = httpRequest.Method;
try
{
do
{
if (retries > 0)
{
logger.Info("Retrying....");
httpRequest = CopyRequest(httpRequest, config, httpRequest.RequestUri.ToString());
this.RequestDetails.RetryAttempts++;
}
try
{
switch (httpRequest.Method)
{
case "POST":
case "PUT":
case "PATCH":
using (StreamWriter writerStream = new StreamWriter(httpRequest.GetRequestStream()))
{
writerStream.Write(payLoad);
writerStream.Flush();
writerStream.Close();
if (ConfigManager.IsLiveModeEnabled(config))
{
logger.Debug("Request details are hidden in live mode.");
}
else
{
logger.Debug(payLoad);
}
}
break;
default:
break;
}
using (WebResponse responseWeb = httpRequest.GetResponse())
{
// Store the response information
this.ResponseDetails.Headers = responseWeb.Headers;
if (responseWeb is HttpWebResponse)
{
this.ResponseDetails.StatusCode = ((HttpWebResponse)responseWeb).StatusCode;
}
using (StreamReader readerStream = new StreamReader(responseWeb.GetResponseStream()))
{
this.ResponseDetails.Body = readerStream.ReadToEnd().Trim();
if (ConfigManager.IsLiveModeEnabled(config))
{
logger.Debug("Response details are hidden in live mode.");
}
else
{
logger.Debug("Service response: ");
logger.Debug(this.ResponseDetails.Body);
}
return(this.ResponseDetails.Body);
}
}
}
catch (WebException ex)
{
// If provided, get and log the response from the remote host.
var response = string.Empty;
if (ex.Response != null)
{
using (var readerStream = new StreamReader(ex.Response.GetResponseStream()))
{
response = readerStream.ReadToEnd().Trim();
logger.Error("Error response:");
logger.Error(response);
}
}
logger.Error(ex.Message);
ConnectionException rethrowEx = null;
// Protocol errors indicate the remote host received the
// request, but responded with an error (usually a 4xx or
// 5xx error).
if (ex.Status == WebExceptionStatus.ProtocolError)
{
var httpWebResponse = (HttpWebResponse)ex.Response;
// If the HTTP status code is flagged as one where we
// should continue retrying, then ignore the exception
// and continue with the retry attempt.
if (httpWebResponse.StatusCode == HttpStatusCode.GatewayTimeout ||
httpWebResponse.StatusCode == HttpStatusCode.RequestTimeout ||
httpWebResponse.StatusCode == HttpStatusCode.BadGateway)
{
continue;
}
rethrowEx = new HttpException(ex.Message, response, httpWebResponse.StatusCode, ex.Status, httpWebResponse.Headers, httpRequest);
}
else if (ex.Status == WebExceptionStatus.ReceiveFailure ||
ex.Status == WebExceptionStatus.ConnectFailure ||
ex.Status == WebExceptionStatus.KeepAliveFailure)
{
logger.Debug("There was a problem connecting to the server: " + ex.Status.ToString());
continue;
}
else if (ex.Status == WebExceptionStatus.Timeout)
{
// For connection timeout errors, include the connection timeout value that was used.
var message = string.Format("{0} (HTTP request timeout was set to {1}ms)", ex.Message, httpRequest.Timeout);
rethrowEx = new ConnectionException(message, response, ex.Status, httpRequest);
}
else
{
// Non-protocol errors indicate something happened with the underlying connection to the server.
rethrowEx = new ConnectionException("Invalid HTTP response: " + ex.Message, response, ex.Status, httpRequest);
}
if (ex.Response != null && ex.Response is HttpWebResponse)
{
var httpWebResponse = ex.Response as HttpWebResponse;
this.ResponseDetails.StatusCode = httpWebResponse.StatusCode;
this.ResponseDetails.Headers = httpWebResponse.Headers;
}
this.ResponseDetails.Exception = rethrowEx;
throw rethrowEx;
}
} while (retries++ < retriesConfigured);
}
catch (PayPalException)
{
// Rethrow any PayPalExceptions since they already contain the
// details of the exception.
throw;
}
catch (System.Exception ex)
{
// Repackage any other exceptions to give a bit more context to
// the caller.
throw new PayPalException("Exception in PayPal.HttpConnection.Execute(): " + ex.Message, ex);
}
// If we've gotten this far, it means all attempts at sending the
// request resulted in a failed attempt.
throw new PayPalException("Retried " + retriesConfigured + " times.... Exception in PayPal.HttpConnection.Execute(). Check log for more details.");
}