-
Notifications
You must be signed in to change notification settings - Fork 295
Add HTTP Response Compression Support #3003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,99 @@ | ||||||||||||||
| // Copyright (c) Microsoft Corporation. | ||||||||||||||
| // Licensed under the MIT License. | ||||||||||||||
|
|
||||||||||||||
| using System.Text.Json; | ||||||||||||||
| using System.Text.Json.Serialization; | ||||||||||||||
| using Azure.DataApiBuilder.Config.ObjectModel; | ||||||||||||||
|
|
||||||||||||||
| namespace Azure.DataApiBuilder.Config.Converters; | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Defines how DAB reads and writes the compression options (JSON). | ||||||||||||||
| /// </summary> | ||||||||||||||
| internal class CompressionOptionsConverterFactory : JsonConverterFactory | ||||||||||||||
| { | ||||||||||||||
| /// <inheritdoc/> | ||||||||||||||
| public override bool CanConvert(Type typeToConvert) | ||||||||||||||
| { | ||||||||||||||
| return typeToConvert.IsAssignableTo(typeof(CompressionOptions)); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <inheritdoc/> | ||||||||||||||
| public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) | ||||||||||||||
| { | ||||||||||||||
| return new CompressionOptionsConverter(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private class CompressionOptionsConverter : JsonConverter<CompressionOptions> | ||||||||||||||
| { | ||||||||||||||
| /// <summary> | ||||||||||||||
| /// Defines how DAB reads the compression options and defines which values are | ||||||||||||||
| /// used to instantiate CompressionOptions. | ||||||||||||||
| /// </summary> | ||||||||||||||
| public override CompressionOptions? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||||||||||||||
| { | ||||||||||||||
| if (reader.TokenType == JsonTokenType.Null) | ||||||||||||||
| { | ||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (reader.TokenType != JsonTokenType.StartObject) | ||||||||||||||
| { | ||||||||||||||
| throw new JsonException("Expected start of object."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| CompressionLevel level = CompressionOptions.DEFAULT_LEVEL; | ||||||||||||||
| bool userProvidedLevel = false; | ||||||||||||||
|
|
||||||||||||||
| while (reader.Read()) | ||||||||||||||
| { | ||||||||||||||
| if (reader.TokenType == JsonTokenType.EndObject) | ||||||||||||||
| { | ||||||||||||||
| break; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (reader.TokenType == JsonTokenType.PropertyName) | ||||||||||||||
| { | ||||||||||||||
| string? propertyName = reader.GetString(); | ||||||||||||||
| reader.Read(); | ||||||||||||||
|
|
||||||||||||||
| if (string.Equals(propertyName, "level", StringComparison.OrdinalIgnoreCase)) | ||||||||||||||
| { | ||||||||||||||
| string? levelStr = reader.GetString(); | ||||||||||||||
| if (levelStr is not null) | ||||||||||||||
| { | ||||||||||||||
| if (Enum.TryParse<CompressionLevel>(levelStr, ignoreCase: true, out CompressionLevel parsedLevel)) | ||||||||||||||
| { | ||||||||||||||
| level = parsedLevel; | ||||||||||||||
| userProvidedLevel = true; | ||||||||||||||
| } | ||||||||||||||
| else | ||||||||||||||
| { | ||||||||||||||
| throw new JsonException($"Invalid compression level: '{levelStr}'. Valid values are: optimal, fastest, none."); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
||||||||||||||
| } | |
| else | |
| { | |
| // Skip unknown properties and their values (including objects/arrays) | |
| reader.Skip(); | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace Azure.DataApiBuilder.Config.ObjectModel; | ||
|
|
||
| /// <summary> | ||
| /// Specifies the compression level for HTTP response compression. | ||
| /// </summary> | ||
| [JsonConverter(typeof(JsonStringEnumConverter))] | ||
| public enum CompressionLevel | ||
| { | ||
| /// <summary> | ||
| /// Provides the best compression ratio at the cost of speed. | ||
| /// </summary> | ||
| Optimal, | ||
|
|
||
| /// <summary> | ||
| /// Provides the fastest compression at the cost of compression ratio. | ||
| /// </summary> | ||
| Fastest, | ||
|
|
||
| /// <summary> | ||
| /// Disables compression. | ||
| /// </summary> | ||
| None | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace Azure.DataApiBuilder.Config.ObjectModel; | ||
|
|
||
| /// <summary> | ||
| /// Configuration options for HTTP response compression. | ||
| /// </summary> | ||
| public record CompressionOptions | ||
| { | ||
| /// <summary> | ||
| /// Default compression level is Optimal. | ||
| /// </summary> | ||
| public const CompressionLevel DEFAULT_LEVEL = CompressionLevel.Optimal; | ||
|
|
||
| /// <summary> | ||
| /// The compression level to use for HTTP response compression. | ||
| /// </summary> | ||
| [JsonPropertyName("level")] | ||
| public CompressionLevel Level { get; init; } = DEFAULT_LEVEL; | ||
|
|
||
| /// <summary> | ||
| /// Flag which informs CLI and JSON serializer whether to write Level | ||
| /// property and value to the runtime config file. | ||
| /// </summary> | ||
| [JsonIgnore(Condition = JsonIgnoreCondition.Always)] | ||
| public bool UserProvidedLevel { get; init; } = false; | ||
|
|
||
| [JsonConstructor] | ||
| public CompressionOptions(CompressionLevel Level = DEFAULT_LEVEL) | ||
| { | ||
| this.Level = Level; | ||
| this.UserProvidedLevel = true; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Default parameterless constructor for cases where no compression level is specified. | ||
| /// </summary> | ||
| public CompressionOptions() | ||
| { | ||
| this.Level = DEFAULT_LEVEL; | ||
| this.UserProvidedLevel = false; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing period in the documentation comment. The summary should end with a period for consistency with other test documentation in the file.