From 36f4fd04f74323c137ca6ac1b464e9f5f04f33bf Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Thu, 5 Jul 2018 22:09:40 -0400 Subject: [PATCH] Add parse overload which fails on invalid inputs --- .../internal/huc/JavaApiConverterTest.java | 4 +- .../java/okhttp3/apache/HttpEntityBody.java | 2 +- .../okhttp3/dnsoverhttps/DnsOverHttps.java | 4 +- .../logging/HttpLoggingInterceptorTest.java | 2 +- .../src/test/java/okhttp3/CacheTest.java | 4 +- .../src/test/java/okhttp3/CallTest.java | 46 +++---- .../java/okhttp3/ConnectionReuseTest.java | 2 +- .../test/java/okhttp3/EventListenerTest.java | 12 +- .../test/java/okhttp3/InterceptorTest.java | 10 +- .../src/test/java/okhttp3/MediaTypeTest.java | 130 ++++++++++++------ .../test/java/okhttp3/MultipartBodyTest.java | 6 +- .../src/test/java/okhttp3/RequestTest.java | 16 +-- .../test/java/okhttp3/ResponseBodyTest.java | 2 +- .../internal/http2/HttpOverHttp2Test.java | 6 +- okhttp/src/main/java/okhttp3/FormBody.java | 3 +- okhttp/src/main/java/okhttp3/MediaType.java | 39 +++++- .../src/main/java/okhttp3/MultipartBody.java | 12 +- .../main/java/okhttp3/guide/PostExample.java | 3 +- .../main/java/okhttp3/recipes/PostFile.java | 2 +- .../java/okhttp3/recipes/PostMultipart.java | 2 +- .../java/okhttp3/recipes/PostStreaming.java | 2 +- .../recipes/PostStreamingWithPipe.java | 2 +- .../main/java/okhttp3/recipes/PostString.java | 2 +- .../recipes/RequestBodyCompression.java | 2 +- 24 files changed, 191 insertions(+), 124 deletions(-) diff --git a/okhttp-android-support/src/test/java/okhttp3/internal/huc/JavaApiConverterTest.java b/okhttp-android-support/src/test/java/okhttp3/internal/huc/JavaApiConverterTest.java index c14d6d57f..ad5d3fdfd 100644 --- a/okhttp-android-support/src/test/java/okhttp3/internal/huc/JavaApiConverterTest.java +++ b/okhttp-android-support/src/test/java/okhttp3/internal/huc/JavaApiConverterTest.java @@ -660,7 +660,7 @@ public class JavaApiConverterTest { } private static RequestBody createRequestBody(String bodyText) { - return RequestBody.create(MediaType.parse("text/plain"), bodyText); + return RequestBody.create(MediaType.get("text/plain"), bodyText); } private static ResponseBody createResponseBody(String bodyText) { @@ -668,7 +668,7 @@ public class JavaApiConverterTest { final long contentLength = source.size(); return new ResponseBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain; charset=utf-8"); + return MediaType.get("text/plain; charset=utf-8"); } @Override public long contentLength() { diff --git a/okhttp-apache/src/main/java/okhttp3/apache/HttpEntityBody.java b/okhttp-apache/src/main/java/okhttp3/apache/HttpEntityBody.java index 45d27aafd..c55543f56 100644 --- a/okhttp-apache/src/main/java/okhttp3/apache/HttpEntityBody.java +++ b/okhttp-apache/src/main/java/okhttp3/apache/HttpEntityBody.java @@ -8,7 +8,7 @@ import org.apache.http.HttpEntity; /** Adapts an {@link HttpEntity} to OkHttp's {@link RequestBody}. */ final class HttpEntityBody extends RequestBody { - private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.parse("application/octet-stream"); + private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.get("application/octet-stream"); private final HttpEntity entity; private final MediaType mediaType; diff --git a/okhttp-dnsoverhttps/src/main/java/okhttp3/dnsoverhttps/DnsOverHttps.java b/okhttp-dnsoverhttps/src/main/java/okhttp3/dnsoverhttps/DnsOverHttps.java index 44a1832cf..a2f63e86c 100644 --- a/okhttp-dnsoverhttps/src/main/java/okhttp3/dnsoverhttps/DnsOverHttps.java +++ b/okhttp-dnsoverhttps/src/main/java/okhttp3/dnsoverhttps/DnsOverHttps.java @@ -53,8 +53,8 @@ import okio.ByteString; * Until then, expect API and behavior changes when you update your OkHttp dependency. */ public class DnsOverHttps implements Dns { - public static final MediaType DNS_MESSAGE = MediaType.parse("application/dns-message"); - public static final MediaType UDPWIREFORMAT = MediaType.parse("application/dns-udpwireformat"); + public static final MediaType DNS_MESSAGE = MediaType.get("application/dns-message"); + public static final MediaType UDPWIREFORMAT = MediaType.get("application/dns-udpwireformat"); public static final int MAX_RESPONSE_SIZE = 64 * 1024; private final OkHttpClient client; private final HttpUrl url; diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.java b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.java index 613aed134..6eab47fc6 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.java +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.java @@ -53,7 +53,7 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeThat; public final class HttpLoggingInterceptorTest { - private static final MediaType PLAIN = MediaType.parse("text/plain; charset=utf-8"); + private static final MediaType PLAIN = MediaType.get("text/plain; charset=utf-8"); @Rule public final MockWebServer server = new MockWebServer(); diff --git a/okhttp-tests/src/test/java/okhttp3/CacheTest.java b/okhttp-tests/src/test/java/okhttp3/CacheTest.java index 9e096772a..05b40f3d0 100644 --- a/okhttp-tests/src/test/java/okhttp3/CacheTest.java +++ b/okhttp-tests/src/test/java/okhttp3/CacheTest.java @@ -774,7 +774,7 @@ public final class CacheTest { private RequestBody requestBodyOrNull(String requestMethod) { return (requestMethod.equals("POST") || requestMethod.equals("PUT")) - ? RequestBody.create(MediaType.parse("text/plain"), "foo") + ? RequestBody.create(MediaType.get("text/plain"), "foo") : null; } @@ -862,7 +862,7 @@ public final class CacheTest { Request request = new Request.Builder() .url(url) - .put(RequestBody.create(MediaType.parse("text/plain"), "foo")) + .put(RequestBody.create(MediaType.get("text/plain"), "foo")) .build(); Response invalidate = client.newCall(request).execute(); assertEquals("", invalidate.body().string()); diff --git a/okhttp-tests/src/test/java/okhttp3/CallTest.java b/okhttp-tests/src/test/java/okhttp3/CallTest.java index 02af8045f..ca9f93b6b 100644 --- a/okhttp-tests/src/test/java/okhttp3/CallTest.java +++ b/okhttp-tests/src/test/java/okhttp3/CallTest.java @@ -206,7 +206,7 @@ public final class CallTest { server.enqueue(new MockResponse()); try { - new Request.Builder().method("GET", RequestBody.create(MediaType.parse("text/plain"), "abc")); + new Request.Builder().method("GET", RequestBody.create(MediaType.get("text/plain"), "abc")); fail(); } catch (IllegalArgumentException expected) { } @@ -300,7 +300,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "def")) + .post(RequestBody.create(MediaType.get("text/plain"), "def")) .build(); executeSynchronously(request) @@ -501,7 +501,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .method("DELETE", RequestBody.create(MediaType.parse("text/plain"), "def")) + .method("DELETE", RequestBody.create(MediaType.get("text/plain"), "def")) .build(); executeSynchronously(request) @@ -518,7 +518,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .put(RequestBody.create(MediaType.parse("text/plain"), "def")) + .put(RequestBody.create(MediaType.get("text/plain"), "def")) .build(); executeSynchronously(request) @@ -547,7 +547,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .patch(RequestBody.create(MediaType.parse("text/plain"), "def")) + .patch(RequestBody.create(MediaType.get("text/plain"), "def")) .build(); executeSynchronously(request) @@ -576,7 +576,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .method("CUSTOM", RequestBody.create(MediaType.parse("text/plain"), "def")) + .method("CUSTOM", RequestBody.create(MediaType.get("text/plain"), "def")) .build(); executeSynchronously(request) @@ -937,7 +937,7 @@ public final class CallTest { // Call 1: set a deadline on the request body. RequestBody requestBody1 = new RequestBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain"); + return MediaType.get("text/plain"); } @Override public void writeTo(BufferedSink sink) throws IOException { @@ -955,7 +955,7 @@ public final class CallTest { // Call 2: check for the absence of a deadline on the request body. RequestBody requestBody2 = new RequestBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain"); + return MediaType.get("text/plain"); } @Override public void writeTo(BufferedSink sink) throws IOException { @@ -1272,7 +1272,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "def")) + .post(RequestBody.create(MediaType.get("text/plain"), "def")) .build(); client.newCall(request).enqueue(callback); @@ -1298,7 +1298,7 @@ public final class CallTest { Request request2 = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "body!")) + .post(RequestBody.create(MediaType.get("text/plain"), "body!")) .build(); Response response2 = client.newCall(request2).execute(); assertEquals("def", response2.body().string()); @@ -1614,7 +1614,7 @@ public final class CallTest { Response response = client.newCall(new Request.Builder() .url(server.url("/page1")) - .post(RequestBody.create(MediaType.parse("text/plain"), "Request Body")) + .post(RequestBody.create(MediaType.get("text/plain"), "Request Body")) .build()).execute(); assertEquals("Page 2", response.body().string()); @@ -1668,7 +1668,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "Hello")) + .post(RequestBody.create(MediaType.get("text/plain"), "Hello")) .build(); Response response = client.newCall(request).execute(); @@ -1777,7 +1777,7 @@ public final class CallTest { // when Response response = client.newCall(new Request.Builder() .url(server.url("/page1")) - .method("PROPFIND", RequestBody.create(MediaType.parse("text/plain"), "Request Body")) + .method("PROPFIND", RequestBody.create(MediaType.get("text/plain"), "Request Body")) .build()).execute(); // then @@ -2408,7 +2408,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); executeSynchronously(request) @@ -2424,7 +2424,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "")) + .post(RequestBody.create(MediaType.get("text/plain"), "")) .build(); executeSynchronously(request) @@ -2448,7 +2448,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); Call call = client.newCall(request); @@ -2473,7 +2473,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); executeSynchronously(request) @@ -2499,7 +2499,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); Call call = client.newCall(request); @@ -2526,7 +2526,7 @@ public final class CallTest { executeSynchronously(new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build()); executeSynchronously(new Request.Builder() .url(server.url("/")) @@ -2548,7 +2548,7 @@ public final class CallTest { executeSynchronously(new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build()); executeSynchronously(new Request.Builder() .url(server.url("/")) @@ -2567,7 +2567,7 @@ public final class CallTest { executeSynchronously(new Request.Builder() .url(server.url("/")) .header("Expect", "100-continue") - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build()); executeSynchronously(new Request.Builder() .url(server.url("/")) @@ -2972,7 +2972,7 @@ public final class CallTest { Request request = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "abc")) + .post(RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); executeSynchronously(request); @@ -3064,7 +3064,7 @@ public final class CallTest { return new RequestBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain; charset=utf-8"); + return MediaType.get("text/plain; charset=utf-8"); } @Override public long contentLength() throws IOException { diff --git a/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java b/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java index 399fbb286..e72d1a45b 100644 --- a/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java +++ b/okhttp-tests/src/test/java/okhttp3/ConnectionReuseTest.java @@ -191,7 +191,7 @@ public final class ConnectionReuseTest { Request requestB = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), "b")) + .post(RequestBody.create(MediaType.get("text/plain"), "b")) .build(); Response responseB = client.newCall(requestB).execute(); assertEquals("b", responseB.body().string()); diff --git a/okhttp-tests/src/test/java/okhttp3/EventListenerTest.java b/okhttp-tests/src/test/java/okhttp3/EventListenerTest.java index 6032e4e9c..ba239ad37 100644 --- a/okhttp-tests/src/test/java/okhttp3/EventListenerTest.java +++ b/okhttp-tests/src/test/java/okhttp3/EventListenerTest.java @@ -970,7 +970,7 @@ public final class EventListenerTest { // Stream a 8 MiB body so the disconnect will happen before the server has read everything. RequestBody requestBody = new RequestBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain"); + return MediaType.get("text/plain"); } @Override public long contentLength() { @@ -1005,26 +1005,26 @@ public final class EventListenerTest { @Test public void requestBodySuccessHttp1OverHttps() throws IOException { enableTlsWithTunnel(false); server.setProtocols(Arrays.asList(Protocol.HTTP_1_1)); - requestBodySuccess(RequestBody.create(MediaType.parse("text/plain"), "Hello"), equalTo(5L), + requestBodySuccess(RequestBody.create(MediaType.get("text/plain"), "Hello"), equalTo(5L), equalTo(19L)); } @Test public void requestBodySuccessHttp2OverHttps() throws IOException { enableTlsWithTunnel(false); server.setProtocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)); - requestBodySuccess(RequestBody.create(MediaType.parse("text/plain"), "Hello"), equalTo(5L), + requestBodySuccess(RequestBody.create(MediaType.get("text/plain"), "Hello"), equalTo(5L), equalTo(19L)); } @Test public void requestBodySuccessHttp() throws IOException { - requestBodySuccess(RequestBody.create(MediaType.parse("text/plain"), "Hello"), equalTo(5L), + requestBodySuccess(RequestBody.create(MediaType.get("text/plain"), "Hello"), equalTo(5L), equalTo(19L)); } @Test public void requestBodySuccessStreaming() throws IOException { RequestBody requestBody = new RequestBody() { @Override public MediaType contentType() { - return MediaType.parse("text/plain"); + return MediaType.get("text/plain"); } @Override public void writeTo(BufferedSink sink) throws IOException { @@ -1037,7 +1037,7 @@ public final class EventListenerTest { } @Test public void requestBodySuccessEmpty() throws IOException { - requestBodySuccess(RequestBody.create(MediaType.parse("text/plain"), ""), equalTo(0L), + requestBodySuccess(RequestBody.create(MediaType.get("text/plain"), ""), equalTo(0L), equalTo(19L)); } diff --git a/okhttp-tests/src/test/java/okhttp3/InterceptorTest.java b/okhttp-tests/src/test/java/okhttp3/InterceptorTest.java index e01a360b9..ed8352969 100644 --- a/okhttp-tests/src/test/java/okhttp3/InterceptorTest.java +++ b/okhttp-tests/src/test/java/okhttp3/InterceptorTest.java @@ -67,7 +67,7 @@ public final class InterceptorTest { .protocol(Protocol.HTTP_1_1) .code(200) .message("Intercepted!") - .body(ResponseBody.create(MediaType.parse("text/plain; charset=utf-8"), "abc")) + .body(ResponseBody.create(MediaType.get("text/plain; charset=utf-8"), "abc")) .build(); client = client.newBuilder() @@ -91,7 +91,7 @@ public final class InterceptorTest { .protocol(Protocol.HTTP_1_1) .code(200) .message("Intercepted!") - .body(ResponseBody.create(MediaType.parse("text/plain; charset=utf-8"), "abc")) + .body(ResponseBody.create(MediaType.get("text/plain; charset=utf-8"), "abc")) .build(); } }; @@ -234,7 +234,7 @@ public final class InterceptorTest { Interceptor interceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); - MediaType mediaType = MediaType.parse("text/plain"); + MediaType mediaType = MediaType.get("text/plain"); RequestBody body = RequestBody.create(mediaType, "abc"); return chain.proceed(originalRequest.newBuilder() .method("POST", body) @@ -283,7 +283,7 @@ public final class InterceptorTest { Request request = new Request.Builder() .url(server.url("/")) .addHeader("Original-Header", "foo") - .method("PUT", RequestBody.create(MediaType.parse("text/plain"), "abc")) + .method("PUT", RequestBody.create(MediaType.get("text/plain"), "abc")) .build(); client.newCall(request).execute(); @@ -818,7 +818,7 @@ public final class InterceptorTest { byte[] data = new byte[2 * 1024 * 1024]; // 2 MiB. Request request1 = new Request.Builder() .url(server.url("/")) - .post(RequestBody.create(MediaType.parse("text/plain"), data)) + .post(RequestBody.create(MediaType.get("text/plain"), data)) .build(); Call call = client.newCall(request1); diff --git a/okhttp-tests/src/test/java/okhttp3/MediaTypeTest.java b/okhttp-tests/src/test/java/okhttp3/MediaTypeTest.java index b2d3f396f..f0b194713 100644 --- a/okhttp-tests/src/test/java/okhttp3/MediaTypeTest.java +++ b/okhttp-tests/src/test/java/okhttp3/MediaTypeTest.java @@ -17,12 +17,17 @@ package okhttp3; import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collection; import okhttp3.internal.Util; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Test MediaType API and parsing. @@ -30,16 +35,34 @@ import static org.junit.Assert.assertTrue; *

This test includes tests from Guava's * MediaTypeTest. */ +@RunWith(Parameterized.class) public class MediaTypeTest { + @Parameterized.Parameters(name = "Use get = {0}") + public static Collection parameters() { + return Arrays.asList( + new Object[] { true }, + new Object[] { false } + ); + } + + @Parameterized.Parameter + public boolean useGet; + + private MediaType parse(String string) { + return useGet + ? MediaType.get(string) + : MediaType.parse(string); + } + @Test public void testParse() throws Exception { - MediaType mediaType = MediaType.parse("text/plain;boundary=foo;charset=utf-8"); + MediaType mediaType = parse("text/plain;boundary=foo;charset=utf-8"); assertEquals("text", mediaType.type()); assertEquals("plain", mediaType.subtype()); assertEquals("UTF-8", mediaType.charset().name()); assertEquals("text/plain;boundary=foo;charset=utf-8", mediaType.toString()); - assertTrue(mediaType.equals(MediaType.parse("text/plain;boundary=foo;charset=utf-8"))); + assertTrue(mediaType.equals(parse("text/plain;boundary=foo;charset=utf-8"))); assertEquals(mediaType.hashCode(), - MediaType.parse("text/plain;boundary=foo;charset=utf-8").hashCode()); + parse("text/plain;boundary=foo;charset=utf-8").hashCode()); } @Test public void testValidParse() throws Exception { @@ -61,75 +84,86 @@ public class MediaTypeTest { } @Test public void testInvalidParse() throws Exception { - assertInvalid(""); - assertInvalid("/"); - assertInvalid("/"); - assertInvalid("text"); - assertInvalid("text/"); - assertInvalid("te encodedNames; private final List encodedValues; diff --git a/okhttp/src/main/java/okhttp3/MediaType.java b/okhttp/src/main/java/okhttp3/MediaType.java index 95194c571..ddbd8fcb1 100644 --- a/okhttp/src/main/java/okhttp3/MediaType.java +++ b/okhttp/src/main/java/okhttp3/MediaType.java @@ -45,12 +45,15 @@ public final class MediaType { } /** - * Returns a media type for {@code string}, or null if {@code string} is not a well-formed media - * type. + * Returns a media type for {@code string}. + * + * @throws IllegalArgumentException if {@code string} is not a well-formed media type. */ - public static @Nullable MediaType parse(String string) { + public static MediaType get(String string) { Matcher typeSubtype = TYPE_SUBTYPE.matcher(string); - if (!typeSubtype.lookingAt()) return null; + if (!typeSubtype.lookingAt()) { + throw new IllegalArgumentException("No subtype found for: \"" + string + '"'); + } String type = typeSubtype.group(1).toLowerCase(Locale.US); String subtype = typeSubtype.group(2).toLowerCase(Locale.US); @@ -58,7 +61,13 @@ public final class MediaType { Matcher parameter = PARAMETER.matcher(string); for (int s = typeSubtype.end(); s < string.length(); s = parameter.end()) { parameter.region(s, string.length()); - if (!parameter.lookingAt()) return null; // This is not a well-formed media type. + if (!parameter.lookingAt()) { + throw new IllegalArgumentException("Parameter is not formatted correctly: \"" + + string.substring(s) + + "\" for: \"" + + string + + '"'); + } String name = parameter.group(1); if (name == null || !name.equalsIgnoreCase("charset")) continue; @@ -74,7 +83,13 @@ public final class MediaType { charsetParameter = parameter.group(3); } if (charset != null && !charsetParameter.equalsIgnoreCase(charset)) { - return null; // Multiple different charsets! + throw new IllegalArgumentException("Multiple charsets defined: \"" + + charset + + "\" and: \"" + + charsetParameter + + "\" for: \"" + + string + + '"'); } charset = charsetParameter; } @@ -82,6 +97,18 @@ public final class MediaType { return new MediaType(string, type, subtype, charset); } + /** + * Returns a media type for {@code string}, or null if {@code string} is not a well-formed media + * type. + */ + public static @Nullable MediaType parse(String string) { + try { + return get(string); + } catch (IllegalArgumentException ignored) { + return null; + } + } + /** * Returns the high-level media type, such as "text", "image", "audio", "video", or * "application". diff --git a/okhttp/src/main/java/okhttp3/MultipartBody.java b/okhttp/src/main/java/okhttp3/MultipartBody.java index 09c1eaf2f..800064cfb 100644 --- a/okhttp/src/main/java/okhttp3/MultipartBody.java +++ b/okhttp/src/main/java/okhttp3/MultipartBody.java @@ -32,34 +32,34 @@ public final class MultipartBody extends RequestBody { * need to be bundled in a particular order. Any "multipart" subtypes that an implementation does * not recognize must be treated as being of subtype "mixed". */ - public static final MediaType MIXED = MediaType.parse("multipart/mixed"); + public static final MediaType MIXED = MediaType.get("multipart/mixed"); /** * The "multipart/alternative" type is syntactically identical to "multipart/mixed", but the * semantics are different. In particular, each of the body parts is an "alternative" version of * the same information. */ - public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative"); + public static final MediaType ALTERNATIVE = MediaType.get("multipart/alternative"); /** * This type is syntactically identical to "multipart/mixed", but the semantics are different. In * particular, in a digest, the default {@code Content-Type} value for a body part is changed from * "text/plain" to "message/rfc822". */ - public static final MediaType DIGEST = MediaType.parse("multipart/digest"); + public static final MediaType DIGEST = MediaType.get("multipart/digest"); /** * This type is syntactically identical to "multipart/mixed", but the semantics are different. In * particular, in a parallel entity, the order of body parts is not significant. */ - public static final MediaType PARALLEL = MediaType.parse("multipart/parallel"); + public static final MediaType PARALLEL = MediaType.get("multipart/parallel"); /** * The media-type multipart/form-data follows the rules of all multipart MIME data streams as * outlined in RFC 2046. In forms, there are a series of fields to be supplied by the user who * fills out the form. Each field has a name. Within a given form, the names are unique. */ - public static final MediaType FORM = MediaType.parse("multipart/form-data"); + public static final MediaType FORM = MediaType.get("multipart/form-data"); private static final byte[] COLONSPACE = {':', ' '}; private static final byte[] CRLF = {'\r', '\n'}; @@ -74,7 +74,7 @@ public final class MultipartBody extends RequestBody { MultipartBody(ByteString boundary, MediaType type, List parts) { this.boundary = boundary; this.originalType = type; - this.contentType = MediaType.parse(type + "; boundary=" + boundary.utf8()); + this.contentType = MediaType.get(type + "; boundary=" + boundary.utf8()); this.parts = Util.immutableList(parts); } diff --git a/samples/guide/src/main/java/okhttp3/guide/PostExample.java b/samples/guide/src/main/java/okhttp3/guide/PostExample.java index b6e70ccc7..ddaacb6c5 100644 --- a/samples/guide/src/main/java/okhttp3/guide/PostExample.java +++ b/samples/guide/src/main/java/okhttp3/guide/PostExample.java @@ -8,8 +8,7 @@ import okhttp3.RequestBody; import okhttp3.Response; public class PostExample { - public static final MediaType JSON - = MediaType.parse("application/json; charset=utf-8"); + public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/PostFile.java b/samples/guide/src/main/java/okhttp3/recipes/PostFile.java index b216b24b3..0e52cddd2 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/PostFile.java +++ b/samples/guide/src/main/java/okhttp3/recipes/PostFile.java @@ -25,7 +25,7 @@ import okhttp3.Response; public final class PostFile { public static final MediaType MEDIA_TYPE_MARKDOWN - = MediaType.parse("text/x-markdown; charset=utf-8"); + = MediaType.get("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java b/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java index 3e93a00e8..60534d7de 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java +++ b/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java @@ -30,7 +30,7 @@ public final class PostMultipart { * these examples, please request your own client ID! https://api.imgur.com/oauth2 */ private static final String IMGUR_CLIENT_ID = "9199fdef135c122"; - private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); + private static final MediaType MEDIA_TYPE_PNG = MediaType.get("image/png"); private final OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/PostStreaming.java b/samples/guide/src/main/java/okhttp3/recipes/PostStreaming.java index 440c7768e..90ec01c6b 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/PostStreaming.java +++ b/samples/guide/src/main/java/okhttp3/recipes/PostStreaming.java @@ -25,7 +25,7 @@ import okio.BufferedSink; public final class PostStreaming { public static final MediaType MEDIA_TYPE_MARKDOWN - = MediaType.parse("text/x-markdown; charset=utf-8"); + = MediaType.get("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/PostStreamingWithPipe.java b/samples/guide/src/main/java/okhttp3/recipes/PostStreamingWithPipe.java index b313ce0d1..c73b9154e 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/PostStreamingWithPipe.java +++ b/samples/guide/src/main/java/okhttp3/recipes/PostStreamingWithPipe.java @@ -27,7 +27,7 @@ import okio.Pipe; public final class PostStreamingWithPipe { public static final MediaType MEDIA_TYPE_MARKDOWN - = MediaType.parse("text/x-markdown; charset=utf-8"); + = MediaType.get("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/PostString.java b/samples/guide/src/main/java/okhttp3/recipes/PostString.java index 8a312bde8..6c8ea4f9e 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/PostString.java +++ b/samples/guide/src/main/java/okhttp3/recipes/PostString.java @@ -24,7 +24,7 @@ import okhttp3.Response; public final class PostString { public static final MediaType MEDIA_TYPE_MARKDOWN - = MediaType.parse("text/x-markdown; charset=utf-8"); + = MediaType.get("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); diff --git a/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java b/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java index b1a62c0fa..5473f6701 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java +++ b/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java @@ -39,7 +39,7 @@ public final class RequestBodyCompression { * https://console.developers.google.com/project */ public static final String GOOGLE_API_KEY = "AIzaSyAx2WZYe0My0i-uGurpvraYJxO7XNbwiGs"; - public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json"); + public static final MediaType MEDIA_TYPE_JSON = MediaType.get("application/json"); private final OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new GzipRequestInterceptor())