/** * Returns a new instance with the same type and subtype as this instance, with the {@code * charset} parameter set to the {@link Charset#name name} of the given charset. Only one {@code * charset} parameter will be present on the new instance regardless of the number set on this * one. * * <p>If a charset must be specified that is not supported on this JVM (and thus is not * representable as a {@link Charset} instance, use {@link #withParameter}. */ public MediaType withCharset(Charset charset) { checkNotNull(charset); MediaType withCharset = withParameter(CHARSET_ATTRIBUTE, charset.name()); // precache the charset so we don't need to parse it withCharset.parsedCharset = Optional.of(charset); return withCharset; }
/** * Creates a media type with the "application" type and the given subtype. * * @throws IllegalArgumentException if subtype is invalid */ static MediaType createApplicationType(String subtype) { return create(APPLICATION_TYPE, subtype); }
/** * Converts the specified {@link AggregatedHttpMessage} to an object of {@code expectedResultType}. */ @Override @Nullable public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType contentType = request.headers().contentType(); if (contentType != null && (contentType.is(MediaType.JSON) || contentType.subtype().endsWith("+json"))) { final ObjectReader reader = readers.computeIfAbsent(expectedResultType, mapper::readerFor); if (reader != null) { final String content = request.content().toString( contentType.charset().orElse(StandardCharsets.UTF_8)); try { return reader.readValue(content); } catch (JsonProcessingException e) { throw new IllegalArgumentException("failed to parse a JSON document: " + e, e); } } } return RequestConverterFunction.fallthrough(); } }
@VisibleForTesting static int compareMediaType(MediaType m1, MediaType m2) { // The order should be "q=1.0, q=0.5". // To ensure descending order, we pass the q values of m2 and m1 respectively. final int qCompare = Float.compare(m2.qualityFactor(), m1.qualityFactor()); if (qCompare != 0) { return qCompare; } // The order should be "application/*, */*". final int wildcardCompare = Integer.compare(m1.numWildcards(), m2.numWildcards()); if (wildcardCompare != 0) { return wildcardCompare; } // Finally, sort by lexicographic order. ex, application/*, image/* return m1.type().compareTo(m2.type()); }
/** * Makes sure the specified {@link MediaType} or its compatible one is registered already. */ private static void checkMediaType(Multimap<MediaType, SerializationFormat> simplifiedMediaTypeToFormats, MediaType mediaType) { final MediaType simplifiedMediaType = mediaType.withoutParameters(); for (SerializationFormat format : simplifiedMediaTypeToFormats.get(simplifiedMediaType)) { for (MediaType registeredMediaType : format.mediaTypes()) { checkState(!registeredMediaType.is(mediaType) && !mediaType.is(registeredMediaType), "media type registered already: ", mediaType); } } }
@Override public void serialize(MediaType mediaType, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(mediaType.toString()); } }
/** * Converts the specified {@link AggregatedHttpMessage} to an object of {@code expectedResultType}. * This converter allows only {@code byte[]} and {@link HttpData} as its return type, and * {@link AggregatedHttpMessage} would be consumed only if it does not have a {@code Content-Type} header * or if it has {@code Content-Type: application/octet-stream} or {@code Content-Type: application/binary}. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType mediaType = request.headers().contentType(); if (mediaType == null || mediaType.is(MediaType.OCTET_STREAM) || mediaType.is(MediaType.APPLICATION_BINARY)) { if (expectedResultType == byte[].class) { return request.content().array(); } if (expectedResultType == HttpData.class) { return request.content(); } } return RequestConverterFunction.fallthrough(); } }
/** * Converts the specified {@link AggregatedHttpMessage} to a {@link String}. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { if (expectedResultType == String.class || expectedResultType == CharSequence.class) { final MediaType contentType = request.headers().contentType(); if (contentType != null && contentType.is(MediaType.ANY_TEXT_TYPE)) { // See https://tools.ietf.org/html/rfc2616#section-3.7.1 return request.content().toString( contentType.charset().orElse(StandardCharsets.ISO_8859_1)); } } return RequestConverterFunction.fallthrough(); } }
@Nullable @Override public MediaType contentType() { final String contentTypeString = get(HttpHeaderNames.CONTENT_TYPE); if (contentTypeString == null) { return null; } final MediaType contentType = this.contentType; if (contentType != null && Ascii.equalsIgnoreCase(contentType.toString(), contentTypeString.trim())) { return contentType; } try { this.contentType = MediaType.parse(contentTypeString); return this.contentType; } catch (IllegalArgumentException unused) { // Invalid media type return null; } }
/** * Creates a new HTTP response of the specified {@link HttpStatus} and closes the stream. * * @param mediaType the {@link MediaType} of the response content * @param content the content of the response */ static HttpResponse of(HttpStatus status, MediaType mediaType, String content) { return of(status, mediaType, content.getBytes(mediaType.charset().orElse(StandardCharsets.UTF_8))); }
/** * Creates a {@link SamlParameters} instance with the specified {@link AggregatedHttpMessage}. */ SamlParameters(AggregatedHttpMessage msg) { requireNonNull(msg, "msg"); final MediaType contentType = msg.headers().contentType(); final QueryStringDecoder decoder; if (contentType != null && contentType.belongsTo(MediaType.FORM_DATA)) { final String query = msg.content().toString( contentType.charset().orElse(StandardCharsets.UTF_8)); decoder = new QueryStringDecoder(query, false); } else { final String path = msg.path(); assert path != null : "path"; decoder = new QueryStringDecoder(path, true); } parameters = decoder.parameters(); }
@Override protected Set<Entry> entries() { return ImmutableSet.of( new Entry("tbinary", create("x-thrift", "TBINARY"), create("vnd.apache.thrift.binary")), new Entry("tcompact", create("x-thrift", "TCOMPACT"), create("vnd.apache.thrift.compact")), new Entry("tjson", create("x-thrift", "TJSON"), create("x-thrift", "TJSON").withCharset(UTF_8), create("vnd.apache.thrift.json"), create("vnd.apache.thrift.json").withCharset(UTF_8)), new Entry("ttext", create("x-thrift", "TTEXT"), create("x-thrift", "TTEXT").withCharset(UTF_8), create("vnd.apache.thrift.text"), create("vnd.apache.thrift.text").withCharset(UTF_8))); }
for (MediaType range : ranges) { requireNonNull(range, "ranges contains null."); float qValue = range.qualityFactor(Float.NEGATIVE_INFINITY); final int numWildcards = range.numWildcards(); final int numParams; if (qValue < 0) { numParams = range.parameters().size(); } else { numParams = range.parameters().size() - 1; if (!candidate.belongsTo(range)) { continue;
private static void addRange( List<MediaType> ranges, CharSequence header, int firstCharIdx, int lastCharIdx) { if (lastCharIdx >= 0) { try { ranges.add(MediaType.parse(header.subSequence(firstCharIdx, lastCharIdx + 1).toString())); } catch (IllegalArgumentException e) { // Ignore the malformed media range. } } } }
private static boolean isFormData(@Nullable MediaType contentType) { return contentType != null && contentType.belongsTo(MediaType.FORM_DATA); }
@Override public HttpHeaders contentType(MediaType contentType) { requireNonNull(contentType, "contentType"); this.contentType = contentType; return set(HttpHeaderNames.CONTENT_TYPE, contentType.toString()); }
@Nullable @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType mediaType = request.headers().contentType(); if (mediaType != null && mediaType.is(MediaType.PLAIN_TEXT_UTF_8)) { return new Request(request.content().toStringUtf8()); } return RequestConverterFunction.fallthrough(); } }