diff --git a/src/libs/ResembleAI/Generated/ResembleAI.AutoSDKHttpResponse.g.cs b/src/libs/ResembleAI/Generated/ResembleAI.AutoSDKHttpResponse.g.cs index 4f72a14..5c66153 100644 --- a/src/libs/ResembleAI/Generated/ResembleAI.AutoSDKHttpResponse.g.cs +++ b/src/libs/ResembleAI/Generated/ResembleAI.AutoSDKHttpResponse.g.cs @@ -118,4 +118,111 @@ public AutoSDKHttpResponse( /// public T Body { get; } } + + /// + /// Represents the result of a conditional HTTP request. A not-modified response has no body + /// and preserves the response entity tag so callers can keep their cached representation. + /// + public sealed class AutoSDKConditionalResponse + { + internal AutoSDKConditionalResponse( + bool notModified, + string? entityTag, + global::ResembleAI.AutoSDKHttpResponse? response) + { + NotModified = notModified; + EntityTag = entityTag; + Response = response; + } + + /// Gets whether the server returned HTTP 304 Not Modified. + public bool NotModified { get; } + + /// Gets the response ETag, when one was supplied. + public string? EntityTag { get; } + + /// Gets the successful response, or null when is true. + public global::ResembleAI.AutoSDKHttpResponse? Response { get; } + } + + /// + /// Helpers for standards-based ETag conditional requests. Generated clients already expose + /// request headers through and successful response + /// headers through ; this helper also turns an OpenAPI + /// 304 error response into a typed not-modified result. + /// + public static class AutoSDKConditionalRequests + { + /// + /// Executes a generated AsResponseAsync method with an optional If-None-Match header. + /// + public static async global::System.Threading.Tasks.Task> SendAsync( + global::System.Func>> send, + string? entityTag = null, + global::ResembleAI.AutoSDKRequestOptions? requestOptions = null, + global::System.Threading.CancellationToken cancellationToken = default) + { + send = send ?? throw new global::System.ArgumentNullException(nameof(send)); + requestOptions = CloneRequestOptions(requestOptions); + if (!string.IsNullOrWhiteSpace(entityTag)) + { + requestOptions.Headers["If-None-Match"] = entityTag!; + } + + try + { + var response = await send(requestOptions, cancellationToken).ConfigureAwait(false); + return new global::ResembleAI.AutoSDKConditionalResponse( + notModified: false, + entityTag: GetEntityTag(response.Headers), + response: response); + } + catch (global::ResembleAI.ApiException exception) + when (exception.StatusCode == global::System.Net.HttpStatusCode.NotModified) + { + return new global::ResembleAI.AutoSDKConditionalResponse( + notModified: true, + entityTag: GetEntityTag(exception.ResponseHeaders) ?? entityTag, + response: null); + } + } + + private static global::ResembleAI.AutoSDKRequestOptions CloneRequestOptions( + global::ResembleAI.AutoSDKRequestOptions? source) + { + var clone = new global::ResembleAI.AutoSDKRequestOptions(); + if (source == null) + { + return clone; + } + + foreach (var header in source.Headers) + { + clone.Headers[header.Key] = header.Value; + } + + foreach (var parameter in source.QueryParameters) + { + clone.QueryParameters[parameter.Key] = parameter.Value; + } + + clone.Timeout = source.Timeout; + clone.Retry = source.Retry; + clone.ReadResponseAsString = source.ReadResponseAsString; + clone.Authorizations = source.Authorizations; + return clone; + } + + /// Gets the first ETag header value from a generated response header map. + public static string? GetEntityTag( + global::System.Collections.Generic.Dictionary>? headers) + { + if (headers == null || !headers.TryGetValue("ETag", out var values)) + { + return null; + } + + return global::System.Linq.Enumerable.FirstOrDefault(values); + } + } } \ No newline at end of file diff --git a/src/libs/ResembleAI/Generated/ResembleAI.OptionsSupport.g.cs b/src/libs/ResembleAI/Generated/ResembleAI.OptionsSupport.g.cs index 394e3e2..66579ce 100644 --- a/src/libs/ResembleAI/Generated/ResembleAI.OptionsSupport.g.cs +++ b/src/libs/ResembleAI/Generated/ResembleAI.OptionsSupport.g.cs @@ -903,11 +903,14 @@ private static void ApplyHeadersCore( foreach (var header in headers) { request.Headers.Remove(header.Key); - request.Content?.Headers.Remove(header.Key); + if (request.Headers.TryAddWithoutValidation(header.Key, header.Value ?? string.Empty)) + { + continue; + } - if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value ?? string.Empty) && - request.Content != null) + if (request.Content != null) { + request.Content.Headers.Remove(header.Key); request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value ?? string.Empty); } }