Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 7c67530

Browse files
committed
Convert StripeGateway to use HttpClient
1 parent c636bb1 commit 7c67530

File tree

1 file changed

+64
-55
lines changed

1 file changed

+64
-55
lines changed

src/Stripe/StripeGateway.cs

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using System.Net;
8+
using System.Net.Http;
9+
using System.Net.Http.Headers;
810
using System.Runtime.Serialization;
911
using System.Text;
1012
using System.Threading;
@@ -815,6 +817,8 @@ public class StripeGateway : IRestGateway
815817
private string stripeAccount;
816818
public ICredentials Credentials { get; set; }
817819
private string UserAgent { get; set; }
820+
821+
public HttpClient Client { get; set; }
818822

819823
public StripeGateway(string apiKey, string publishableKey = null, string stripeAccount = null)
820824
{
@@ -823,92 +827,97 @@ public StripeGateway(string apiKey, string publishableKey = null, string stripeA
823827
this.stripeAccount = stripeAccount;
824828
Credentials = new NetworkCredential(apiKey, "");
825829
Timeout = TimeSpan.FromSeconds(60);
826-
UserAgent = "servicestack .net stripe v1";
830+
UserAgent = "ServiceStack.Stripe";
827831
Currency = Currencies.UnitedStatesDollar;
832+
Client = new HttpClient(new HttpClientHandler {
833+
Credentials = Credentials,
834+
PreAuthenticate = true,
835+
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
836+
}, disposeHandler:true);
828837
JsConfig.InitStatics();
829-
830-
//https://support.stripe.com/questions/how-do-i-upgrade-my-stripe-integration-from-tls-1-0-to-tls-1-2#dotnet
831-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
832838
}
833839

834-
protected virtual void InitRequest(HttpWebRequest req, string method, string idempotencyKey)
840+
private HttpRequestMessage PrepareRequest(string relativeUrl, string method, string requestBody, string idempotencyKey)
835841
{
836-
req.Accept = MimeTypes.Json;
837-
req.Credentials = Credentials;
842+
var url = BaseUrl.CombineWith(relativeUrl);
843+
844+
var httpReq = new HttpRequestMessage(new HttpMethod(method), url);
838845

839-
if (method == HttpMethods.Post || method == HttpMethods.Put)
840-
req.ContentType = MimeTypes.FormUrlEncoded;
846+
httpReq.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, Env.VersionString));
847+
httpReq.Headers.Add(HttpHeaders.Accept, MimeTypes.Json);
841848

842849
if (!string.IsNullOrWhiteSpace(idempotencyKey))
843-
req.Headers["Idempotency-Key"] = idempotencyKey;
850+
httpReq.Headers.Add("Idempotency-Key", idempotencyKey);
844851

845-
req.Headers["Stripe-Version"] = APIVersion;
852+
httpReq.Headers.Add("Stripe-Version", APIVersion);
846853

847-
if(!string.IsNullOrWhiteSpace(stripeAccount))
854+
if (requestBody != null)
848855
{
849-
req.Headers["Stripe-Account"] = stripeAccount;
856+
httpReq.Content = new StringContent(requestBody, Encoding.UTF8);
857+
if (method is HttpMethods.Post or HttpMethods.Put)
858+
httpReq.Content!.Headers.ContentType = new MediaTypeHeaderValue(MimeTypes.FormUrlEncoded);
850859
}
851860

852-
PclExport.Instance.Config(req,
853-
userAgent: UserAgent,
854-
timeout: Timeout,
855-
preAuthenticate: true);
861+
return httpReq;
856862
}
857863

858-
protected virtual void HandleStripeException(WebException ex)
864+
private Exception CreateException(HttpResponseMessage httpRes)
859865
{
860-
string errorBody = ex.GetResponseBody();
861-
var errorStatus = ex.GetStatus() ?? HttpStatusCode.BadRequest;
866+
#if NET6_0_OR_GREATER
867+
return new HttpRequestException(httpRes.ReasonPhrase, null, httpRes.StatusCode);
868+
#else
869+
return new HttpRequestException(httpRes.ReasonPhrase);
870+
#endif
871+
}
862872

863-
if (ex.IsAny400())
873+
protected virtual string Send(string relativeUrl, string method, string requestBody, string idempotencyKey)
874+
{
875+
var httpReq = PrepareRequest(relativeUrl, method, requestBody, idempotencyKey);
876+
877+
#if NET6_0_OR_GREATER
878+
var httpRes = Client.Send(httpReq);
879+
var responseBody = httpRes.Content.ReadAsStream().ReadToEnd(Encoding.UTF8);
880+
#else
881+
var httpRes = Client.SendAsync(httpReq).GetAwaiter().GetResult();
882+
var responseBody = httpRes.Content.ReadAsStreamAsync().GetAwaiter().GetResult().ReadToEnd(Encoding.UTF8);
883+
#endif
884+
885+
if (httpRes.IsSuccessStatusCode)
886+
return responseBody;
887+
888+
if (httpRes.StatusCode is >= HttpStatusCode.BadRequest and < HttpStatusCode.InternalServerError)
864889
{
865-
var result = errorBody.FromJson<StripeErrors>();
890+
var result = responseBody.FromJson<StripeErrors>();
866891
throw new StripeException(result.Error)
867892
{
868-
StatusCode = errorStatus
893+
StatusCode = httpRes.StatusCode
869894
};
870895
}
896+
897+
httpRes.EnsureSuccessStatusCode();
898+
throw CreateException(httpRes); // should never reach here
871899
}
872900

873-
protected virtual string Send(string relativeUrl, string method, string body, string idempotencyKey)
901+
protected virtual async Task<string> SendAsync(string relativeUrl, string method, string requestBody, string idempotencyKey, CancellationToken token=default)
874902
{
875-
try
876-
{
877-
var url = BaseUrl.CombineWith(relativeUrl);
878-
var response = url.SendStringToUrl(method: method, requestBody: body, requestFilter: req =>
879-
{
880-
InitRequest(req, method, idempotencyKey);
881-
});
882-
883-
return response;
884-
}
885-
catch (WebException ex)
886-
{
887-
HandleStripeException(ex);
903+
var httpReq = PrepareRequest(relativeUrl, method, requestBody, idempotencyKey);
888904

889-
throw;
890-
}
891-
}
905+
var httpRes = await Client.SendAsync(httpReq, token).ConfigAwait();
906+
var responseBody = await (await httpRes.Content.ReadAsStreamAsync()).ReadToEndAsync(Encoding.UTF8).ConfigAwait();
907+
if (httpRes.IsSuccessStatusCode)
908+
return responseBody;
892909

893-
protected virtual async Task<string> SendAsync(string relativeUrl, string method, string body, string idempotencyKey, CancellationToken token=default)
894-
{
895-
try
910+
if (httpRes.StatusCode is >= HttpStatusCode.BadRequest and < HttpStatusCode.InternalServerError)
896911
{
897-
var url = BaseUrl.CombineWith(relativeUrl);
898-
var response = await url.SendStringToUrlAsync(method: method, requestBody: body, requestFilter: req =>
912+
var result = responseBody.FromJson<StripeErrors>();
913+
throw new StripeException(result.Error)
899914
{
900-
InitRequest(req, method, idempotencyKey);
901-
});
902-
903-
return response;
915+
StatusCode = httpRes.StatusCode
916+
};
904917
}
905-
catch (Exception ex)
906-
{
907-
if (ex.UnwrapIfSingleException() is WebException webEx)
908-
HandleStripeException(webEx);
909918

910-
throw;
911-
}
919+
httpRes.EnsureSuccessStatusCode();
920+
throw CreateException(httpRes); // should never reach here
912921
}
913922

914923
public class ConfigScope : IDisposable

0 commit comments

Comments
 (0)