-
Notifications
You must be signed in to change notification settings - Fork 14
Open
Description
SDK does not handle UPS Connect with the 302 response and redirect URL (to OAuth) in the header. Instead, a timeout is hit.
Please update the response object to have the redirect URL and have it return accordingly. The HttpClient needs to be updated to not "AllowAutoRedirect" and pull the URL from the "Location" header.
Error is thrown on:
await shipEngineSdk.ConnectCarrier(CarrierName.Ups, upsAccountInfo, cancellationToken);
I have tried doing the following and was still throwing a custom ShipEngineException:
public virtual async Task<IShipEngine> GetShipEngineSDKWithNoRedirectAsync()
{
#if NET48
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
#endif
#if NETFRAMEWORK
var handler = new HttpClientHandler { AllowAutoRedirect = false };
#else
var handler = new SocketsHttpHandler { AllowAutoRedirect = false };
#endif
var httpClient = new HttpClient(handler)
{
BaseAddress = new Uri("https://api.shipengine.com/"),
};
// Some CDNs/WAFs reject requests with no UA header — add one.
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("YourApiClient/1.0");
var apiKey = await ... GetApiKey;
var config = new Config(apiKey);
return new ShipEngine(config, httpClient);
}
This is our current work around to connect without using the SDK:
private async Task<string> UpsConnectAsync(
string apiKey,
string baseUrl, // e.g., "https://api.shipengine.com/" or "https://api.eu.shipengine.com/"
string accountNumber,
string nickname,
string? accountCountryCode,
string? accountPostalCode,
CancellationToken ct)
{
#if NET48
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
#endif
#if NETFRAMEWORK
var handler = new HttpClientHandler { AllowAutoRedirect = false };
#else
var handler = new SocketsHttpHandler { AllowAutoRedirect = false };
#endif
using var http = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) };
http.DefaultRequestHeaders.Add("API-Key", apiKey); // ShipEngine auth
http.DefaultRequestHeaders.Accept.ParseAdd("application/json");
http.DefaultRequestHeaders.UserAgent.ParseAdd("YourAPIClient/1.0");
http.DefaultRequestHeaders.ExpectContinue = false;
// Minimal body for UPS connect (snake_case fields per API)
var body = new
{
nickname = nickname,
account_number = accountNumber,
account_country_code = accountCountryCode,
account_postal_code = accountPostalCode
};
using var req = new HttpRequestMessage(HttpMethod.Post, "v1/connections/carriers/ups")
{
Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")
};
using var resp = await http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct);
if (resp.StatusCode == HttpStatusCode.Redirect || resp.StatusCode == HttpStatusCode.RedirectMethod)
{
var oauthUrl = resp.Headers.Location?.ToString();
if (!string.IsNullOrEmpty(oauthUrl))
return oauthUrl!;
var b = await resp.Content.ReadAsStringAsync();
throw new InvalidOperationException("Expected UPS OAuth Location header was missing. Body: " + b);
}
// Bubble up config/auth issues with details
var bodyText = await resp.Content.ReadAsStringAsync();
throw new InvalidOperationException($"ShipEngine connect returned {(int)resp.StatusCode} {resp.ReasonPhrase}. Body: {bodyText}");
}
Metadata
Metadata
Assignees
Labels
No labels