Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions src/libs/ResembleAI/Generated/ResembleAI.AutoSDKHttpResponse.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,111 @@ public AutoSDKHttpResponse(
/// </summary>
public T Body { get; }
}

/// <summary>
/// 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.
/// </summary>
public sealed class AutoSDKConditionalResponse<T>
{
internal AutoSDKConditionalResponse(
bool notModified,
string? entityTag,
global::ResembleAI.AutoSDKHttpResponse<T>? response)
{
NotModified = notModified;
EntityTag = entityTag;
Response = response;
}

/// <summary>Gets whether the server returned HTTP 304 Not Modified.</summary>
public bool NotModified { get; }

/// <summary>Gets the response ETag, when one was supplied.</summary>
public string? EntityTag { get; }

/// <summary>Gets the successful response, or null when <see cref="NotModified"/> is true.</summary>
public global::ResembleAI.AutoSDKHttpResponse<T>? Response { get; }
}

/// <summary>
/// Helpers for standards-based ETag conditional requests. Generated clients already expose
/// request headers through <see cref="AutoSDKRequestOptions"/> and successful response
/// headers through <see cref="AutoSDKHttpResponse"/>; this helper also turns an OpenAPI
/// <c>304</c> error response into a typed not-modified result.
/// </summary>
public static class AutoSDKConditionalRequests
{
/// <summary>
/// Executes a generated <c>AsResponseAsync</c> method with an optional If-None-Match header.
/// </summary>
public static async global::System.Threading.Tasks.Task<global::ResembleAI.AutoSDKConditionalResponse<T>> SendAsync<T>(
global::System.Func<global::ResembleAI.AutoSDKRequestOptions, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task<global::ResembleAI.AutoSDKHttpResponse<T>>> 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<T>(
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<T>(
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;
}

/// <summary>Gets the first ETag header value from a generated response header map.</summary>
public static string? GetEntityTag(
global::System.Collections.Generic.Dictionary<string, global::System.Collections.Generic.IEnumerable<string>>? headers)
{
if (headers == null || !headers.TryGetValue("ETag", out var values))
{
return null;
}

return global::System.Linq.Enumerable.FirstOrDefault(values);
}
}
}
9 changes: 6 additions & 3 deletions src/libs/ResembleAI/Generated/ResembleAI.OptionsSupport.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down