diff --git a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml
index 9dccb5286e34..6daa15d8eed0 100755
--- a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml
+++ b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml
@@ -239,6 +239,7 @@
+
diff --git a/sdk/core/azure-core/src/main/java/com/azure/core/util/serializer/SerializerEncoding.java b/sdk/core/azure-core/src/main/java/com/azure/core/util/serializer/SerializerEncoding.java
index 4fdc7326e962..287a3a5c8bfe 100644
--- a/sdk/core/azure-core/src/main/java/com/azure/core/util/serializer/SerializerEncoding.java
+++ b/sdk/core/azure-core/src/main/java/com/azure/core/util/serializer/SerializerEncoding.java
@@ -3,8 +3,11 @@
package com.azure.core.util.serializer;
-
import com.azure.core.http.HttpHeaders;
+import com.azure.core.util.logging.ClientLogger;
+
+import java.util.Map;
+import java.util.TreeMap;
/**
* Supported serialization encoding formats.
@@ -20,21 +23,68 @@ public enum SerializerEncoding {
*/
XML;
+ private static final ClientLogger LOGGER = new ClientLogger(SerializerEncoding.class);
+ private static final String CONTENT_TYPE = "Content-Type";
+ private static final Map SUPPORTED_MIME_TYPES;
+ private static final TreeMap SUPPORTED_SUFFIXES;
+ private static final SerializerEncoding DEFAULT_ENCODING = JSON;
+
+
+ static {
+ // Encodings and suffixes from: https://tools.ietf.org/html/rfc6838
+ SUPPORTED_MIME_TYPES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ SUPPORTED_MIME_TYPES.put("text/xml", XML);
+ SUPPORTED_MIME_TYPES.put("application/xml", XML);
+ SUPPORTED_MIME_TYPES.put("application/json", JSON);
+
+ SUPPORTED_SUFFIXES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ SUPPORTED_SUFFIXES.put("xml", XML);
+ SUPPORTED_SUFFIXES.put("json", JSON);
+ }
+
/**
* Determines the serializer encoding to use based on the Content-Type header.
*
- * @param headers the headers to check the encoding for
- * @return the serializer encoding to use for the body
+ * @param headers the headers to check the encoding for.
+ * @return the serializer encoding to use for the body. {@link #JSON} if there is no Content-Type header or an
+ * unrecognized Content-Type encoding is returned.
*/
public static SerializerEncoding fromHeaders(HttpHeaders headers) {
- String mimeContentType = headers.getValue("Content-Type");
- if (mimeContentType != null) {
- String[] parts = mimeContentType.split(";");
- if (parts[0].equalsIgnoreCase("application/xml") || parts[0].equalsIgnoreCase("text/xml")) {
- return XML;
- }
+ final String mimeContentType = headers.getValue(CONTENT_TYPE);
+ if (mimeContentType == null || mimeContentType.isEmpty()) {
+ LOGGER.warning("'{}' not found. Returning default encoding: {}", CONTENT_TYPE, DEFAULT_ENCODING);
+ return DEFAULT_ENCODING;
+ }
+
+ final SerializerEncoding encoding = SUPPORTED_MIME_TYPES.get(mimeContentType);
+ if (encoding != null) {
+ return encoding;
+ }
+
+ final String[] parts = mimeContentType.split(";");
+ final String[] mimeTypeParts = parts[0].split("/");
+ if (mimeTypeParts.length != 2) {
+ LOGGER.warning("Content-Type '{}' does not match mime-type formatting 'type'/'subtype'. "
+ + "Returning default: {}", parts[0], DEFAULT_ENCODING);
+ return DEFAULT_ENCODING;
+ }
+
+ // Check the suffix if it does not match the full types.
+ final String subtype = mimeTypeParts[1];
+ final int lastIndex = subtype.lastIndexOf("+");
+ if (lastIndex == -1) {
+ return DEFAULT_ENCODING;
+ }
+
+ final String mimeTypeSuffix = subtype.substring(lastIndex + 1);
+ final SerializerEncoding serializerEncoding = SUPPORTED_SUFFIXES.get(mimeTypeSuffix);
+ if (serializerEncoding != null) {
+ return serializerEncoding;
}
- return JSON;
+ LOGGER.warning("Content-Type '{}' does not match any supported one. Returning default: {}",
+ mimeContentType, DEFAULT_ENCODING);
+
+ return DEFAULT_ENCODING;
}
}
diff --git a/sdk/core/azure-core/src/test/java/com/azure/core/util/serializer/SerializerEncodingTests.java b/sdk/core/azure-core/src/test/java/com/azure/core/util/serializer/SerializerEncodingTests.java
new file mode 100644
index 000000000000..06f425da099d
--- /dev/null
+++ b/sdk/core/azure-core/src/test/java/com/azure/core/util/serializer/SerializerEncodingTests.java
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.core.util.serializer;
+
+import com.azure.core.http.HttpHeaders;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.Collections;
+
+/**
+ * Tests for {@link SerializerEncoding}.
+ */
+class SerializerEncodingTests {
+ private static final String CONTENT_TYPE = "Content-Type";
+
+ @ParameterizedTest
+ @ValueSource(strings = {"application/xml", "application/atom+xml", "text/xml", "application/foo+XML", "TEXT/XML"})
+ void recognizeXml(String mimeType) {
+ // Arrange
+ HttpHeaders headers = new HttpHeaders(Collections.singletonMap(CONTENT_TYPE, mimeType));
+
+ // Act & Assert
+ Assertions.assertEquals(SerializerEncoding.XML, SerializerEncoding.fromHeaders(headers));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"application/json", "application/kv+json", "APPLICATION/JSON", "application/FOO+JSON"})
+ void recognizeJson(String mimeType) {
+ // Arrange
+ HttpHeaders headers = new HttpHeaders(Collections.singletonMap(CONTENT_TYPE, mimeType));
+
+ // Act & Assert
+ Assertions.assertEquals(SerializerEncoding.JSON, SerializerEncoding.fromHeaders(headers));
+ }
+
+ @Test
+ void defaultNoContentType() {
+ // Arrange
+ HttpHeaders headers = new HttpHeaders(Collections.singletonMap("Http-Method", "GET"));
+
+ // Act & Assert
+ Assertions.assertEquals(SerializerEncoding.JSON, SerializerEncoding.fromHeaders(headers));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"application/binary", "invalid-mime-type"})
+ void defaultUnsupportedType(String mimeType) {
+ // Arrange
+ HttpHeaders headers = new HttpHeaders(Collections.singletonMap(CONTENT_TYPE, mimeType));
+
+ // Act & Assert
+ Assertions.assertEquals(SerializerEncoding.JSON, SerializerEncoding.fromHeaders(headers));
+ }
+}