!htc refactor MediaType and ContentType model for better type-safety and cleanliness
This commit is contained in:
parent
3520d7e827
commit
e9240b7d86
31 changed files with 895 additions and 819 deletions
|
|
@ -9,33 +9,33 @@ import akka.japi.Option;
|
|||
/**
|
||||
* Represents an Http content-type. A content-type consists of a media-type and an optional charset.
|
||||
*/
|
||||
public abstract class ContentType {
|
||||
/**
|
||||
* Returns the media-type of this content-type.
|
||||
*/
|
||||
public abstract MediaType mediaType();
|
||||
public interface ContentType {
|
||||
|
||||
/**
|
||||
* Returns the charset of this content-type.
|
||||
* The media-type of this content-type.
|
||||
*/
|
||||
public abstract HttpCharset charset();
|
||||
MediaType mediaType();
|
||||
|
||||
/**
|
||||
* Returns the optionally defined charset of this content-type.
|
||||
* True if this ContentType is non-textual.
|
||||
*/
|
||||
public abstract Option<HttpCharset> getDefinedCharset();
|
||||
boolean binary();
|
||||
|
||||
/**
|
||||
* Creates a content-type from a media-type and a charset.
|
||||
* Returns the charset if this ContentType is non-binary.
|
||||
*/
|
||||
public static ContentType create(MediaType mediaType, HttpCharset charset) {
|
||||
return akka.http.scaladsl.model.ContentType.apply((akka.http.scaladsl.model.MediaType) mediaType, (akka.http.scaladsl.model.HttpCharset) charset);
|
||||
Option<HttpCharset> getCharsetOption();
|
||||
|
||||
interface Binary extends ContentType {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a content-type from a media-type without specifying a charset.
|
||||
*/
|
||||
public static ContentType create(MediaType mediaType) {
|
||||
return akka.http.scaladsl.model.ContentType.apply((akka.http.scaladsl.model.MediaType) mediaType);
|
||||
interface NonBinary extends ContentType {
|
||||
HttpCharset charset();
|
||||
}
|
||||
|
||||
interface WithFixedCharset extends NonBinary {
|
||||
}
|
||||
|
||||
interface WithCharset extends NonBinary {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
package akka.http.javadsl.model;
|
||||
|
||||
|
||||
import akka.http.scaladsl.model.ContentType$;
|
||||
|
||||
/**
|
||||
* Contains the set of predefined content-types for convenience.
|
||||
* <p>
|
||||
|
|
@ -11,14 +13,26 @@ package akka.http.javadsl.model;
|
|||
* you can obtain it from a {@link MediaType} by using: {@code MediaTypes.TEXT_HTML.toContentType()}
|
||||
*/
|
||||
public final class ContentTypes {
|
||||
public static final ContentType APPLICATION_JSON = MediaTypes.APPLICATION_JSON.toContentType();
|
||||
public static final ContentType APPLICATION_OCTET_STREAM = MediaTypes.APPLICATION_OCTET_STREAM.toContentType();
|
||||
public static final ContentType.WithFixedCharset APPLICATION_JSON = MediaTypes.APPLICATION_JSON.toContentType();
|
||||
public static final ContentType.Binary APPLICATION_OCTET_STREAM = MediaTypes.APPLICATION_OCTET_STREAM.toContentType();
|
||||
|
||||
public static final ContentType TEXT_PLAIN = MediaTypes.TEXT_PLAIN.toContentType();
|
||||
public static final ContentType TEXT_PLAIN_UTF8 = akka.http.scaladsl.model.ContentTypes.text$divplain$u0028UTF$minus8$u0029();
|
||||
public static final ContentType TEXT_HTML = MediaTypes.TEXT_HTML.toContentType();
|
||||
public static final ContentType TEXT_XML = MediaTypes.TEXT_XML.toContentType();
|
||||
public static final ContentType.WithCharset TEXT_PLAIN_UTF8 =
|
||||
akka.http.scaladsl.model.ContentTypes.text$divplain$u0028UTF$minus8$u0029();
|
||||
public static final ContentType.WithCharset TEXT_HTML_UTF8 =
|
||||
akka.http.scaladsl.model.ContentTypes.text$divhtml$u0028UTF$minus8$u0029();
|
||||
public static final ContentType.WithCharset TEXT_XML_UTF8 =
|
||||
akka.http.scaladsl.model.ContentTypes.text$divxml$u0028UTF$minus8$u0029();
|
||||
|
||||
public static final ContentType APPLICATION_X_WWW_FORM_URLENCODED = MediaTypes.APPLICATION_X_WWW_FORM_URLENCODED.toContentType();
|
||||
public static final ContentType MULTIPART_FORM_DATA = MediaTypes.MULTIPART_FORM_DATA.toContentType();
|
||||
public static ContentType.Binary create(MediaType.Binary mediaType) {
|
||||
return ContentType$.MODULE$.apply((akka.http.scaladsl.model.MediaType.Binary) mediaType);
|
||||
}
|
||||
|
||||
public static ContentType.WithFixedCharset create(MediaType.WithFixedCharset mediaType) {
|
||||
return ContentType$.MODULE$.apply((akka.http.scaladsl.model.MediaType.WithFixedCharset) mediaType);
|
||||
}
|
||||
|
||||
public static ContentType.WithCharset create(MediaType.WithOpenCharset mediaType, HttpCharset charset) {
|
||||
return ContentType$.MODULE$.apply((akka.http.scaladsl.model.MediaType.WithOpenCharset) mediaType,
|
||||
(akka.http.scaladsl.model.HttpCharset) charset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public final class FormData {
|
|||
* Converts this FormData to a RequestEntity using the given encoding.
|
||||
*/
|
||||
public RequestEntity toEntity(HttpCharset charset) {
|
||||
return HttpEntities.create(ContentType.create(MediaTypes.APPLICATION_X_WWW_FORM_URLENCODED, charset), fields.render(charset));
|
||||
return HttpEntities.create(ContentTypes.create(MediaTypes.APPLICATION_X_WWW_FORM_URLENCODED, charset), fields.render(charset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ package akka.http.javadsl.model;
|
|||
* charset. {@link HttpCharsetRanges} contains static constructors for HttpCharsetRanges.
|
||||
*/
|
||||
public abstract class HttpCharsetRange {
|
||||
/**
|
||||
* Returns if this range matches all charsets.
|
||||
*/
|
||||
public abstract boolean matchesAll();
|
||||
|
||||
/**
|
||||
* The qValue for this range.
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ public final class HttpEntities {
|
|||
return HttpEntity$.MODULE$.apply(bytes);
|
||||
}
|
||||
|
||||
public static HttpEntityStrict create(ContentType contentType, String string) {
|
||||
return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType) contentType, string);
|
||||
public static HttpEntityStrict create(ContentType.NonBinary contentType, String string) {
|
||||
return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType.NonBinary) contentType, string);
|
||||
}
|
||||
|
||||
public static HttpEntityStrict create(ContentType contentType, byte[] bytes) {
|
||||
|
|
@ -52,7 +52,7 @@ public final class HttpEntities {
|
|||
return new akka.http.scaladsl.model.HttpEntity.Default((akka.http.scaladsl.model.ContentType) contentType, contentLength, data.asScala());
|
||||
}
|
||||
|
||||
public static HttpEntity.Chunked create(ContentType contentType, Source<ByteString, Object> data) {
|
||||
public static HttpEntityChunked create(ContentType contentType, Source<ByteString, Object> data) {
|
||||
return HttpEntity.Chunked$.MODULE$.fromData((akka.http.scaladsl.model.ContentType) contentType, data.asScala());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,48 +40,48 @@ public interface HttpEntity {
|
|||
/**
|
||||
* Returns the content-type of this entity
|
||||
*/
|
||||
public abstract ContentType contentType();
|
||||
ContentType contentType();
|
||||
|
||||
/**
|
||||
* The empty entity.
|
||||
*/
|
||||
public static final HttpEntityStrict EMPTY = HttpEntity$.MODULE$.Empty();
|
||||
HttpEntityStrict EMPTY = HttpEntity$.MODULE$.Empty();
|
||||
|
||||
/**
|
||||
* Returns if this entity is known to be empty. Open-ended entity types like
|
||||
* HttpEntityChunked and HttpCloseDelimited will always return false here.
|
||||
*/
|
||||
public abstract boolean isKnownEmpty();
|
||||
boolean isKnownEmpty();
|
||||
|
||||
/**
|
||||
* Returns if this entity is a subtype of HttpEntityChunked.
|
||||
*/
|
||||
public abstract boolean isChunked();
|
||||
boolean isChunked();
|
||||
|
||||
/**
|
||||
* Returns if this entity is a subtype of HttpEntityDefault.
|
||||
*/
|
||||
public abstract boolean isDefault();
|
||||
boolean isDefault();
|
||||
|
||||
/**
|
||||
* Returns if this entity is a subtype of HttpEntityCloseDelimited.
|
||||
*/
|
||||
public abstract boolean isCloseDelimited();
|
||||
boolean isCloseDelimited();
|
||||
|
||||
/**
|
||||
* Returns if this entity is a subtype of HttpEntityIndefiniteLength.
|
||||
*/
|
||||
public abstract boolean isIndefiniteLength();
|
||||
boolean isIndefiniteLength();
|
||||
|
||||
/**
|
||||
* Returns Some(contentLength) if the length is defined and none otherwise.
|
||||
*/
|
||||
public abstract Option<Long> getContentLengthOption();
|
||||
Option<Long> getContentLengthOption();
|
||||
|
||||
/**
|
||||
* Returns a stream of data bytes this entity consists of.
|
||||
*/
|
||||
public abstract Source<ByteString, Object> getDataBytes();
|
||||
Source<ByteString, Object> getDataBytes();
|
||||
|
||||
/**
|
||||
* Returns a future of a strict entity that contains the same data as this entity
|
||||
|
|
@ -92,5 +92,5 @@ public interface HttpEntity {
|
|||
* Use getDataBytes and stream processing instead if the expected data is big or
|
||||
* is likely to take a long time.
|
||||
*/
|
||||
public abstract Future<HttpEntityStrict> toStrict(long timeoutMillis, Materializer materializer);
|
||||
Future<HttpEntityStrict> toStrict(long timeoutMillis, Materializer materializer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public interface HttpMessage {
|
|||
/**
|
||||
* Returns a copy of Self message with a new entity.
|
||||
*/
|
||||
Self withEntity(ContentType type, String string);
|
||||
Self withEntity(ContentType.NonBinary type, String string);
|
||||
|
||||
/**
|
||||
* Returns a copy of Self message with a new entity.
|
||||
|
|
|
|||
|
|
@ -7,33 +7,61 @@ package akka.http.javadsl.model;
|
|||
/**
|
||||
* Represents an Http media-type. A media-type consists of a main-type and a sub-type.
|
||||
*/
|
||||
public abstract class MediaType {
|
||||
/**
|
||||
* Returns the main-type of this media-type.
|
||||
*/
|
||||
public abstract String mainType();
|
||||
public interface MediaType {
|
||||
|
||||
/**
|
||||
* Returns the sub-type of this media-type.
|
||||
* The main-type of this media-type.
|
||||
*/
|
||||
public abstract String subType();
|
||||
String mainType();
|
||||
|
||||
/**
|
||||
* The sub-type of this media-type.
|
||||
*/
|
||||
String subType();
|
||||
|
||||
/**
|
||||
* True when this media-type is generally compressible.
|
||||
*/
|
||||
boolean compressible();
|
||||
|
||||
/**
|
||||
* True when this media-type is not character-based.
|
||||
*/
|
||||
boolean binary();
|
||||
|
||||
boolean isApplication();
|
||||
boolean isAudio();
|
||||
boolean isImage();
|
||||
boolean isMessage();
|
||||
boolean isMultipart();
|
||||
boolean isText();
|
||||
boolean isVideo();
|
||||
|
||||
/**
|
||||
* Creates a media-range from this media-type.
|
||||
*/
|
||||
public MediaRange toRange() {
|
||||
return MediaRanges.create(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContentType from this media-type
|
||||
*/
|
||||
public ContentType toContentType() { return ContentType.create(this); }
|
||||
MediaRange toRange();
|
||||
|
||||
/**
|
||||
* Creates a media-range from this media-type with a given qValue.
|
||||
*/
|
||||
public MediaRange toRange(float qValue) {
|
||||
return MediaRanges.create(this, qValue);
|
||||
MediaRange toRange(float qValue);
|
||||
|
||||
interface Binary extends MediaType {
|
||||
ContentType.Binary toContentType();
|
||||
}
|
||||
|
||||
interface NonBinary extends MediaType {
|
||||
}
|
||||
|
||||
interface WithFixedCharset extends NonBinary {
|
||||
ContentType.WithFixedCharset toContentType();
|
||||
}
|
||||
|
||||
interface WithOpenCharset extends NonBinary {
|
||||
ContentType.WithCharset toContentType(HttpCharset charset);
|
||||
}
|
||||
|
||||
interface Multipart extends WithOpenCharset {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,189 +7,188 @@ package akka.http.javadsl.model;
|
|||
import akka.http.impl.util.Util;
|
||||
import akka.http.scaladsl.model.MediaTypes$;
|
||||
import akka.japi.Option;
|
||||
|
||||
import java.util.Map;
|
||||
import scala.collection.immutable.List;
|
||||
|
||||
/**
|
||||
* Contains the set of predefined media-types.
|
||||
*/
|
||||
public abstract class MediaTypes {
|
||||
public static final MediaType APPLICATION_ATOM_XML = akka.http.scaladsl.model.MediaTypes.application$divatom$plusxml();
|
||||
public static final MediaType APPLICATION_BASE64 = akka.http.scaladsl.model.MediaTypes.application$divbase64();
|
||||
public static final MediaType APPLICATION_EXCEL = akka.http.scaladsl.model.MediaTypes.application$divexcel();
|
||||
public static final MediaType APPLICATION_FONT_WOFF = akka.http.scaladsl.model.MediaTypes.application$divfont$minuswoff();
|
||||
public static final MediaType APPLICATION_GNUTAR = akka.http.scaladsl.model.MediaTypes.application$divgnutar();
|
||||
public static final MediaType APPLICATION_JAVA_ARCHIVE = akka.http.scaladsl.model.MediaTypes.application$divjava$minusarchive();
|
||||
public static final MediaType APPLICATION_JAVASCRIPT = akka.http.scaladsl.model.MediaTypes.application$divjavascript();
|
||||
public static final MediaType APPLICATION_JSON = akka.http.scaladsl.model.MediaTypes.application$divjson();
|
||||
public static final MediaType APPLICATION_JSON_PATCH_JSON = akka.http.scaladsl.model.MediaTypes.application$divjson$minuspatch$plusjson();
|
||||
public static final MediaType APPLICATION_LHA = akka.http.scaladsl.model.MediaTypes.application$divlha();
|
||||
public static final MediaType APPLICATION_LZX = akka.http.scaladsl.model.MediaTypes.application$divlzx();
|
||||
public static final MediaType APPLICATION_MSPOWERPOINT = akka.http.scaladsl.model.MediaTypes.application$divmspowerpoint();
|
||||
public static final MediaType APPLICATION_MSWORD = akka.http.scaladsl.model.MediaTypes.application$divmsword();
|
||||
public static final MediaType APPLICATION_OCTET_STREAM = akka.http.scaladsl.model.MediaTypes.application$divoctet$minusstream();
|
||||
public static final MediaType APPLICATION_PDF = akka.http.scaladsl.model.MediaTypes.application$divpdf();
|
||||
public static final MediaType APPLICATION_POSTSCRIPT = akka.http.scaladsl.model.MediaTypes.application$divpostscript();
|
||||
public static final MediaType APPLICATION_RSS_XML = akka.http.scaladsl.model.MediaTypes.application$divrss$plusxml();
|
||||
public static final MediaType APPLICATION_SOAP_XML = akka.http.scaladsl.model.MediaTypes.application$divsoap$plusxml();
|
||||
public static final MediaType APPLICATION_VND_API_JSON = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eapi$plusjson();
|
||||
public static final MediaType APPLICATION_VND_GOOGLE_EARTH_KML_XML = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Egoogle$minusearth$u002Ekml$plusxml();
|
||||
public static final MediaType APPLICATION_VND_GOOGLE_EARTH_KMZ = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Egoogle$minusearth$u002Ekmz();
|
||||
public static final MediaType APPLICATION_VND_MS_FONTOBJECT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Ems$minusfontobject();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_CHART = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Echart();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_DATABASE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Edatabase();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_FORMULA = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Eformula();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_GRAPHICS = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Egraphics();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_IMAGE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Eimage();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_PRESENTATION = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Epresentation();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_SPREADSHEET = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Espreadsheet();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT_MASTER = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext$minusmaster();
|
||||
public static final MediaType APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT_WEB = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext$minusweb();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_PRESENTATION = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Epresentation();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_SLIDE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Eslide();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_SLIDESHOW = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Eslideshow();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Etemplate();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_SHEET = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Espreadsheetml$u002Esheet();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Espreadsheetml$u002Etemplate();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_DOCUMENT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Ewordprocessingml$u002Edocument();
|
||||
public static final MediaType APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Ewordprocessingml$u002Etemplate();
|
||||
public static final MediaType APPLICATION_X_7Z_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minus7z$minuscompressed();
|
||||
public static final MediaType APPLICATION_X_ACE_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusace$minuscompressed();
|
||||
public static final MediaType APPLICATION_X_APPLE_DISKIMAGE = akka.http.scaladsl.model.MediaTypes.application$divx$minusapple$minusdiskimage();
|
||||
public static final MediaType APPLICATION_X_ARC_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusarc$minuscompressed();
|
||||
public static final MediaType APPLICATION_X_BZIP = akka.http.scaladsl.model.MediaTypes.application$divx$minusbzip();
|
||||
public static final MediaType APPLICATION_X_BZIP2 = akka.http.scaladsl.model.MediaTypes.application$divx$minusbzip2();
|
||||
public static final MediaType APPLICATION_X_CHROME_EXTENSION = akka.http.scaladsl.model.MediaTypes.application$divx$minuschrome$minusextension();
|
||||
public static final MediaType APPLICATION_X_COMPRESS = akka.http.scaladsl.model.MediaTypes.application$divx$minuscompress();
|
||||
public static final MediaType APPLICATION_X_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minuscompressed();
|
||||
public static final MediaType APPLICATION_X_DEBIAN_PACKAGE = akka.http.scaladsl.model.MediaTypes.application$divx$minusdebian$minuspackage();
|
||||
public static final MediaType APPLICATION_X_DVI = akka.http.scaladsl.model.MediaTypes.application$divx$minusdvi();
|
||||
public static final MediaType APPLICATION_X_FONT_TRUETYPE = akka.http.scaladsl.model.MediaTypes.application$divx$minusfont$minustruetype();
|
||||
public static final MediaType APPLICATION_X_FONT_OPENTYPE = akka.http.scaladsl.model.MediaTypes.application$divx$minusfont$minusopentype();
|
||||
public static final MediaType APPLICATION_X_GTAR = akka.http.scaladsl.model.MediaTypes.application$divx$minusgtar();
|
||||
public static final MediaType APPLICATION_X_GZIP = akka.http.scaladsl.model.MediaTypes.application$divx$minusgzip();
|
||||
public static final MediaType APPLICATION_X_LATEX = akka.http.scaladsl.model.MediaTypes.application$divx$minuslatex();
|
||||
public static final MediaType APPLICATION_X_RAR_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusrar$minuscompressed();
|
||||
public static final MediaType APPLICATION_X_REDHAT_PACKAGE_MANAGER = akka.http.scaladsl.model.MediaTypes.application$divx$minusredhat$minuspackage$minusmanager();
|
||||
public static final MediaType APPLICATION_X_SHOCKWAVE_FLASH = akka.http.scaladsl.model.MediaTypes.application$divx$minusshockwave$minusflash();
|
||||
public static final MediaType APPLICATION_X_TAR = akka.http.scaladsl.model.MediaTypes.application$divx$minustar();
|
||||
public static final MediaType APPLICATION_X_TEX = akka.http.scaladsl.model.MediaTypes.application$divx$minustex();
|
||||
public static final MediaType APPLICATION_X_TEXINFO = akka.http.scaladsl.model.MediaTypes.application$divx$minustexinfo();
|
||||
public static final MediaType APPLICATION_X_VRML = akka.http.scaladsl.model.MediaTypes.application$divx$minusvrml();
|
||||
public static final MediaType APPLICATION_X_WWW_FORM_URLENCODED = akka.http.scaladsl.model.MediaTypes.application$divx$minuswww$minusform$minusurlencoded();
|
||||
public static final MediaType APPLICATION_X_X509_CA_CERT = akka.http.scaladsl.model.MediaTypes.application$divx$minusx509$minusca$minuscert();
|
||||
public static final MediaType APPLICATION_X_XPINSTALL = akka.http.scaladsl.model.MediaTypes.application$divx$minusxpinstall();
|
||||
public static final MediaType APPLICATION_XHTML_XML = akka.http.scaladsl.model.MediaTypes.application$divxhtml$plusxml();
|
||||
public static final MediaType APPLICATION_XML_DTD = akka.http.scaladsl.model.MediaTypes.application$divxml$minusdtd();
|
||||
public static final MediaType APPLICATION_XML = akka.http.scaladsl.model.MediaTypes.application$divxml();
|
||||
public static final MediaType APPLICATION_ZIP = akka.http.scaladsl.model.MediaTypes.application$divzip();
|
||||
public static final MediaType AUDIO_AIFF = akka.http.scaladsl.model.MediaTypes.audio$divaiff();
|
||||
public static final MediaType AUDIO_BASIC = akka.http.scaladsl.model.MediaTypes.audio$divbasic();
|
||||
public static final MediaType AUDIO_MIDI = akka.http.scaladsl.model.MediaTypes.audio$divmidi();
|
||||
public static final MediaType AUDIO_MOD = akka.http.scaladsl.model.MediaTypes.audio$divmod();
|
||||
public static final MediaType AUDIO_MPEG = akka.http.scaladsl.model.MediaTypes.audio$divmpeg();
|
||||
public static final MediaType AUDIO_OGG = akka.http.scaladsl.model.MediaTypes.audio$divogg();
|
||||
public static final MediaType AUDIO_VOC = akka.http.scaladsl.model.MediaTypes.audio$divvoc();
|
||||
public static final MediaType AUDIO_VORBIS = akka.http.scaladsl.model.MediaTypes.audio$divvorbis();
|
||||
public static final MediaType AUDIO_VOXWARE = akka.http.scaladsl.model.MediaTypes.audio$divvoxware();
|
||||
public static final MediaType AUDIO_WAV = akka.http.scaladsl.model.MediaTypes.audio$divwav();
|
||||
public static final MediaType AUDIO_X_REALAUDIO = akka.http.scaladsl.model.MediaTypes.audio$divx$minusrealaudio();
|
||||
public static final MediaType AUDIO_X_PSID = akka.http.scaladsl.model.MediaTypes.audio$divx$minuspsid();
|
||||
public static final MediaType AUDIO_XM = akka.http.scaladsl.model.MediaTypes.audio$divxm();
|
||||
public static final MediaType AUDIO_WEBM = akka.http.scaladsl.model.MediaTypes.audio$divwebm();
|
||||
public static final MediaType IMAGE_GIF = akka.http.scaladsl.model.MediaTypes.image$divgif();
|
||||
public static final MediaType IMAGE_JPEG = akka.http.scaladsl.model.MediaTypes.image$divjpeg();
|
||||
public static final MediaType IMAGE_PICT = akka.http.scaladsl.model.MediaTypes.image$divpict();
|
||||
public static final MediaType IMAGE_PNG = akka.http.scaladsl.model.MediaTypes.image$divpng();
|
||||
public static final MediaType IMAGE_SVG_XML = akka.http.scaladsl.model.MediaTypes.image$divsvg$plusxml();
|
||||
public static final MediaType IMAGE_TIFF = akka.http.scaladsl.model.MediaTypes.image$divtiff();
|
||||
public static final MediaType IMAGE_X_ICON = akka.http.scaladsl.model.MediaTypes.image$divx$minusicon();
|
||||
public static final MediaType IMAGE_X_MS_BMP = akka.http.scaladsl.model.MediaTypes.image$divx$minusms$minusbmp();
|
||||
public static final MediaType IMAGE_X_PCX = akka.http.scaladsl.model.MediaTypes.image$divx$minuspcx();
|
||||
public static final MediaType IMAGE_X_PICT = akka.http.scaladsl.model.MediaTypes.image$divx$minuspict();
|
||||
public static final MediaType IMAGE_X_QUICKTIME = akka.http.scaladsl.model.MediaTypes.image$divx$minusquicktime();
|
||||
public static final MediaType IMAGE_X_RGB = akka.http.scaladsl.model.MediaTypes.image$divx$minusrgb();
|
||||
public static final MediaType IMAGE_X_XBITMAP = akka.http.scaladsl.model.MediaTypes.image$divx$minusxbitmap();
|
||||
public static final MediaType IMAGE_X_XPIXMAP = akka.http.scaladsl.model.MediaTypes.image$divx$minusxpixmap();
|
||||
public static final MediaType IMAGE_WEBP = akka.http.scaladsl.model.MediaTypes.image$divwebp();
|
||||
public static final MediaType MESSAGE_HTTP = akka.http.scaladsl.model.MediaTypes.message$divhttp();
|
||||
public static final MediaType MESSAGE_DELIVERY_STATUS = akka.http.scaladsl.model.MediaTypes.message$divdelivery$minusstatus();
|
||||
public static final MediaType MESSAGE_RFC822 = akka.http.scaladsl.model.MediaTypes.message$divrfc822();
|
||||
public static final MediaType MULTIPART_MIXED = akka.http.scaladsl.model.MediaTypes.multipart$divmixed();
|
||||
public static final MediaType MULTIPART_ALTERNATIVE = akka.http.scaladsl.model.MediaTypes.multipart$divalternative();
|
||||
public static final MediaType MULTIPART_RELATED = akka.http.scaladsl.model.MediaTypes.multipart$divrelated();
|
||||
public static final MediaType MULTIPART_FORM_DATA = akka.http.scaladsl.model.MediaTypes.multipart$divform$minusdata();
|
||||
public static final MediaType MULTIPART_SIGNED = akka.http.scaladsl.model.MediaTypes.multipart$divsigned();
|
||||
public static final MediaType MULTIPART_ENCRYPTED = akka.http.scaladsl.model.MediaTypes.multipart$divencrypted();
|
||||
public static final MediaType MULTIPART_BYTERANGES = akka.http.scaladsl.model.MediaTypes.multipart$divbyteranges();
|
||||
public static final MediaType TEXT_ASP = akka.http.scaladsl.model.MediaTypes.text$divasp();
|
||||
public static final MediaType TEXT_CACHE_MANIFEST = akka.http.scaladsl.model.MediaTypes.text$divcache$minusmanifest();
|
||||
public static final MediaType TEXT_CALENDAR = akka.http.scaladsl.model.MediaTypes.text$divcalendar();
|
||||
public static final MediaType TEXT_CSS = akka.http.scaladsl.model.MediaTypes.text$divcss();
|
||||
public static final MediaType TEXT_CSV = akka.http.scaladsl.model.MediaTypes.text$divcsv();
|
||||
public static final MediaType TEXT_HTML = akka.http.scaladsl.model.MediaTypes.text$divhtml();
|
||||
public static final MediaType TEXT_MCF = akka.http.scaladsl.model.MediaTypes.text$divmcf();
|
||||
public static final MediaType TEXT_PLAIN = akka.http.scaladsl.model.MediaTypes.text$divplain();
|
||||
public static final MediaType TEXT_RICHTEXT = akka.http.scaladsl.model.MediaTypes.text$divrichtext();
|
||||
public static final MediaType TEXT_TAB_SEPARATED_VALUES = akka.http.scaladsl.model.MediaTypes.text$divtab$minusseparated$minusvalues();
|
||||
public static final MediaType TEXT_URI_LIST = akka.http.scaladsl.model.MediaTypes.text$divuri$minuslist();
|
||||
public static final MediaType TEXT_VND_WAP_WML = akka.http.scaladsl.model.MediaTypes.text$divvnd$u002Ewap$u002Ewml();
|
||||
public static final MediaType TEXT_VND_WAP_WMLSCRIPT = akka.http.scaladsl.model.MediaTypes.text$divvnd$u002Ewap$u002Ewmlscript();
|
||||
public static final MediaType TEXT_X_ASM = akka.http.scaladsl.model.MediaTypes.text$divx$minusasm();
|
||||
public static final MediaType TEXT_X_C = akka.http.scaladsl.model.MediaTypes.text$divx$minusc();
|
||||
public static final MediaType TEXT_X_COMPONENT = akka.http.scaladsl.model.MediaTypes.text$divx$minuscomponent();
|
||||
public static final MediaType TEXT_X_H = akka.http.scaladsl.model.MediaTypes.text$divx$minush();
|
||||
public static final MediaType TEXT_X_JAVA_SOURCE = akka.http.scaladsl.model.MediaTypes.text$divx$minusjava$minussource();
|
||||
public static final MediaType TEXT_X_PASCAL = akka.http.scaladsl.model.MediaTypes.text$divx$minuspascal();
|
||||
public static final MediaType TEXT_X_SCRIPT = akka.http.scaladsl.model.MediaTypes.text$divx$minusscript();
|
||||
public static final MediaType TEXT_X_SCRIPTCSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptcsh();
|
||||
public static final MediaType TEXT_X_SCRIPTELISP = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptelisp();
|
||||
public static final MediaType TEXT_X_SCRIPTKSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptksh();
|
||||
public static final MediaType TEXT_X_SCRIPTLISP = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptlisp();
|
||||
public static final MediaType TEXT_X_SCRIPTPERL = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptperl();
|
||||
public static final MediaType TEXT_X_SCRIPTPERL_MODULE = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptperl$minusmodule();
|
||||
public static final MediaType TEXT_X_SCRIPTPHYTON = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptphyton();
|
||||
public static final MediaType TEXT_X_SCRIPTREXX = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptrexx();
|
||||
public static final MediaType TEXT_X_SCRIPTSCHEME = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptscheme();
|
||||
public static final MediaType TEXT_X_SCRIPTSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptsh();
|
||||
public static final MediaType TEXT_X_SCRIPTTCL = akka.http.scaladsl.model.MediaTypes.text$divx$minusscripttcl();
|
||||
public static final MediaType TEXT_X_SCRIPTTCSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscripttcsh();
|
||||
public static final MediaType TEXT_X_SCRIPTZSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptzsh();
|
||||
public static final MediaType TEXT_X_SERVER_PARSED_HTML = akka.http.scaladsl.model.MediaTypes.text$divx$minusserver$minusparsed$minushtml();
|
||||
public static final MediaType TEXT_X_SETEXT = akka.http.scaladsl.model.MediaTypes.text$divx$minussetext();
|
||||
public static final MediaType TEXT_X_SGML = akka.http.scaladsl.model.MediaTypes.text$divx$minussgml();
|
||||
public static final MediaType TEXT_X_SPEECH = akka.http.scaladsl.model.MediaTypes.text$divx$minusspeech();
|
||||
public static final MediaType TEXT_X_UUENCODE = akka.http.scaladsl.model.MediaTypes.text$divx$minusuuencode();
|
||||
public static final MediaType TEXT_X_VCALENDAR = akka.http.scaladsl.model.MediaTypes.text$divx$minusvcalendar();
|
||||
public static final MediaType TEXT_X_VCARD = akka.http.scaladsl.model.MediaTypes.text$divx$minusvcard();
|
||||
public static final MediaType TEXT_XML = akka.http.scaladsl.model.MediaTypes.text$divxml();
|
||||
public static final MediaType VIDEO_AVS_VIDEO = akka.http.scaladsl.model.MediaTypes.video$divavs$minusvideo();
|
||||
public static final MediaType VIDEO_DIVX = akka.http.scaladsl.model.MediaTypes.video$divdivx();
|
||||
public static final MediaType VIDEO_GL = akka.http.scaladsl.model.MediaTypes.video$divgl();
|
||||
public static final MediaType VIDEO_MP4 = akka.http.scaladsl.model.MediaTypes.video$divmp4();
|
||||
public static final MediaType VIDEO_MPEG = akka.http.scaladsl.model.MediaTypes.video$divmpeg();
|
||||
public static final MediaType VIDEO_OGG = akka.http.scaladsl.model.MediaTypes.video$divogg();
|
||||
public static final MediaType VIDEO_QUICKTIME = akka.http.scaladsl.model.MediaTypes.video$divquicktime();
|
||||
public static final MediaType VIDEO_X_DV = akka.http.scaladsl.model.MediaTypes.video$divx$minusdv();
|
||||
public static final MediaType VIDEO_X_FLV = akka.http.scaladsl.model.MediaTypes.video$divx$minusflv();
|
||||
public static final MediaType VIDEO_X_MOTION_JPEG = akka.http.scaladsl.model.MediaTypes.video$divx$minusmotion$minusjpeg();
|
||||
public static final MediaType VIDEO_X_MS_ASF = akka.http.scaladsl.model.MediaTypes.video$divx$minusms$minusasf();
|
||||
public static final MediaType VIDEO_X_MSVIDEO = akka.http.scaladsl.model.MediaTypes.video$divx$minusmsvideo();
|
||||
public static final MediaType VIDEO_X_SGI_MOVIE = akka.http.scaladsl.model.MediaTypes.video$divx$minussgi$minusmovie();
|
||||
public static final MediaType VIDEO_WEBM = akka.http.scaladsl.model.MediaTypes.video$divwebm();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_ATOM_XML = akka.http.scaladsl.model.MediaTypes.application$divatom$plusxml();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_BASE64 = akka.http.scaladsl.model.MediaTypes.application$divbase64();
|
||||
public static final MediaType.Binary APPLICATION_EXCEL = akka.http.scaladsl.model.MediaTypes.application$divexcel();
|
||||
public static final MediaType.Binary APPLICATION_FONT_WOFF = akka.http.scaladsl.model.MediaTypes.application$divfont$minuswoff();
|
||||
public static final MediaType.Binary APPLICATION_GNUTAR = akka.http.scaladsl.model.MediaTypes.application$divgnutar();
|
||||
public static final MediaType.Binary APPLICATION_JAVA_ARCHIVE = akka.http.scaladsl.model.MediaTypes.application$divjava$minusarchive();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_JAVASCRIPT = akka.http.scaladsl.model.MediaTypes.application$divjavascript();
|
||||
public static final MediaType.WithFixedCharset APPLICATION_JSON = akka.http.scaladsl.model.MediaTypes.application$divjson();
|
||||
public static final MediaType.WithFixedCharset APPLICATION_JSON_PATCH_JSON = akka.http.scaladsl.model.MediaTypes.application$divjson$minuspatch$plusjson();
|
||||
public static final MediaType.Binary APPLICATION_LHA = akka.http.scaladsl.model.MediaTypes.application$divlha();
|
||||
public static final MediaType.Binary APPLICATION_LZX = akka.http.scaladsl.model.MediaTypes.application$divlzx();
|
||||
public static final MediaType.Binary APPLICATION_MSPOWERPOINT = akka.http.scaladsl.model.MediaTypes.application$divmspowerpoint();
|
||||
public static final MediaType.Binary APPLICATION_MSWORD = akka.http.scaladsl.model.MediaTypes.application$divmsword();
|
||||
public static final MediaType.Binary APPLICATION_OCTET_STREAM = akka.http.scaladsl.model.MediaTypes.application$divoctet$minusstream();
|
||||
public static final MediaType.Binary APPLICATION_PDF = akka.http.scaladsl.model.MediaTypes.application$divpdf();
|
||||
public static final MediaType.Binary APPLICATION_POSTSCRIPT = akka.http.scaladsl.model.MediaTypes.application$divpostscript();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_RSS_XML = akka.http.scaladsl.model.MediaTypes.application$divrss$plusxml();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_SOAP_XML = akka.http.scaladsl.model.MediaTypes.application$divsoap$plusxml();
|
||||
public static final MediaType.WithFixedCharset APPLICATION_VND_API_JSON = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eapi$plusjson();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_VND_GOOGLE_EARTH_KML_XML = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Egoogle$minusearth$u002Ekml$plusxml();
|
||||
public static final MediaType.Binary APPLICATION_VND_GOOGLE_EARTH_KMZ = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Egoogle$minusearth$u002Ekmz();
|
||||
public static final MediaType.Binary APPLICATION_VND_MS_FONTOBJECT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Ems$minusfontobject();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_CHART = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Echart();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_DATABASE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Edatabase();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_FORMULA = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Eformula();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_GRAPHICS = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Egraphics();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_IMAGE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Eimage();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_PRESENTATION = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Epresentation();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_SPREADSHEET = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Espreadsheet();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT_MASTER = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext$minusmaster();
|
||||
public static final MediaType.Binary APPLICATION_VND_OASIS_OPENDOCUMENT_TEXT_WEB = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eoasis$u002Eopendocument$u002Etext$minusweb();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_PRESENTATION = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Epresentation();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_SLIDE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Eslide();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_SLIDESHOW = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Eslideshow();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Epresentationml$u002Etemplate();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_SHEET = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Espreadsheetml$u002Esheet();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Espreadsheetml$u002Etemplate();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_DOCUMENT = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Ewordprocessingml$u002Edocument();
|
||||
public static final MediaType.Binary APPLICATION_VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_TEMPLATE = akka.http.scaladsl.model.MediaTypes.application$divvnd$u002Eopenxmlformats$minusofficedocument$u002Ewordprocessingml$u002Etemplate();
|
||||
public static final MediaType.Binary APPLICATION_X_7Z_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minus7z$minuscompressed();
|
||||
public static final MediaType.Binary APPLICATION_X_ACE_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusace$minuscompressed();
|
||||
public static final MediaType.Binary APPLICATION_X_APPLE_DISKIMAGE = akka.http.scaladsl.model.MediaTypes.application$divx$minusapple$minusdiskimage();
|
||||
public static final MediaType.Binary APPLICATION_X_ARC_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusarc$minuscompressed();
|
||||
public static final MediaType.Binary APPLICATION_X_BZIP = akka.http.scaladsl.model.MediaTypes.application$divx$minusbzip();
|
||||
public static final MediaType.Binary APPLICATION_X_BZIP2 = akka.http.scaladsl.model.MediaTypes.application$divx$minusbzip2();
|
||||
public static final MediaType.Binary APPLICATION_X_CHROME_EXTENSION = akka.http.scaladsl.model.MediaTypes.application$divx$minuschrome$minusextension();
|
||||
public static final MediaType.Binary APPLICATION_X_COMPRESS = akka.http.scaladsl.model.MediaTypes.application$divx$minuscompress();
|
||||
public static final MediaType.Binary APPLICATION_X_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minuscompressed();
|
||||
public static final MediaType.Binary APPLICATION_X_DEBIAN_PACKAGE = akka.http.scaladsl.model.MediaTypes.application$divx$minusdebian$minuspackage();
|
||||
public static final MediaType.Binary APPLICATION_X_DVI = akka.http.scaladsl.model.MediaTypes.application$divx$minusdvi();
|
||||
public static final MediaType.Binary APPLICATION_X_FONT_TRUETYPE = akka.http.scaladsl.model.MediaTypes.application$divx$minusfont$minustruetype();
|
||||
public static final MediaType.Binary APPLICATION_X_FONT_OPENTYPE = akka.http.scaladsl.model.MediaTypes.application$divx$minusfont$minusopentype();
|
||||
public static final MediaType.Binary APPLICATION_X_GTAR = akka.http.scaladsl.model.MediaTypes.application$divx$minusgtar();
|
||||
public static final MediaType.Binary APPLICATION_X_GZIP = akka.http.scaladsl.model.MediaTypes.application$divx$minusgzip();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_X_LATEX = akka.http.scaladsl.model.MediaTypes.application$divx$minuslatex();
|
||||
public static final MediaType.Binary APPLICATION_X_RAR_COMPRESSED = akka.http.scaladsl.model.MediaTypes.application$divx$minusrar$minuscompressed();
|
||||
public static final MediaType.Binary APPLICATION_X_REDHAT_PACKAGE_MANAGER = akka.http.scaladsl.model.MediaTypes.application$divx$minusredhat$minuspackage$minusmanager();
|
||||
public static final MediaType.Binary APPLICATION_X_SHOCKWAVE_FLASH = akka.http.scaladsl.model.MediaTypes.application$divx$minusshockwave$minusflash();
|
||||
public static final MediaType.Binary APPLICATION_X_TAR = akka.http.scaladsl.model.MediaTypes.application$divx$minustar();
|
||||
public static final MediaType.Binary APPLICATION_X_TEX = akka.http.scaladsl.model.MediaTypes.application$divx$minustex();
|
||||
public static final MediaType.Binary APPLICATION_X_TEXINFO = akka.http.scaladsl.model.MediaTypes.application$divx$minustexinfo();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_X_VRML = akka.http.scaladsl.model.MediaTypes.application$divx$minusvrml();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_X_WWW_FORM_URLENCODED = akka.http.scaladsl.model.MediaTypes.application$divx$minuswww$minusform$minusurlencoded();
|
||||
public static final MediaType.Binary APPLICATION_X_X509_CA_CERT = akka.http.scaladsl.model.MediaTypes.application$divx$minusx509$minusca$minuscert();
|
||||
public static final MediaType.Binary APPLICATION_X_XPINSTALL = akka.http.scaladsl.model.MediaTypes.application$divx$minusxpinstall();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_XHTML_XML = akka.http.scaladsl.model.MediaTypes.application$divxhtml$plusxml();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_XML_DTD = akka.http.scaladsl.model.MediaTypes.application$divxml$minusdtd();
|
||||
public static final MediaType.WithOpenCharset APPLICATION_XML = akka.http.scaladsl.model.MediaTypes.application$divxml();
|
||||
public static final MediaType.Binary APPLICATION_ZIP = akka.http.scaladsl.model.MediaTypes.application$divzip();
|
||||
|
||||
public static final MediaType.Binary AUDIO_AIFF = akka.http.scaladsl.model.MediaTypes.audio$divaiff();
|
||||
public static final MediaType.Binary AUDIO_BASIC = akka.http.scaladsl.model.MediaTypes.audio$divbasic();
|
||||
public static final MediaType.Binary AUDIO_MIDI = akka.http.scaladsl.model.MediaTypes.audio$divmidi();
|
||||
public static final MediaType.Binary AUDIO_MOD = akka.http.scaladsl.model.MediaTypes.audio$divmod();
|
||||
public static final MediaType.Binary AUDIO_MPEG = akka.http.scaladsl.model.MediaTypes.audio$divmpeg();
|
||||
public static final MediaType.Binary AUDIO_OGG = akka.http.scaladsl.model.MediaTypes.audio$divogg();
|
||||
public static final MediaType.Binary AUDIO_VOC = akka.http.scaladsl.model.MediaTypes.audio$divvoc();
|
||||
public static final MediaType.Binary AUDIO_VORBIS = akka.http.scaladsl.model.MediaTypes.audio$divvorbis();
|
||||
public static final MediaType.Binary AUDIO_VOXWARE = akka.http.scaladsl.model.MediaTypes.audio$divvoxware();
|
||||
public static final MediaType.Binary AUDIO_WAV = akka.http.scaladsl.model.MediaTypes.audio$divwav();
|
||||
public static final MediaType.Binary AUDIO_X_REALAUDIO = akka.http.scaladsl.model.MediaTypes.audio$divx$minusrealaudio();
|
||||
public static final MediaType.Binary AUDIO_X_PSID = akka.http.scaladsl.model.MediaTypes.audio$divx$minuspsid();
|
||||
public static final MediaType.Binary AUDIO_XM = akka.http.scaladsl.model.MediaTypes.audio$divxm();
|
||||
public static final MediaType.Binary AUDIO_WEBM = akka.http.scaladsl.model.MediaTypes.audio$divwebm();
|
||||
|
||||
public static final MediaType.Binary IMAGE_GIF = akka.http.scaladsl.model.MediaTypes.image$divgif();
|
||||
public static final MediaType.Binary IMAGE_JPEG = akka.http.scaladsl.model.MediaTypes.image$divjpeg();
|
||||
public static final MediaType.Binary IMAGE_PICT = akka.http.scaladsl.model.MediaTypes.image$divpict();
|
||||
public static final MediaType.Binary IMAGE_PNG = akka.http.scaladsl.model.MediaTypes.image$divpng();
|
||||
public static final MediaType.Binary IMAGE_SVG_XML = akka.http.scaladsl.model.MediaTypes.image$divsvg$plusxml();
|
||||
public static final MediaType.Binary IMAGE_TIFF = akka.http.scaladsl.model.MediaTypes.image$divtiff();
|
||||
public static final MediaType.Binary IMAGE_X_ICON = akka.http.scaladsl.model.MediaTypes.image$divx$minusicon();
|
||||
public static final MediaType.Binary IMAGE_X_MS_BMP = akka.http.scaladsl.model.MediaTypes.image$divx$minusms$minusbmp();
|
||||
public static final MediaType.Binary IMAGE_X_PCX = akka.http.scaladsl.model.MediaTypes.image$divx$minuspcx();
|
||||
public static final MediaType.Binary IMAGE_X_PICT = akka.http.scaladsl.model.MediaTypes.image$divx$minuspict();
|
||||
public static final MediaType.Binary IMAGE_X_QUICKTIME = akka.http.scaladsl.model.MediaTypes.image$divx$minusquicktime();
|
||||
public static final MediaType.Binary IMAGE_X_RGB = akka.http.scaladsl.model.MediaTypes.image$divx$minusrgb();
|
||||
public static final MediaType.Binary IMAGE_X_XBITMAP = akka.http.scaladsl.model.MediaTypes.image$divx$minusxbitmap();
|
||||
public static final MediaType.Binary IMAGE_X_XPIXMAP = akka.http.scaladsl.model.MediaTypes.image$divx$minusxpixmap();
|
||||
public static final MediaType.Binary IMAGE_WEBP = akka.http.scaladsl.model.MediaTypes.image$divwebp();
|
||||
|
||||
public static final MediaType.Binary MESSAGE_HTTP = akka.http.scaladsl.model.MediaTypes.message$divhttp();
|
||||
public static final MediaType.Binary MESSAGE_DELIVERY_STATUS = akka.http.scaladsl.model.MediaTypes.message$divdelivery$minusstatus();
|
||||
public static final MediaType.Binary MESSAGE_RFC822 = akka.http.scaladsl.model.MediaTypes.message$divrfc822();
|
||||
|
||||
public static final MediaType.WithOpenCharset MULTIPART_MIXED = akka.http.scaladsl.model.MediaTypes.multipart$divmixed();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_ALTERNATIVE = akka.http.scaladsl.model.MediaTypes.multipart$divalternative();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_RELATED = akka.http.scaladsl.model.MediaTypes.multipart$divrelated();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_FORM_DATA = akka.http.scaladsl.model.MediaTypes.multipart$divform$minusdata();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_SIGNED = akka.http.scaladsl.model.MediaTypes.multipart$divsigned();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_ENCRYPTED = akka.http.scaladsl.model.MediaTypes.multipart$divencrypted();
|
||||
public static final MediaType.WithOpenCharset MULTIPART_BYTERANGES = akka.http.scaladsl.model.MediaTypes.multipart$divbyteranges();
|
||||
|
||||
public static final MediaType.WithOpenCharset TEXT_ASP = akka.http.scaladsl.model.MediaTypes.text$divasp();
|
||||
public static final MediaType.WithOpenCharset TEXT_CACHE_MANIFEST = akka.http.scaladsl.model.MediaTypes.text$divcache$minusmanifest();
|
||||
public static final MediaType.WithOpenCharset TEXT_CALENDAR = akka.http.scaladsl.model.MediaTypes.text$divcalendar();
|
||||
public static final MediaType.WithOpenCharset TEXT_CSS = akka.http.scaladsl.model.MediaTypes.text$divcss();
|
||||
public static final MediaType.WithOpenCharset TEXT_CSV = akka.http.scaladsl.model.MediaTypes.text$divcsv();
|
||||
public static final MediaType.WithOpenCharset TEXT_HTML = akka.http.scaladsl.model.MediaTypes.text$divhtml();
|
||||
public static final MediaType.WithOpenCharset TEXT_MCF = akka.http.scaladsl.model.MediaTypes.text$divmcf();
|
||||
public static final MediaType.WithOpenCharset TEXT_PLAIN = akka.http.scaladsl.model.MediaTypes.text$divplain();
|
||||
public static final MediaType.WithOpenCharset TEXT_RICHTEXT = akka.http.scaladsl.model.MediaTypes.text$divrichtext();
|
||||
public static final MediaType.WithOpenCharset TEXT_TAB_SEPARATED_VALUES = akka.http.scaladsl.model.MediaTypes.text$divtab$minusseparated$minusvalues();
|
||||
public static final MediaType.WithOpenCharset TEXT_URI_LIST = akka.http.scaladsl.model.MediaTypes.text$divuri$minuslist();
|
||||
public static final MediaType.WithOpenCharset TEXT_VND_WAP_WML = akka.http.scaladsl.model.MediaTypes.text$divvnd$u002Ewap$u002Ewml();
|
||||
public static final MediaType.WithOpenCharset TEXT_VND_WAP_WMLSCRIPT = akka.http.scaladsl.model.MediaTypes.text$divvnd$u002Ewap$u002Ewmlscript();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_ASM = akka.http.scaladsl.model.MediaTypes.text$divx$minusasm();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_C = akka.http.scaladsl.model.MediaTypes.text$divx$minusc();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_COMPONENT = akka.http.scaladsl.model.MediaTypes.text$divx$minuscomponent();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_H = akka.http.scaladsl.model.MediaTypes.text$divx$minush();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_JAVA_SOURCE = akka.http.scaladsl.model.MediaTypes.text$divx$minusjava$minussource();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_PASCAL = akka.http.scaladsl.model.MediaTypes.text$divx$minuspascal();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPT = akka.http.scaladsl.model.MediaTypes.text$divx$minusscript();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTCSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptcsh();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTELISP = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptelisp();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTKSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptksh();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTLISP = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptlisp();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTPERL = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptperl();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTPERL_MODULE = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptperl$minusmodule();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTPHYTON = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptphyton();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTREXX = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptrexx();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTSCHEME = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptscheme();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptsh();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTTCL = akka.http.scaladsl.model.MediaTypes.text$divx$minusscripttcl();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTTCSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscripttcsh();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SCRIPTZSH = akka.http.scaladsl.model.MediaTypes.text$divx$minusscriptzsh();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SERVER_PARSED_HTML = akka.http.scaladsl.model.MediaTypes.text$divx$minusserver$minusparsed$minushtml();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SETEXT = akka.http.scaladsl.model.MediaTypes.text$divx$minussetext();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SGML = akka.http.scaladsl.model.MediaTypes.text$divx$minussgml();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_SPEECH = akka.http.scaladsl.model.MediaTypes.text$divx$minusspeech();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_UUENCODE = akka.http.scaladsl.model.MediaTypes.text$divx$minusuuencode();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_VCALENDAR = akka.http.scaladsl.model.MediaTypes.text$divx$minusvcalendar();
|
||||
public static final MediaType.WithOpenCharset TEXT_X_VCARD = akka.http.scaladsl.model.MediaTypes.text$divx$minusvcard();
|
||||
public static final MediaType.WithOpenCharset TEXT_XML = akka.http.scaladsl.model.MediaTypes.text$divxml();
|
||||
|
||||
public static final MediaType.Binary VIDEO_AVS_VIDEO = akka.http.scaladsl.model.MediaTypes.video$divavs$minusvideo();
|
||||
public static final MediaType.Binary VIDEO_DIVX = akka.http.scaladsl.model.MediaTypes.video$divdivx();
|
||||
public static final MediaType.Binary VIDEO_GL = akka.http.scaladsl.model.MediaTypes.video$divgl();
|
||||
public static final MediaType.Binary VIDEO_MP4 = akka.http.scaladsl.model.MediaTypes.video$divmp4();
|
||||
public static final MediaType.Binary VIDEO_MPEG = akka.http.scaladsl.model.MediaTypes.video$divmpeg();
|
||||
public static final MediaType.Binary VIDEO_OGG = akka.http.scaladsl.model.MediaTypes.video$divogg();
|
||||
public static final MediaType.Binary VIDEO_QUICKTIME = akka.http.scaladsl.model.MediaTypes.video$divquicktime();
|
||||
public static final MediaType.Binary VIDEO_X_DV = akka.http.scaladsl.model.MediaTypes.video$divx$minusdv();
|
||||
public static final MediaType.Binary VIDEO_X_FLV = akka.http.scaladsl.model.MediaTypes.video$divx$minusflv();
|
||||
public static final MediaType.Binary VIDEO_X_MOTION_JPEG = akka.http.scaladsl.model.MediaTypes.video$divx$minusmotion$minusjpeg();
|
||||
public static final MediaType.Binary VIDEO_X_MS_ASF = akka.http.scaladsl.model.MediaTypes.video$divx$minusms$minusasf();
|
||||
public static final MediaType.Binary VIDEO_X_MSVIDEO = akka.http.scaladsl.model.MediaTypes.video$divx$minusmsvideo();
|
||||
public static final MediaType.Binary VIDEO_X_SGI_MOVIE = akka.http.scaladsl.model.MediaTypes.video$divx$minussgi$minusmovie();
|
||||
public static final MediaType.Binary VIDEO_WEBM = akka.http.scaladsl.model.MediaTypes.video$divwebm();
|
||||
|
||||
/**
|
||||
* Creates a custom media type.
|
||||
*/
|
||||
public static MediaType custom(
|
||||
String mainType,
|
||||
String subType,
|
||||
boolean compressible,
|
||||
akka.http.scaladsl.model.MediaType.Encoding encoding,
|
||||
Iterable<String> fileExtensions,
|
||||
Map<String, String> params) {
|
||||
return akka.http.scaladsl.model.MediaType.custom(mainType, subType, encoding, compressible, Util.<String, String>convertIterable(fileExtensions), Util.convertMapToScala(params), false);
|
||||
public static MediaType custom(String value, boolean binary, boolean compressible) {
|
||||
return akka.http.scaladsl.model.MediaType.custom(value, binary, compressible, List.<String>empty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ private[parser] trait AcceptHeader { this: Parser with CommonRules with CommonAc
|
|||
}
|
||||
} else {
|
||||
val (p, q) = MediaRange.splitOffQValue(params.toMap)
|
||||
MediaRange(getMediaType(main, sub, p), q)
|
||||
MediaRange(getMediaType(main, sub, p contains "charset", p), q)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,22 +12,28 @@ private[parser] trait CommonActions {
|
|||
|
||||
type StringMapBuilder = scala.collection.mutable.Builder[(String, String), Map[String, String]]
|
||||
|
||||
def getMediaType(mainType: String, subType: String, params: Map[String, String]): MediaType = {
|
||||
def getMediaType(mainType: String, subType: String, charsetDefined: Boolean,
|
||||
params: Map[String, String]): MediaType = {
|
||||
val subLower = subType.toRootLowerCase
|
||||
mainType.toRootLowerCase match {
|
||||
case "multipart" ⇒ subType.toRootLowerCase match {
|
||||
case "multipart" ⇒ subLower match {
|
||||
case "mixed" ⇒ multipart.mixed(params)
|
||||
case "alternative" ⇒ multipart.alternative(params)
|
||||
case "related" ⇒ multipart.related(params)
|
||||
case "form-data" ⇒ multipart.`form-data`(params)
|
||||
case "signed" ⇒ multipart.signed(params)
|
||||
case "encrypted" ⇒ multipart.encrypted(params)
|
||||
case custom ⇒ multipart(custom, params)
|
||||
case custom ⇒ MediaType.customMultipart(custom, params)
|
||||
}
|
||||
case mainLower ⇒
|
||||
MediaTypes.getForKey((mainLower, subType.toRootLowerCase)) match {
|
||||
MediaTypes.getForKey((mainLower, subLower)) match {
|
||||
case Some(registered) ⇒ if (params.isEmpty) registered else registered.withParams(params)
|
||||
case None ⇒ MediaType.custom(mainType, subType, encoding = MediaType.Encoding.Open,
|
||||
params = params, allowArbitrarySubtypes = true)
|
||||
case None ⇒
|
||||
if (charsetDefined)
|
||||
MediaType.customWithOpenCharset(mainLower, subType, params = params, allowArbitrarySubtypes = true)
|
||||
else
|
||||
MediaType.customBinary(mainLower, subType, compressible = true, params = params,
|
||||
allowArbitrarySubtypes = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,14 @@ private[parser] trait ContentTypeHeader { this: Parser with CommonRules with Com
|
|||
params match {
|
||||
case Nil ⇒
|
||||
val parameters = if (builder eq null) Map.empty[String, String] else builder.result()
|
||||
val mediaType = getMediaType(main, sub, parameters)
|
||||
ContentType(mediaType, charset)
|
||||
getMediaType(main, sub, charset.isDefined, parameters) match {
|
||||
case x: MediaType.Binary ⇒ ContentType.Binary(x)
|
||||
case x: MediaType.WithFixedCharset ⇒ ContentType.WithFixedCharset(x)
|
||||
case x: MediaType.WithOpenCharset ⇒
|
||||
// if we have an open charset media-type but no charset parameter we default to UTF-8
|
||||
val cs = if (charset.isDefined) charset.get else HttpCharsets.`UTF-8`
|
||||
ContentType.WithCharset(x, cs)
|
||||
}
|
||||
|
||||
case Seq(("charset", value), tail @ _*) ⇒
|
||||
contentType(main, sub, tail, Some(getCharset(value)), builder)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ private[parser] trait LinkHeader { this: Parser with CommonRules with CommonActi
|
|||
}
|
||||
}
|
||||
|
||||
def `link-media-type` = rule { `media-type` ~> ((mt, st, pm) ⇒ getMediaType(mt, st, pm.toMap)) }
|
||||
def `link-media-type` = rule { `media-type` ~> ((mt, st, pm) ⇒ getMediaType(mt, st, pm contains "charset", pm.toMap)) }
|
||||
|
||||
// filter out subsequent `rel`, `media`, `title`, `type` and `type*` params
|
||||
@tailrec private def sanitize(params: Seq[LinkParam], result: Seq[LinkParam] = Nil, seenRel: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ private[http] object JavaMapping {
|
|||
implicit object DateTime extends Inherited[jm.DateTime, akka.http.scaladsl.model.DateTime]
|
||||
|
||||
implicit object ContentType extends Inherited[jm.ContentType, sm.ContentType]
|
||||
implicit object ContentTypeBinary extends Inherited[jm.ContentType.Binary, sm.ContentType.Binary]
|
||||
implicit object ContentTypeNonBinary extends Inherited[jm.ContentType.NonBinary, sm.ContentType.NonBinary]
|
||||
implicit object ContentTypeWithFixedCharset extends Inherited[jm.ContentType.WithFixedCharset, sm.ContentType.WithFixedCharset]
|
||||
implicit object ContentTypeWithCharset extends Inherited[jm.ContentType.WithCharset, sm.ContentType.WithCharset]
|
||||
implicit object ContentTypeRange extends Inherited[jm.ContentTypeRange, sm.ContentTypeRange]
|
||||
implicit object Host extends Inherited[jm.Host, sm.Uri.Host]
|
||||
implicit object HttpCharset extends Inherited[jm.HttpCharset, sm.HttpCharset]
|
||||
|
|
@ -167,6 +171,10 @@ private[http] object JavaMapping {
|
|||
implicit object HttpResponse extends Inherited[jm.HttpResponse, sm.HttpResponse]
|
||||
implicit object MediaRange extends Inherited[jm.MediaRange, sm.MediaRange]
|
||||
implicit object MediaType extends Inherited[jm.MediaType, sm.MediaType]
|
||||
implicit object MediaTypeBinary extends Inherited[jm.MediaType.Binary, sm.MediaType.Binary]
|
||||
implicit object MediaTypeNonBinary extends Inherited[jm.MediaType.NonBinary, sm.MediaType.NonBinary]
|
||||
implicit object MediaTypeFixedCharset extends Inherited[jm.MediaType.WithFixedCharset, sm.MediaType.WithFixedCharset]
|
||||
implicit object MediaTypeOpenCharset extends Inherited[jm.MediaType.WithOpenCharset, sm.MediaType.WithOpenCharset]
|
||||
implicit object StatusCode extends Inherited[jm.StatusCode, sm.StatusCode]
|
||||
|
||||
implicit object ContentRange extends Inherited[jm.ContentRange, sm.ContentRange]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ import akka.http.impl.util.JavaMapping.Implicits._
|
|||
|
||||
final case class ContentTypeRange(mediaRange: MediaRange, charsetRange: HttpCharsetRange) extends jm.ContentTypeRange with ValueRenderable {
|
||||
def matches(contentType: jm.ContentType) =
|
||||
mediaRange.matches(contentType.mediaType) && charsetRange.matches(contentType.charset)
|
||||
contentType match {
|
||||
case ContentType.Binary(mt) ⇒ mediaRange.matches(mt)
|
||||
case x: ContentType.NonBinary ⇒ mediaRange.matches(x.mediaType) && charsetRange.matches(x.charset)
|
||||
}
|
||||
|
||||
def render[R <: Rendering](r: R): r.type = charsetRange match {
|
||||
case HttpCharsetRange.`*` ⇒ r ~~ mediaRange
|
||||
|
|
@ -22,7 +25,7 @@ final case class ContentTypeRange(mediaRange: MediaRange, charsetRange: HttpChar
|
|||
/**
|
||||
* Returns a [[ContentType]] instance which fits this range.
|
||||
*/
|
||||
def specimen: ContentType = ContentType(mediaRange.specimen, charsetRange.specimen)
|
||||
def specimen: ContentType = ContentType(mediaRange.specimen, () ⇒ charsetRange.specimen)
|
||||
}
|
||||
|
||||
object ContentTypeRange {
|
||||
|
|
@ -31,74 +34,82 @@ object ContentTypeRange {
|
|||
implicit def apply(mediaType: MediaType): ContentTypeRange = apply(mediaType, HttpCharsetRange.`*`)
|
||||
implicit def apply(mediaRange: MediaRange): ContentTypeRange = apply(mediaRange, HttpCharsetRange.`*`)
|
||||
implicit def apply(contentType: ContentType): ContentTypeRange =
|
||||
contentType.definedCharset match {
|
||||
case Some(charset) ⇒ apply(contentType.mediaType, charset)
|
||||
case None ⇒ ContentTypeRange(contentType.mediaType)
|
||||
contentType match {
|
||||
case ContentType.Binary(mt) ⇒ ContentTypeRange(mt)
|
||||
case ContentType.WithFixedCharset(mt) ⇒ ContentTypeRange(mt)
|
||||
case ContentType.WithCharset(mt, cs) ⇒ ContentTypeRange(mt, cs)
|
||||
}
|
||||
}
|
||||
|
||||
abstract case class ContentType private (mediaType: MediaType, definedCharset: Option[HttpCharset]) extends jm.ContentType with ValueRenderable {
|
||||
private[http] def render[R <: Rendering](r: R): r.type = definedCharset match {
|
||||
case Some(cs) ⇒ r ~~ mediaType ~~ ContentType.`; charset=` ~~ cs
|
||||
case _ ⇒ r ~~ mediaType
|
||||
}
|
||||
def charset: HttpCharset = definedCharset orElse mediaType.encoding.charset getOrElse HttpCharsets.`UTF-8`
|
||||
/**
|
||||
* A `ContentType` represents a specific MediaType / HttpCharset combination.
|
||||
*
|
||||
* If the MediaType is not flexible with regard to the charset used, e.g. because it's a binary MediaType or
|
||||
* the charset is fixed, then the `ContentType` is a simple wrapper.
|
||||
*/
|
||||
sealed trait ContentType extends jm.ContentType with ValueRenderable {
|
||||
def mediaType: MediaType
|
||||
def charsetOption: Option[HttpCharset]
|
||||
|
||||
def hasOpenCharset: Boolean = definedCharset.isEmpty && mediaType.encoding == MediaType.Encoding.Open
|
||||
|
||||
def withMediaType(mediaType: MediaType) =
|
||||
if (mediaType != this.mediaType) ContentType(mediaType, definedCharset) else this
|
||||
def withCharset(charset: HttpCharset) =
|
||||
if (definedCharset.isEmpty || charset != definedCharset.get) ContentType(mediaType, charset) else this
|
||||
def withoutDefinedCharset =
|
||||
if (definedCharset.isDefined) ContentType(mediaType, None) else this
|
||||
def withDefaultCharset(charset: HttpCharset) =
|
||||
if (mediaType.encoding == MediaType.Encoding.Open && definedCharset.isEmpty) ContentType(mediaType, charset) else this
|
||||
private[http] def render[R <: Rendering](r: R): r.type = r ~~ mediaType
|
||||
|
||||
/** Java API */
|
||||
def getDefinedCharset: JOption[jm.HttpCharset] = definedCharset.asJava
|
||||
def getCharsetOption: JOption[jm.HttpCharset] = charsetOption.asJava
|
||||
}
|
||||
|
||||
object ContentType {
|
||||
private[http] case object `; charset=` extends SingletonValueRenderable
|
||||
|
||||
implicit def apply(mediaType: MediaType): ContentType = apply(mediaType, None)
|
||||
|
||||
def apply(mediaType: MediaType, charset: HttpCharset): ContentType = apply(mediaType, Some(charset))
|
||||
|
||||
def apply(mediaType: MediaType, charset: Option[HttpCharset]): ContentType = {
|
||||
val definedCharset =
|
||||
charset match {
|
||||
case None ⇒ None
|
||||
case Some(cs) ⇒ mediaType.encoding match {
|
||||
case MediaType.Encoding.Open ⇒ charset
|
||||
case MediaType.Encoding.Fixed(`cs`) ⇒ None
|
||||
case x ⇒ throw new IllegalArgumentException(
|
||||
s"MediaType $mediaType has a $x encoding and doesn't allow a custom `charset` $cs")
|
||||
}
|
||||
}
|
||||
new ContentType(mediaType, definedCharset) {}
|
||||
final case class Binary(mediaType: MediaType.Binary) extends jm.ContentType.Binary with ContentType {
|
||||
def binary = true
|
||||
def charsetOption = None
|
||||
}
|
||||
|
||||
sealed trait NonBinary extends jm.ContentType.NonBinary with ContentType {
|
||||
def binary = false
|
||||
def charset: HttpCharset
|
||||
def charsetOption = Some(charset)
|
||||
}
|
||||
|
||||
final case class WithFixedCharset(val mediaType: MediaType.WithFixedCharset)
|
||||
extends jm.ContentType.WithFixedCharset with NonBinary {
|
||||
def charset = mediaType.charset
|
||||
}
|
||||
|
||||
final case class WithCharset(val mediaType: MediaType.WithOpenCharset, val charset: HttpCharset)
|
||||
extends jm.ContentType.WithCharset with NonBinary {
|
||||
|
||||
private[http] override def render[R <: Rendering](r: R): r.type =
|
||||
super.render(r) ~~ ContentType.`; charset=` ~~ charset
|
||||
}
|
||||
|
||||
implicit def apply(mediaType: MediaType.Binary): Binary = Binary(mediaType)
|
||||
implicit def apply(mediaType: MediaType.WithFixedCharset): WithFixedCharset = WithFixedCharset(mediaType)
|
||||
def apply(mediaType: MediaType.WithOpenCharset, charset: HttpCharset): WithCharset = WithCharset(mediaType, charset)
|
||||
def apply(mediaType: MediaType, charset: () ⇒ HttpCharset): ContentType =
|
||||
mediaType match {
|
||||
case x: MediaType.Binary ⇒ ContentType(x)
|
||||
case x: MediaType.WithFixedCharset ⇒ ContentType(x)
|
||||
case x: MediaType.WithOpenCharset ⇒ ContentType(x, charset())
|
||||
}
|
||||
|
||||
def unapply(contentType: ContentType): Option[(MediaType, Option[HttpCharset])] =
|
||||
Some(contentType.mediaType → contentType.charsetOption)
|
||||
|
||||
/**
|
||||
* Tries to parse a ``ContentType`` value from the given String. Returns ``Right(contentType)`` if successful and
|
||||
* ``Left(errors)`` otherwise.
|
||||
*/
|
||||
def parse(value: String): Either[List[ErrorInfo], ContentType] =
|
||||
headers.`Content-Type`.parseFromValueString(value).right.map(_.contentType)
|
||||
|
||||
private[http] case object `; charset=` extends SingletonValueRenderable
|
||||
}
|
||||
|
||||
object ContentTypes {
|
||||
val `application/json` = ContentType(MediaTypes.`application/json`)
|
||||
val `application/octet-stream` = ContentType(MediaTypes.`application/octet-stream`)
|
||||
|
||||
val `text/plain` = ContentType(MediaTypes.`text/plain`)
|
||||
val `text/plain(UTF-8)` = ContentType(MediaTypes.`text/plain`, HttpCharsets.`UTF-8`)
|
||||
val `text/html` = ContentType(MediaTypes.`text/html`)
|
||||
val `text/xml` = ContentType(MediaTypes.`text/xml`)
|
||||
|
||||
val `application/x-www-form-urlencoded` = ContentType(MediaTypes.`application/x-www-form-urlencoded`)
|
||||
val `multipart/form-data` = ContentType(MediaTypes.`multipart/form-data`)
|
||||
val `text/plain(UTF-8)` = MediaTypes.`text/plain` withCharset HttpCharsets.`UTF-8`
|
||||
val `text/html(UTF-8)` = MediaTypes.`text/html` withCharset HttpCharsets.`UTF-8`
|
||||
val `text/xml(UTF-8)` = MediaTypes.`text/xml` withCharset HttpCharsets.`UTF-8`
|
||||
|
||||
// used for explicitly suppressing the rendering of Content-Type headers on requests and responses
|
||||
val NoContentType = ContentType(MediaTypes.NoMediaType)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ package akka.http.scaladsl.model
|
|||
|
||||
import akka.http.impl.model.parser.CharacterClasses
|
||||
import akka.http.impl.util.StringRendering
|
||||
import akka.http.javadsl.{ model ⇒ jm }
|
||||
import akka.http.scaladsl.model.HttpCharsets._
|
||||
import akka.http.scaladsl.model.MediaTypes._
|
||||
|
||||
/**
|
||||
|
|
@ -19,7 +17,7 @@ final case class FormData(fields: Uri.Query) {
|
|||
|
||||
def toEntity(charset: HttpCharset): akka.http.scaladsl.model.RequestEntity = {
|
||||
val render: StringRendering = UriRendering.renderQuery(new StringRendering, this.fields, charset.nioCharset, CharacterClasses.unreserved)
|
||||
HttpEntity(ContentType(`application/x-www-form-urlencoded`, `UTF-8`), render.get)
|
||||
HttpEntity(`application/x-www-form-urlencoded` withCharset charset, render.get)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ object HttpCharsetRange {
|
|||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
final def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ "*;q=" ~~ qValue else r ~~ '*'
|
||||
def matches(charset: HttpCharset) = true
|
||||
def matchesAll: Boolean = true
|
||||
def specimen: HttpCharset = HttpCharsets.`UTF-8`
|
||||
def withQValue(qValue: Float) =
|
||||
if (qValue == 1.0f) `*` else if (qValue != this.qValue) `*`(qValue.toFloat) else this
|
||||
|
|
@ -47,7 +46,6 @@ object HttpCharsetRange {
|
|||
final case class One(charset: HttpCharset, qValue: Float) extends HttpCharsetRange {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def matches(charset: HttpCharset) = this.charset.value.equalsIgnoreCase(charset.value)
|
||||
def matchesAll: Boolean = false
|
||||
def specimen: HttpCharset = charset
|
||||
def withQValue(qValue: Float) = One(charset, qValue)
|
||||
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ charset ~~ ";q=" ~~ qValue else r ~~ charset
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ object HttpEntity {
|
|||
implicit def apply(string: String): Strict = apply(ContentTypes.`text/plain(UTF-8)`, string)
|
||||
implicit def apply(bytes: Array[Byte]): Strict = apply(ContentTypes.`application/octet-stream`, bytes)
|
||||
implicit def apply(data: ByteString): Strict = apply(ContentTypes.`application/octet-stream`, data)
|
||||
def apply(contentType: ContentType, string: String): Strict =
|
||||
def apply(contentType: ContentType.NonBinary, string: String): Strict =
|
||||
if (string.isEmpty) empty(contentType) else apply(contentType, ByteString(string.getBytes(contentType.charset.nioCharset)))
|
||||
def apply(contentType: ContentType, bytes: Array[Byte]): Strict =
|
||||
if (bytes.length == 0) empty(contentType) else apply(contentType, ByteString(bytes))
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ sealed trait HttpMessage extends jm.HttpMessage {
|
|||
def withEntity(string: String): Self = withEntity(HttpEntity(string))
|
||||
def withEntity(bytes: Array[Byte]): Self = withEntity(HttpEntity(bytes))
|
||||
def withEntity(bytes: ByteString): Self = withEntity(HttpEntity(bytes))
|
||||
def withEntity(contentType: jm.ContentType, string: String): Self = withEntity(HttpEntity(contentType.asInstanceOf[ContentType], string))
|
||||
def withEntity(contentType: jm.ContentType.NonBinary, string: String): Self =
|
||||
withEntity(HttpEntity(contentType.asInstanceOf[ContentType.NonBinary], string))
|
||||
def withEntity(contentType: jm.ContentType, bytes: Array[Byte]): Self = withEntity(HttpEntity(contentType.asInstanceOf[ContentType], bytes))
|
||||
def withEntity(contentType: jm.ContentType, bytes: ByteString): Self = withEntity(HttpEntity(contentType.asInstanceOf[ContentType], bytes))
|
||||
def withEntity(contentType: jm.ContentType, file: java.io.File): Self = withEntity(HttpEntity(contentType.asInstanceOf[ContentType], file))
|
||||
|
|
@ -163,115 +164,11 @@ final case class HttpRequest(method: HttpMethod = HttpMethods.GET,
|
|||
def withEffectiveUri(securedConnection: Boolean, defaultHostHeader: Host = Host.empty): HttpRequest =
|
||||
copy(uri = effectiveUri(securedConnection, defaultHostHeader))
|
||||
|
||||
/**
|
||||
* The media-ranges accepted by the client according to the `Accept` request header.
|
||||
* The returned ranges are sorted by decreasing q-value.
|
||||
*/
|
||||
def acceptedMediaRanges: immutable.Seq[MediaRange] =
|
||||
(for {
|
||||
Accept(mediaRanges) ← headers
|
||||
range ← mediaRanges
|
||||
} yield range).sortBy(-_.qValue)
|
||||
|
||||
/**
|
||||
* The charset-ranges accepted by the client according to the `Accept-Charset` request header.
|
||||
* The returned ranges are sorted by decreasing q-value.
|
||||
*/
|
||||
def acceptedCharsetRanges: immutable.Seq[HttpCharsetRange] =
|
||||
(for {
|
||||
`Accept-Charset`(charsetRanges) ← headers
|
||||
range ← charsetRanges
|
||||
} yield range).sortBy(-_.qValue)
|
||||
|
||||
/**
|
||||
* The encoding-ranges accepted by the client according to the `Accept-Encoding` request header.
|
||||
* The returned ranges are sorted by decreasing q-value.
|
||||
*/
|
||||
def acceptedEncodingRanges: immutable.Seq[HttpEncodingRange] =
|
||||
(for {
|
||||
`Accept-Encoding`(encodingRanges) ← headers
|
||||
range ← encodingRanges
|
||||
} yield range).sortBy(-_.qValue)
|
||||
|
||||
/**
|
||||
* The language-ranges accepted by the client according to the `Accept-Language` request header.
|
||||
* The returned ranges are sorted by increasing generality (i.e. most specific first).
|
||||
*/
|
||||
def acceptedLanguageRanges: immutable.Seq[LanguageRange] =
|
||||
(for {
|
||||
`Accept-Language`(languageRanges) ← headers
|
||||
range ← languageRanges
|
||||
} yield range).sortBy {
|
||||
case _: LanguageRange.`*` ⇒ 0 // most general, needs to come last
|
||||
case x ⇒ -(x.subTags.size + 1) // more subtags -> more specific -> go first
|
||||
}
|
||||
|
||||
/**
|
||||
* All cookies provided by the client in one or more `Cookie` headers.
|
||||
*/
|
||||
def cookies: immutable.Seq[HttpCookiePair] = for (`Cookie`(cookies) ← headers; cookie ← cookies) yield cookie
|
||||
|
||||
/**
|
||||
* Determines whether the given media-type is accepted by the client.
|
||||
*/
|
||||
def isMediaTypeAccepted(mediaType: MediaType, ranges: Seq[MediaRange] = acceptedMediaRanges): Boolean =
|
||||
qValueForMediaType(mediaType, ranges) > 0f
|
||||
|
||||
/**
|
||||
* Returns the q-value that the client (implicitly or explicitly) attaches to the given media-type.
|
||||
*/
|
||||
def qValueForMediaType(mediaType: MediaType, ranges: Seq[MediaRange] = acceptedMediaRanges): Float =
|
||||
ranges match {
|
||||
case Nil ⇒ 1.0f // http://tools.ietf.org/html/rfc7231#section-5.3.1
|
||||
case x ⇒ x collectFirst { case r if r matches mediaType ⇒ r.qValue } getOrElse 0f
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given charset is accepted by the client.
|
||||
*/
|
||||
def isCharsetAccepted(charset: HttpCharset, ranges: Seq[HttpCharsetRange] = acceptedCharsetRanges): Boolean =
|
||||
qValueForCharset(charset, ranges) > 0f
|
||||
|
||||
/**
|
||||
* Returns the q-value that the client (implicitly or explicitly) attaches to the given charset.
|
||||
*/
|
||||
def qValueForCharset(charset: HttpCharset, ranges: Seq[HttpCharsetRange] = acceptedCharsetRanges): Float =
|
||||
ranges match {
|
||||
case Nil ⇒ 1.0f // http://tools.ietf.org/html/rfc7231#section-5.3.1
|
||||
case x ⇒ x collectFirst { case r if r matches charset ⇒ r.qValue } getOrElse 0f
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given encoding is accepted by the client.
|
||||
*/
|
||||
def isEncodingAccepted(encoding: HttpEncoding, ranges: Seq[HttpEncodingRange] = acceptedEncodingRanges): Boolean =
|
||||
qValueForEncoding(encoding, ranges) > 0f
|
||||
|
||||
/**
|
||||
* Returns the q-value that the client (implicitly or explicitly) attaches to the given encoding.
|
||||
*/
|
||||
def qValueForEncoding(encoding: HttpEncoding, ranges: Seq[HttpEncodingRange] = acceptedEncodingRanges): Float =
|
||||
ranges match {
|
||||
case Nil ⇒ 1.0f // http://tools.ietf.org/html/rfc7231#section-5.3.1
|
||||
case x ⇒ x collectFirst { case r if r matches encoding ⇒ r.qValue } getOrElse 0f
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given language is accepted by the client.
|
||||
*/
|
||||
def isLanguageAccepted(language: Language, ranges: Seq[LanguageRange] = acceptedLanguageRanges): Boolean =
|
||||
qValueForLanguage(language, ranges) > 0f
|
||||
|
||||
/**
|
||||
* Returns the q-value that the client (implicitly or explicitly) attaches to the given language.
|
||||
* Note: The given ranges must be sorted by increasing generality (i.e. most specific first)!
|
||||
*/
|
||||
def qValueForLanguage(language: Language, ranges: Seq[LanguageRange] = acceptedLanguageRanges): Float =
|
||||
ranges match {
|
||||
case Nil ⇒ 1.0f // http://tools.ietf.org/html/rfc7231#section-5.3.1
|
||||
case x ⇒ x collectFirst { case r if r matches language ⇒ r.qValue } getOrElse 0f
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this request can be safely retried, which is the case only of the request method is idempotent.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.scaladsl.model
|
||||
|
||||
import language.implicitConversions
|
||||
import java.util
|
||||
import akka.http.impl.util._
|
||||
import akka.http.javadsl.{ model ⇒ jm }
|
||||
|
||||
sealed abstract class MediaRange extends jm.MediaRange with Renderable with WithQValue[MediaRange] {
|
||||
def value: String
|
||||
def mainType: String
|
||||
def params: Map[String, String]
|
||||
def qValue: Float
|
||||
def matches(mediaType: MediaType): Boolean
|
||||
def isApplication = false
|
||||
def isAudio = false
|
||||
def isImage = false
|
||||
def isMessage = false
|
||||
def isMultipart = false
|
||||
def isText = false
|
||||
def isVideo = false
|
||||
def isWildcard = mainType == "*"
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with the params replaced by the given ones.
|
||||
* If the given map contains a "q" value the `qValue` member is (also) updated.
|
||||
*/
|
||||
def withParams(params: Map[String, String]): MediaRange
|
||||
|
||||
/**
|
||||
* Constructs a `ContentTypeRange` from this instance and the given charset.
|
||||
*/
|
||||
def withCharsetRange(charsetRange: HttpCharsetRange): ContentTypeRange = ContentTypeRange(this, charsetRange)
|
||||
|
||||
/**
|
||||
* Returns a [[MediaType]] instance which fits this range.
|
||||
*/
|
||||
def specimen: MediaType
|
||||
|
||||
/** Java API */
|
||||
def getParams: util.Map[String, String] = {
|
||||
import collection.JavaConverters._
|
||||
params.asJava
|
||||
}
|
||||
/** Java API */
|
||||
def matches(mediaType: jm.MediaType): Boolean = {
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
matches(mediaType.asScala)
|
||||
}
|
||||
}
|
||||
|
||||
object MediaRange {
|
||||
private[http] def splitOffQValue(params: Map[String, String], defaultQ: Float = 1.0f): (Map[String, String], Float) =
|
||||
params.get("q") match {
|
||||
case Some(x) ⇒ (params - "q") -> (try x.toFloat catch { case _: NumberFormatException ⇒ 1.0f })
|
||||
case None ⇒ params -> defaultQ
|
||||
}
|
||||
|
||||
private final case class Custom(mainType: String, params: Map[String, String], qValue: Float)
|
||||
extends MediaRange with ValueRenderable {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def matches(mediaType: MediaType) = mainType == "*" || mediaType.mainType == mainType
|
||||
def withParams(params: Map[String, String]) = custom(mainType, params, qValue)
|
||||
def withQValue(qValue: Float) = if (qValue != this.qValue) custom(mainType, params, qValue) else this
|
||||
def render[R <: Rendering](r: R): r.type = {
|
||||
r ~~ mainType ~~ '/' ~~ '*'
|
||||
if (qValue < 1.0f) r ~~ ";q=" ~~ qValue
|
||||
if (params.nonEmpty) params foreach { case (k, v) ⇒ r ~~ ';' ~~ ' ' ~~ k ~~ '=' ~~# v }
|
||||
r
|
||||
}
|
||||
override def isApplication = mainType == "application"
|
||||
override def isAudio = mainType == "audio"
|
||||
override def isImage = mainType == "image"
|
||||
override def isMessage = mainType == "message"
|
||||
override def isMultipart = mainType == "multipart"
|
||||
override def isText = mainType == "text"
|
||||
override def isVideo = mainType == "video"
|
||||
def specimen = MediaType.customBinary(mainType, "custom", compressible = true)
|
||||
}
|
||||
|
||||
def custom(mainType: String, params: Map[String, String] = Map.empty, qValue: Float = 1.0f): MediaRange = {
|
||||
val (ps, q) = splitOffQValue(params, qValue)
|
||||
Custom(mainType.toRootLowerCase, ps, q)
|
||||
}
|
||||
|
||||
final case class One(mediaType: MediaType, qValue: Float) extends MediaRange with ValueRenderable {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def mainType = mediaType.mainType
|
||||
def params = mediaType.params
|
||||
override def isApplication = mediaType.isApplication
|
||||
override def isAudio = mediaType.isAudio
|
||||
override def isImage = mediaType.isImage
|
||||
override def isMessage = mediaType.isMessage
|
||||
override def isMultipart = mediaType.isMultipart
|
||||
override def isText = mediaType.isText
|
||||
override def isVideo = mediaType.isVideo
|
||||
def matches(mediaType: MediaType) =
|
||||
this.mediaType.mainType == mediaType.mainType && this.mediaType.subType == mediaType.subType
|
||||
def withParams(params: Map[String, String]) = copy(mediaType = mediaType.withParams(params))
|
||||
def withQValue(qValue: Float) = copy(qValue = qValue)
|
||||
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ mediaType ~~ ";q=" ~~ qValue else r ~~ mediaType
|
||||
def specimen = mediaType
|
||||
}
|
||||
|
||||
implicit def apply(mediaType: MediaType): MediaRange = apply(mediaType, 1.0f)
|
||||
def apply(mediaType: MediaType, qValue: Float = 1.0f): MediaRange = One(mediaType, qValue)
|
||||
}
|
||||
|
||||
object MediaRanges extends ObjectRegistry[String, MediaRange] {
|
||||
|
||||
sealed abstract case class PredefinedMediaRange(value: String) extends MediaRange with LazyValueBytesRenderable {
|
||||
val mainType = value takeWhile (_ != '/')
|
||||
register(mainType, this)
|
||||
def params = Map.empty
|
||||
def qValue = 1.0f
|
||||
def withParams(params: Map[String, String]) = MediaRange.custom(mainType, params)
|
||||
def withQValue(qValue: Float) = if (qValue != 1.0f) MediaRange.custom(mainType, params, qValue) else this
|
||||
}
|
||||
|
||||
val `*/*` = new PredefinedMediaRange("*/*") {
|
||||
def matches(mediaType: MediaType) = true
|
||||
def specimen = MediaTypes.`text/plain`
|
||||
}
|
||||
val `*/*;q=MIN` = `*/*`.withQValue(Float.MinPositiveValue)
|
||||
val `application/*` = new PredefinedMediaRange("application/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isApplication
|
||||
override def isApplication = true
|
||||
def specimen = MediaTypes.`application/json`
|
||||
}
|
||||
val `audio/*` = new PredefinedMediaRange("audio/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isAudio
|
||||
override def isAudio = true
|
||||
def specimen = MediaTypes.`audio/ogg`
|
||||
}
|
||||
val `image/*` = new PredefinedMediaRange("image/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isImage
|
||||
override def isImage = true
|
||||
def specimen = MediaTypes.`image/png`
|
||||
}
|
||||
val `message/*` = new PredefinedMediaRange("message/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isMessage
|
||||
override def isMessage = true
|
||||
def specimen = MediaTypes.`message/rfc822`
|
||||
}
|
||||
val `multipart/*` = new PredefinedMediaRange("multipart/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isMultipart
|
||||
override def isMultipart = true
|
||||
def specimen = MediaTypes.`multipart/form-data`
|
||||
}
|
||||
val `text/*` = new PredefinedMediaRange("text/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isText
|
||||
override def isText = true
|
||||
def specimen = MediaTypes.`text/plain`
|
||||
}
|
||||
val `video/*` = new PredefinedMediaRange("video/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isVideo
|
||||
override def isVideo = true
|
||||
def specimen = MediaTypes.`video/mp4`
|
||||
}
|
||||
}
|
||||
|
|
@ -5,243 +5,115 @@
|
|||
package akka.http.scaladsl.model
|
||||
|
||||
import language.implicitConversions
|
||||
import java.util
|
||||
import scala.collection.immutable
|
||||
import akka.http.impl.util._
|
||||
import akka.http.javadsl.{ model ⇒ jm }
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
|
||||
sealed abstract class MediaRange extends jm.MediaRange with Renderable with WithQValue[MediaRange] {
|
||||
def value: String
|
||||
def mainType: String
|
||||
/**
|
||||
* A MediaType describes the type of the content of an HTTP message entity.
|
||||
*
|
||||
* While knowledge of the MediaType alone suffices for being able to properly interpret binary content this
|
||||
* is not generally the case for non-binary (i.e. character-based) content, which also requires the definition
|
||||
* of a specific character encoding ([[HttpCharset]]).
|
||||
* Therefore [[MediaType]] instances are frequently encountered as a member of a [[ContentType]], which
|
||||
* groups a [[MediaType]] with a potentially required [[HttpCharset]] to hold everything required for being
|
||||
* able to interpret an [[HttpEntity]].
|
||||
*
|
||||
* MediaTypes come in three basic forms:
|
||||
*
|
||||
* 1. Binary: These do not need an additional [[HttpCharset]] to be able to form a [[ContentType]]. Therefore
|
||||
* they can be implicitly converted to the latter.
|
||||
*
|
||||
* 2. WithOpenCharset: Most character-based MediaTypes are of this form, which can be combined with all
|
||||
* [[HttpCharset]] instances to form a [[ContentType]].
|
||||
*
|
||||
* 3. WithFixedCharset: Some character-based MediaTypes prescribe a single, clearly defined charset and as such,
|
||||
* similarly to binary MediaTypes, do not require the addition of an [[HttpCharset]] instances to form a
|
||||
* [[ContentType]]. The most prominent example is probably `application/json` which must always be UTF-8 encoded.
|
||||
* Like binary MediaTypes `WithFixedCharset` types can be implicitly converted to a [[ContentType]].
|
||||
*/
|
||||
sealed abstract class MediaType extends jm.MediaType with LazyValueBytesRenderable with WithQValue[MediaRange] {
|
||||
|
||||
def fileExtensions: List[String]
|
||||
def params: Map[String, String]
|
||||
def qValue: Float
|
||||
def matches(mediaType: MediaType): Boolean
|
||||
def isApplication = false
|
||||
def isAudio = false
|
||||
def isImage = false
|
||||
def isMessage = false
|
||||
def isMultipart = false
|
||||
def isText = false
|
||||
def isVideo = false
|
||||
def isWildcard = mainType == "*"
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with the params replaced by the given ones.
|
||||
* If the given map contains a "q" value the `qValue` member is (also) updated.
|
||||
*/
|
||||
def withParams(params: Map[String, String]): MediaRange
|
||||
override def isApplication: Boolean = false
|
||||
override def isAudio: Boolean = false
|
||||
override def isImage: Boolean = false
|
||||
override def isMessage: Boolean = false
|
||||
override def isMultipart: Boolean = false
|
||||
override def isText: Boolean = false
|
||||
override def isVideo: Boolean = false
|
||||
|
||||
/**
|
||||
* Constructs a `ContentTypeRange` from this instance and the given charset.
|
||||
*/
|
||||
def withCharset(charsetRange: HttpCharsetRange): ContentTypeRange = ContentTypeRange(this, charsetRange)
|
||||
|
||||
/**
|
||||
* Returns a [[MediaType]] instance which fits this range.
|
||||
*/
|
||||
def specimen: MediaType
|
||||
|
||||
/** Java API */
|
||||
def getParams: util.Map[String, String] = {
|
||||
import collection.JavaConverters._
|
||||
params.asJava
|
||||
}
|
||||
/** Java API */
|
||||
def matches(mediaType: jm.MediaType): Boolean = {
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
matches(mediaType.asScala)
|
||||
}
|
||||
}
|
||||
|
||||
object MediaRange {
|
||||
private[http] def splitOffQValue(params: Map[String, String], defaultQ: Float = 1.0f): (Map[String, String], Float) =
|
||||
params.get("q") match {
|
||||
case Some(x) ⇒ (params - "q") -> (try x.toFloat catch { case _: NumberFormatException ⇒ 1.0f })
|
||||
case None ⇒ params -> defaultQ
|
||||
}
|
||||
|
||||
private final case class Custom(mainType: String, params: Map[String, String], qValue: Float)
|
||||
extends MediaRange with ValueRenderable {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def matches(mediaType: MediaType) = mainType == "*" || mediaType.mainType == mainType
|
||||
def withParams(params: Map[String, String]) = custom(mainType, params, qValue)
|
||||
def withQValue(qValue: Float) = if (qValue != this.qValue) custom(mainType, params, qValue) else this
|
||||
def render[R <: Rendering](r: R): r.type = {
|
||||
r ~~ mainType ~~ '/' ~~ '*'
|
||||
if (qValue < 1.0f) r ~~ ";q=" ~~ qValue
|
||||
if (params.nonEmpty) params foreach { case (k, v) ⇒ r ~~ ';' ~~ ' ' ~~ k ~~ '=' ~~# v }
|
||||
r
|
||||
}
|
||||
override def isApplication = mainType == "application"
|
||||
override def isAudio = mainType == "audio"
|
||||
override def isImage = mainType == "image"
|
||||
override def isMessage = mainType == "message"
|
||||
override def isMultipart = mainType == "multipart"
|
||||
override def isText = mainType == "text"
|
||||
override def isVideo = mainType == "video"
|
||||
def specimen = MediaType.custom(mainType, "custom", MediaType.Encoding.Binary)
|
||||
}
|
||||
|
||||
def custom(mainType: String, params: Map[String, String] = Map.empty, qValue: Float = 1.0f): MediaRange = {
|
||||
val (ps, q) = splitOffQValue(params, qValue)
|
||||
Custom(mainType.toRootLowerCase, ps, q)
|
||||
}
|
||||
|
||||
final case class One(mediaType: MediaType, qValue: Float) extends MediaRange with ValueRenderable {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def mainType = mediaType.mainType
|
||||
def params = mediaType.params
|
||||
override def isApplication = mediaType.isApplication
|
||||
override def isAudio = mediaType.isAudio
|
||||
override def isImage = mediaType.isImage
|
||||
override def isMessage = mediaType.isMessage
|
||||
override def isMultipart = mediaType.isMultipart
|
||||
override def isText = mediaType.isText
|
||||
override def isVideo = mediaType.isVideo
|
||||
def matches(mediaType: MediaType) =
|
||||
this.mediaType.mainType == mediaType.mainType && this.mediaType.subType == mediaType.subType
|
||||
def withParams(params: Map[String, String]) = copy(mediaType = mediaType.withParams(params))
|
||||
def withQValue(qValue: Float) = copy(qValue = qValue)
|
||||
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ mediaType ~~ ";q=" ~~ qValue else r ~~ mediaType
|
||||
def specimen = mediaType
|
||||
}
|
||||
|
||||
implicit def apply(mediaType: MediaType): MediaRange = apply(mediaType, 1.0f)
|
||||
def apply(mediaType: MediaType, qValue: Float = 1.0f): MediaRange = One(mediaType, qValue)
|
||||
}
|
||||
|
||||
object MediaRanges extends ObjectRegistry[String, MediaRange] {
|
||||
|
||||
sealed abstract case class PredefinedMediaRange(value: String) extends MediaRange with LazyValueBytesRenderable {
|
||||
val mainType = value takeWhile (_ != '/')
|
||||
register(mainType, this)
|
||||
def params = Map.empty
|
||||
def qValue = 1.0f
|
||||
def withParams(params: Map[String, String]) = MediaRange.custom(mainType, params)
|
||||
def withQValue(qValue: Float) = if (qValue != 1.0f) MediaRange.custom(mainType, params, qValue) else this
|
||||
}
|
||||
|
||||
val `*/*` = new PredefinedMediaRange("*/*") {
|
||||
def matches(mediaType: MediaType) = true
|
||||
def specimen = MediaTypes.`text/plain`
|
||||
}
|
||||
val `*/*;q=MIN` = `*/*`.withQValue(Float.MinPositiveValue)
|
||||
val `application/*` = new PredefinedMediaRange("application/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isApplication
|
||||
override def isApplication = true
|
||||
def specimen = MediaTypes.`application/json`
|
||||
}
|
||||
val `audio/*` = new PredefinedMediaRange("audio/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isAudio
|
||||
override def isAudio = true
|
||||
def specimen = MediaTypes.`audio/ogg`
|
||||
}
|
||||
val `image/*` = new PredefinedMediaRange("image/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isImage
|
||||
override def isImage = true
|
||||
def specimen = MediaTypes.`image/png`
|
||||
}
|
||||
val `message/*` = new PredefinedMediaRange("message/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isMessage
|
||||
override def isMessage = true
|
||||
def specimen = MediaTypes.`message/rfc822`
|
||||
}
|
||||
val `multipart/*` = new PredefinedMediaRange("multipart/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isMultipart
|
||||
override def isMultipart = true
|
||||
def specimen = MediaTypes.`multipart/form-data`
|
||||
}
|
||||
val `text/*` = new PredefinedMediaRange("text/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isText
|
||||
override def isText = true
|
||||
def specimen = MediaTypes.`text/plain`
|
||||
}
|
||||
val `video/*` = new PredefinedMediaRange("video/*") {
|
||||
def matches(mediaType: MediaType) = mediaType.isVideo
|
||||
override def isVideo = true
|
||||
def specimen = MediaTypes.`video/mp4`
|
||||
}
|
||||
}
|
||||
|
||||
sealed abstract case class MediaType private[http] (value: String)(val mainType: String,
|
||||
val subType: String,
|
||||
val compressible: Boolean,
|
||||
val encoding: MediaType.Encoding,
|
||||
val fileExtensions: immutable.Seq[String],
|
||||
val params: Map[String, String])
|
||||
extends jm.MediaType with LazyValueBytesRenderable with WithQValue[MediaRange] {
|
||||
def isApplication = false
|
||||
def isAudio = false
|
||||
def isImage = false
|
||||
def isMessage = false
|
||||
def isMultipart = false
|
||||
def isText = false
|
||||
def isVideo = false
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with the params replaced by the given ones.
|
||||
*/
|
||||
def withParams(params: Map[String, String]): MediaType
|
||||
|
||||
/**
|
||||
* Constructs a `ContentType` from this instance and the given charset.
|
||||
*/
|
||||
def withCharset(charset: HttpCharset): ContentType = ContentType(this, charset)
|
||||
|
||||
def withQValue(qValue: Float): MediaRange = MediaRange(this, qValue.toFloat)
|
||||
}
|
||||
|
||||
class MultipartMediaType private[http] (_value: String, _subType: String, _params: Map[String, String])
|
||||
extends MediaType(_value)("multipart", _subType, compressible = true, encoding = MediaType.Encoding.Open, Nil, _params) {
|
||||
override def isMultipart = true
|
||||
def withBoundary(boundary: String): MultipartMediaType = withParams {
|
||||
if (boundary.isEmpty) params - "boundary" else params.updated("boundary", boundary)
|
||||
}
|
||||
def withParams(params: Map[String, String]) = MediaTypes.multipart(subType, params)
|
||||
}
|
||||
override def equals(that: Any): Boolean =
|
||||
that match {
|
||||
case x: MediaType ⇒ value equalsIgnoreCase x.value
|
||||
case _ ⇒ false
|
||||
}
|
||||
|
||||
sealed abstract class NonMultipartMediaType private[http] (_value: String, _mainType: String, _subType: String,
|
||||
_compressible: Boolean, _encoding: MediaType.Encoding,
|
||||
_fileExtensions: immutable.Seq[String],
|
||||
_params: Map[String, String])
|
||||
extends MediaType(_value)(_mainType, _subType, _compressible, _encoding, _fileExtensions, _params) {
|
||||
private[http] def this(mainType: String, subType: String, compressible: Boolean, encoding: MediaType.Encoding,
|
||||
fileExtensions: immutable.Seq[String]) =
|
||||
this(mainType + '/' + subType, mainType, subType, compressible, encoding, fileExtensions, Map.empty)
|
||||
def withParams(params: Map[String, String]) =
|
||||
MediaType.custom(mainType, subType, encoding, compressible, fileExtensions, params)
|
||||
override def hashCode(): Int = value.hashCode
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
def toRange = jm.MediaRanges.create(this)
|
||||
def toRange(qValue: Float) = jm.MediaRanges.create(this, qValue)
|
||||
}
|
||||
|
||||
object MediaType {
|
||||
sealed abstract class Encoding(val charset: Option[HttpCharset])
|
||||
object Encoding {
|
||||
/**
|
||||
* Indicates that the media type is non-textual and a character encoding therefore has no meaning.
|
||||
*/
|
||||
case object Binary extends Encoding(None)
|
||||
|
||||
/**
|
||||
* Indicates that the media-type allow for flexible character encoding through a `charset` parameter.
|
||||
*/
|
||||
case object Open extends Encoding(None)
|
||||
def applicationBinary(subType: String, compressible: Boolean, fileExtensions: String*): Binary =
|
||||
new Binary("application/" + subType, "application", subType, compressible, fileExtensions.toList) {
|
||||
override def isApplication = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that a media-type is textual and mandates a clearly defined character encoding.
|
||||
*/
|
||||
final case class Fixed(cs: HttpCharset) extends Encoding(Some(cs))
|
||||
}
|
||||
def applicationWithFixedCharset(subType: String, charset: HttpCharset,
|
||||
fileExtensions: String*): WithFixedCharset =
|
||||
new WithFixedCharset("application/" + subType, "application", subType, charset, fileExtensions.toList) {
|
||||
override def isApplication = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom media type.
|
||||
*/
|
||||
def custom(mainType: String, subType: String, encoding: MediaType.Encoding,
|
||||
compressible: Boolean = false, fileExtensions: immutable.Seq[String] = Nil,
|
||||
params: Map[String, String] = Map.empty, allowArbitrarySubtypes: Boolean = false): MediaType = {
|
||||
require(mainType != "multipart", "Cannot create a MultipartMediaType here, use `multipart.apply` instead!")
|
||||
def applicationWithOpenCharset(subType: String, fileExtensions: String*): WithOpenCharset =
|
||||
new NonMultipartWithOpenCharset("application/" + subType, "application", subType, fileExtensions.toList) {
|
||||
override def isApplication = true
|
||||
}
|
||||
|
||||
def audio(subType: String, compressible: Boolean, fileExtensions: String*): Binary =
|
||||
new Binary("audio/" + subType, "audio", subType, compressible, fileExtensions.toList) {
|
||||
override def isAudio = true
|
||||
}
|
||||
|
||||
def image(subType: String, compressible: Boolean, fileExtensions: String*): Binary =
|
||||
new Binary("image/" + subType, "image", subType, compressible, fileExtensions.toList) {
|
||||
override def isImage = true
|
||||
}
|
||||
|
||||
def message(subType: String, compressible: Boolean, fileExtensions: String*): Binary =
|
||||
new Binary("message/" + subType, "message", subType, compressible, fileExtensions.toList) {
|
||||
override def isMessage = true
|
||||
}
|
||||
|
||||
def text(subType: String, fileExtensions: String*): WithOpenCharset =
|
||||
new NonMultipartWithOpenCharset("text/" + subType, "text", subType, fileExtensions.toList) {
|
||||
override def isText = true
|
||||
}
|
||||
|
||||
def video(subType: String, compressible: Boolean, fileExtensions: String*): Binary =
|
||||
new Binary("video/" + subType, "video", subType, compressible, fileExtensions.toList) {
|
||||
override def isVideo = true
|
||||
}
|
||||
|
||||
def customBinary(mainType: String, subType: String, compressible: Boolean, fileExtensions: List[String] = Nil,
|
||||
params: Map[String, String] = Map.empty, allowArbitrarySubtypes: Boolean = false): Binary = {
|
||||
require(mainType != "multipart", "Cannot create a MediaType.Multipart here, use `customMultipart` instead!")
|
||||
require(allowArbitrarySubtypes || subType != "*", "Cannot create a MediaRange here, use `MediaRange.custom` instead!")
|
||||
val r = new StringRendering ~~ mainType ~~ '/' ~~ subType
|
||||
if (params.nonEmpty) params foreach { case (k, v) ⇒ r ~~ ';' ~~ ' ' ~~ k ~~ '=' ~~# v }
|
||||
new NonMultipartMediaType(r.get, mainType, subType, compressible, encoding, fileExtensions, params) {
|
||||
val _params = params
|
||||
new Binary(renderValue(mainType, subType, params), mainType, subType, compressible, fileExtensions) {
|
||||
override def params = _params
|
||||
override def isApplication = mainType == "application"
|
||||
override def isAudio = mainType == "audio"
|
||||
override def isImage = mainType == "image"
|
||||
|
|
@ -251,26 +123,135 @@ object MediaType {
|
|||
}
|
||||
}
|
||||
|
||||
def custom(value: String, encoding: MediaType.Encoding): MediaType = {
|
||||
def customWithFixedCharset(mainType: String, subType: String, charset: HttpCharset, fileExtensions: List[String] = Nil,
|
||||
params: Map[String, String] = Map.empty,
|
||||
allowArbitrarySubtypes: Boolean = false): WithFixedCharset = {
|
||||
require(mainType != "multipart", "Cannot create a MediaType.Multipart here, use `customMultipart` instead!")
|
||||
require(allowArbitrarySubtypes || subType != "*", "Cannot create a MediaRange here, use `MediaRange.custom` instead!")
|
||||
val _params = params
|
||||
new WithFixedCharset(renderValue(mainType, subType, params), mainType, subType, charset, fileExtensions) {
|
||||
override def params = _params
|
||||
override def isApplication = mainType == "application"
|
||||
override def isAudio = mainType == "audio"
|
||||
override def isImage = mainType == "image"
|
||||
override def isMessage = mainType == "message"
|
||||
override def isText = mainType == "text"
|
||||
override def isVideo = mainType == "video"
|
||||
}
|
||||
}
|
||||
|
||||
def customWithOpenCharset(mainType: String, subType: String, fileExtensions: List[String] = Nil,
|
||||
params: Map[String, String] = Map.empty,
|
||||
allowArbitrarySubtypes: Boolean = false): WithOpenCharset = {
|
||||
require(mainType != "multipart", "Cannot create a MediaType.Multipart here, use `customMultipart` instead!")
|
||||
require(allowArbitrarySubtypes || subType != "*", "Cannot create a MediaRange here, use `MediaRange.custom` instead!")
|
||||
val _params = params
|
||||
new NonMultipartWithOpenCharset(renderValue(mainType, subType, params), mainType, subType, fileExtensions) {
|
||||
override def params = _params
|
||||
override def isApplication = mainType == "application"
|
||||
override def isAudio = mainType == "audio"
|
||||
override def isImage = mainType == "image"
|
||||
override def isMessage = mainType == "message"
|
||||
override def isText = mainType == "text"
|
||||
override def isVideo = mainType == "video"
|
||||
}
|
||||
}
|
||||
|
||||
def customMultipart(subType: String, params: Map[String, String]): Multipart = {
|
||||
require(subType != "*", "Cannot create a MediaRange here, use MediaRanges.`multipart/*` instead!")
|
||||
new Multipart(subType, params)
|
||||
}
|
||||
|
||||
def custom(value: String, binary: Boolean, compressible: Boolean = true,
|
||||
fileExtensions: List[String] = Nil): MediaType = {
|
||||
val parts = value.split('/')
|
||||
if (parts.length != 2) throw new IllegalArgumentException(value + " is not a valid media-type")
|
||||
custom(parts(0), parts(1), encoding)
|
||||
require(parts.length == 2, s"`$value` is not a valid media-type. It must consist of two parts separated by '/'.")
|
||||
if (binary) customBinary(parts(0), parts(1), compressible, fileExtensions)
|
||||
else customWithOpenCharset(parts(0), parts(1), fileExtensions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to parse a ``MediaType`` value from the given String. Returns ``Right(mediaType)`` if successful and
|
||||
* ``Left(errors)`` otherwise.
|
||||
* Tries to parse a ``MediaType`` value from the given String.
|
||||
* Returns ``Right(mediaType)`` if successful and ``Left(errors)`` otherwise.
|
||||
*/
|
||||
def parse(value: String): Either[List[ErrorInfo], MediaType] =
|
||||
ContentType.parse(value).right.map(_.mediaType)
|
||||
|
||||
def unapply(mediaType: MediaType): Option[String] = Some(mediaType.value)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private def renderValue(mainType: String, subType: String, params: Map[String, String]): String = {
|
||||
val r = new StringRendering ~~ mainType ~~ '/' ~~ subType
|
||||
if (params.nonEmpty) params foreach { case (k, v) ⇒ r ~~ ';' ~~ ' ' ~~ k ~~ '=' ~~# v }
|
||||
r.get
|
||||
}
|
||||
|
||||
sealed abstract class Binary(val value: String, val mainType: String, val subType: String, val compressible: Boolean,
|
||||
val fileExtensions: List[String]) extends MediaType with jm.MediaType.Binary {
|
||||
def binary = true
|
||||
def params: Map[String, String] = Map.empty
|
||||
def withParams(params: Map[String, String]): Binary with MediaType =
|
||||
customBinary(mainType, subType, compressible, fileExtensions, params)
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
def toContentType: ContentType.Binary = ContentType(this)
|
||||
}
|
||||
|
||||
sealed abstract class NonBinary extends MediaType with jm.MediaType.NonBinary {
|
||||
def binary = false
|
||||
def compressible = true
|
||||
}
|
||||
|
||||
sealed abstract class WithFixedCharset(val value: String, val mainType: String, val subType: String,
|
||||
val charset: HttpCharset, val fileExtensions: List[String])
|
||||
extends NonBinary with jm.MediaType.WithFixedCharset {
|
||||
def params: Map[String, String] = Map.empty
|
||||
def withParams(params: Map[String, String]): WithFixedCharset with MediaType =
|
||||
customWithFixedCharset(mainType, subType, charset, fileExtensions, params)
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
def toContentType: ContentType.WithFixedCharset = ContentType(this)
|
||||
}
|
||||
|
||||
sealed abstract class WithOpenCharset extends NonBinary with jm.MediaType.WithOpenCharset {
|
||||
def withCharset(charset: HttpCharset): ContentType.WithCharset = ContentType(this, charset)
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
def toContentType(charset: jm.HttpCharset): ContentType.WithCharset = withCharset(charset.asScala)
|
||||
}
|
||||
|
||||
sealed abstract class NonMultipartWithOpenCharset(val value: String, val mainType: String, val subType: String,
|
||||
val fileExtensions: List[String]) extends WithOpenCharset {
|
||||
def params: Map[String, String] = Map.empty
|
||||
def withParams(params: Map[String, String]): WithOpenCharset with MediaType =
|
||||
customWithOpenCharset(mainType, subType, fileExtensions, params)
|
||||
}
|
||||
|
||||
final class Multipart(val subType: String, val params: Map[String, String])
|
||||
extends WithOpenCharset with jm.MediaType.Multipart {
|
||||
val value = renderValue(mainType, subType, params)
|
||||
override def mainType = "multipart"
|
||||
override def isMultipart = true
|
||||
override def fileExtensions = Nil
|
||||
def withParams(params: Map[String, String]): MediaType.Multipart = new MediaType.Multipart(subType, params)
|
||||
def withBoundary(boundary: String): MediaType.Multipart =
|
||||
withParams(if (boundary.isEmpty) params - "boundary" else params.updated("boundary", boundary))
|
||||
}
|
||||
}
|
||||
|
||||
object MediaTypes extends ObjectRegistry[(String, String), MediaType] {
|
||||
import MediaType.Encoding
|
||||
|
||||
private[this] var extensionMap = Map.empty[String, MediaType]
|
||||
|
||||
private def register(mediaType: MediaType): MediaType = {
|
||||
def forExtension(ext: String): Option[MediaType] = extensionMap.get(ext.toRootLowerCase)
|
||||
|
||||
private def register[T <: MediaType](mediaType: T): T = {
|
||||
def registerFileExtension(ext: String): Unit = {
|
||||
val lcExt = ext.toRootLowerCase
|
||||
require(!extensionMap.contains(lcExt), s"Extension '$ext' clash: media-types '${extensionMap(lcExt)}' and '$mediaType'")
|
||||
|
|
@ -280,120 +261,95 @@ object MediaTypes extends ObjectRegistry[(String, String), MediaType] {
|
|||
register(mediaType.mainType.toRootLowerCase -> mediaType.subType.toRootLowerCase, mediaType)
|
||||
}
|
||||
|
||||
def forExtension(ext: String): Option[MediaType] = extensionMap.get(ext.toRootLowerCase)
|
||||
|
||||
private def app(subType: String, compressible: Boolean, encoding: Encoding, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("application", subType, compressible, encoding, immutable.Seq(fileExtensions: _*)) {
|
||||
override def isApplication = true
|
||||
}
|
||||
}
|
||||
private def aud(subType: String, compressible: Boolean, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("audio", subType, compressible, encoding = Encoding.Binary, immutable.Seq(fileExtensions: _*)) {
|
||||
override def isAudio = true
|
||||
}
|
||||
}
|
||||
private def img(subType: String, compressible: Boolean, encoding: Encoding, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("image", subType, compressible, encoding, immutable.Seq(fileExtensions: _*)) {
|
||||
override def isImage = true
|
||||
}
|
||||
}
|
||||
private def msg(subType: String, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("message", subType, compressible = true, encoding = Encoding.Binary,
|
||||
immutable.Seq(fileExtensions: _*)) {
|
||||
override def isMessage = true
|
||||
}
|
||||
}
|
||||
private def txt(subType: String, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("text", subType, compressible = true, encoding = Encoding.Open, immutable.Seq(fileExtensions: _*)) {
|
||||
override def isText = true
|
||||
}
|
||||
}
|
||||
private def vid(subType: String, fileExtensions: String*) = register {
|
||||
new NonMultipartMediaType("video", subType, compressible = false, encoding = Encoding.Binary, immutable.Seq(fileExtensions: _*)) {
|
||||
override def isVideo = true
|
||||
}
|
||||
}
|
||||
|
||||
import MediaType._
|
||||
|
||||
/////////////////////////// PREDEFINED MEDIA-TYPE DEFINITION ////////////////////////////
|
||||
// format: OFF
|
||||
private final val compressible = true // compile-time constant
|
||||
private final val uncompressible = false // compile-time constant
|
||||
private def binary = Encoding.Binary
|
||||
private def openEncoding = Encoding.Open
|
||||
|
||||
private def abin(st: String, c: Boolean, fe: String*) = register(applicationBinary(st, c, fe: _*))
|
||||
private def awfc(st: String, cs: HttpCharset, fe: String*) = register(applicationWithFixedCharset(st, cs, fe: _*))
|
||||
private def awoc(st: String, fe: String*) = register(applicationWithOpenCharset(st, fe: _*))
|
||||
private def aud(st: String, c: Boolean, fe: String*) = register(audio(st, c, fe: _*))
|
||||
private def img(st: String, c: Boolean, fe: String*) = register(image(st, c, fe: _*))
|
||||
private def msg(st: String, fe: String*) = register(message(st, compressible, fe: _*))
|
||||
private def txt(st: String, fe: String*) = register(text(st, fe: _*))
|
||||
private def vid(st: String, fe: String*) = register(video(st, compressible, fe: _*))
|
||||
|
||||
// dummy value currently only used by ContentType.NoContentType
|
||||
private[http] val NoMediaType = new NonMultipartMediaType("none", "none", false, Encoding.Binary, immutable.Seq.empty) {}
|
||||
private[http] val NoMediaType = MediaType.customBinary("none", "none", compressible = false)
|
||||
|
||||
val `application/atom+xml` = app("atom+xml", compressible, openEncoding, "atom")
|
||||
val `application/base64` = app("base64", compressible, binary, "mm", "mme")
|
||||
val `application/excel` = app("excel", uncompressible, binary, "xl", "xla", "xlb", "xlc", "xld", "xlk", "xll", "xlm", "xls", "xlt", "xlv", "xlw")
|
||||
val `application/font-woff` = app("font-woff", uncompressible, binary, "woff")
|
||||
val `application/gnutar` = app("gnutar", uncompressible, binary, "tgz")
|
||||
val `application/java-archive` = app("java-archive", uncompressible, binary, "jar", "war", "ear")
|
||||
val `application/javascript` = app("javascript", compressible, openEncoding, "js")
|
||||
val `application/json` = app("json", compressible, Encoding.Fixed(HttpCharsets.`UTF-8`), "json")
|
||||
val `application/json-patch+json` = app("json-patch+json", compressible, Encoding.Fixed(HttpCharsets.`UTF-8`))
|
||||
val `application/lha` = app("lha", uncompressible, binary, "lha")
|
||||
val `application/lzx` = app("lzx", uncompressible, binary, "lzx")
|
||||
val `application/mspowerpoint` = app("mspowerpoint", uncompressible, binary, "pot", "pps", "ppt", "ppz")
|
||||
val `application/msword` = app("msword", uncompressible, binary, "doc", "dot", "w6w", "wiz", "word", "wri")
|
||||
val `application/octet-stream` = app("octet-stream", uncompressible, binary, "a", "bin", "class", "dump", "exe", "lhx", "lzh", "o", "psd", "saveme", "zoo")
|
||||
val `application/pdf` = app("pdf", uncompressible, binary, "pdf")
|
||||
val `application/postscript` = app("postscript", compressible, binary, "ai", "eps", "ps")
|
||||
val `application/rss+xml` = app("rss+xml", compressible, openEncoding, "rss")
|
||||
val `application/soap+xml` = app("soap+xml", compressible, openEncoding)
|
||||
val `application/vnd.api+json` = app("vnd.api+json", compressible, Encoding.Fixed(HttpCharsets.`UTF-8`))
|
||||
val `application/vnd.google-earth.kml+xml` = app("vnd.google-earth.kml+xml", compressible, openEncoding, "kml")
|
||||
val `application/vnd.google-earth.kmz` = app("vnd.google-earth.kmz", uncompressible, binary, "kmz")
|
||||
val `application/vnd.ms-fontobject` = app("vnd.ms-fontobject", compressible, binary, "eot")
|
||||
val `application/vnd.oasis.opendocument.chart` = app("vnd.oasis.opendocument.chart", compressible, binary, "odc")
|
||||
val `application/vnd.oasis.opendocument.database` = app("vnd.oasis.opendocument.database", compressible, binary, "odb")
|
||||
val `application/vnd.oasis.opendocument.formula` = app("vnd.oasis.opendocument.formula", compressible, binary, "odf")
|
||||
val `application/vnd.oasis.opendocument.graphics` = app("vnd.oasis.opendocument.graphics", compressible, binary, "odg")
|
||||
val `application/vnd.oasis.opendocument.image` = app("vnd.oasis.opendocument.image", compressible, binary, "odi")
|
||||
val `application/vnd.oasis.opendocument.presentation` = app("vnd.oasis.opendocument.presentation", compressible, binary, "odp")
|
||||
val `application/vnd.oasis.opendocument.spreadsheet` = app("vnd.oasis.opendocument.spreadsheet", compressible, binary, "ods")
|
||||
val `application/vnd.oasis.opendocument.text` = app("vnd.oasis.opendocument.text", compressible, binary, "odt")
|
||||
val `application/vnd.oasis.opendocument.text-master` = app("vnd.oasis.opendocument.text-master", compressible, binary, "odm", "otm")
|
||||
val `application/vnd.oasis.opendocument.text-web` = app("vnd.oasis.opendocument.text-web", compressible, binary, "oth")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.presentation` = app("vnd.openxmlformats-officedocument.presentationml.presentation", compressible, binary, "pptx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.slide` = app("vnd.openxmlformats-officedocument.presentationml.slide", compressible, binary, "sldx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.slideshow` = app("vnd.openxmlformats-officedocument.presentationml.slideshow", compressible, binary, "ppsx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.template` = app("vnd.openxmlformats-officedocument.presentationml.template", compressible, binary, "potx")
|
||||
val `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` = app("vnd.openxmlformats-officedocument.spreadsheetml.sheet", compressible, binary, "xlsx")
|
||||
val `application/vnd.openxmlformats-officedocument.spreadsheetml.template` = app("vnd.openxmlformats-officedocument.spreadsheetml.template", compressible, binary, "xltx")
|
||||
val `application/vnd.openxmlformats-officedocument.wordprocessingml.document` = app("vnd.openxmlformats-officedocument.wordprocessingml.document", compressible, binary, "docx")
|
||||
val `application/vnd.openxmlformats-officedocument.wordprocessingml.template` = app("vnd.openxmlformats-officedocument.wordprocessingml.template", compressible, binary, "dotx")
|
||||
val `application/x-7z-compressed` = app("x-7z-compressed", uncompressible, binary, "7z", "s7z")
|
||||
val `application/x-ace-compressed` = app("x-ace-compressed", uncompressible, binary, "ace")
|
||||
val `application/x-apple-diskimage` = app("x-apple-diskimage", uncompressible, binary, "dmg")
|
||||
val `application/x-arc-compressed` = app("x-arc-compressed", uncompressible, binary, "arc")
|
||||
val `application/x-bzip` = app("x-bzip", uncompressible, binary, "bz")
|
||||
val `application/x-bzip2` = app("x-bzip2", uncompressible, binary, "boz", "bz2")
|
||||
val `application/x-chrome-extension` = app("x-chrome-extension", uncompressible, binary, "crx")
|
||||
val `application/x-compress` = app("x-compress", uncompressible, binary, "z")
|
||||
val `application/x-compressed` = app("x-compressed", uncompressible, binary, "gz")
|
||||
val `application/x-debian-package` = app("x-debian-package", compressible, binary, "deb")
|
||||
val `application/x-dvi` = app("x-dvi", compressible, binary, "dvi")
|
||||
val `application/x-font-truetype` = app("x-font-truetype", compressible, binary, "ttf")
|
||||
val `application/x-font-opentype` = app("x-font-opentype", compressible, binary, "otf")
|
||||
val `application/x-gtar` = app("x-gtar", uncompressible, binary, "gtar")
|
||||
val `application/x-gzip` = app("x-gzip", uncompressible, binary, "gzip")
|
||||
val `application/x-latex` = app("x-latex", compressible, binary, "latex", "ltx")
|
||||
val `application/x-rar-compressed` = app("x-rar-compressed", uncompressible, binary, "rar")
|
||||
val `application/x-redhat-package-manager` = app("x-redhat-package-manager", uncompressible, binary, "rpm")
|
||||
val `application/x-shockwave-flash` = app("x-shockwave-flash", uncompressible, binary, "swf")
|
||||
val `application/x-tar` = app("x-tar", compressible, binary, "tar")
|
||||
val `application/x-tex` = app("x-tex", compressible, binary, "tex")
|
||||
val `application/x-texinfo` = app("x-texinfo", compressible, binary, "texi", "texinfo")
|
||||
val `application/x-vrml` = app("x-vrml", compressible, openEncoding, "vrml")
|
||||
val `application/x-www-form-urlencoded` = app("x-www-form-urlencoded", compressible, openEncoding)
|
||||
val `application/x-x509-ca-cert` = app("x-x509-ca-cert", compressible, binary, "der")
|
||||
val `application/x-xpinstall` = app("x-xpinstall", uncompressible, binary, "xpi")
|
||||
val `application/xhtml+xml` = app("xhtml+xml", compressible, openEncoding)
|
||||
val `application/xml-dtd` = app("xml-dtd", compressible, openEncoding)
|
||||
val `application/xml` = app("xml", compressible, openEncoding)
|
||||
val `application/zip` = app("zip", uncompressible, binary, "zip")
|
||||
val `application/atom+xml` = awoc("atom+xml", "atom")
|
||||
val `application/base64` = awoc("base64", "mm", "mme")
|
||||
val `application/excel` = abin("excel", uncompressible, "xl", "xla", "xlb", "xlc", "xld", "xlk", "xll", "xlm", "xls", "xlt", "xlv", "xlw")
|
||||
val `application/font-woff` = abin("font-woff", uncompressible, "woff")
|
||||
val `application/gnutar` = abin("gnutar", uncompressible, "tgz")
|
||||
val `application/java-archive` = abin("java-archive", uncompressible, "jar", "war", "ear")
|
||||
val `application/javascript` = awoc("javascript", "js")
|
||||
val `application/json` = awfc("json", HttpCharsets.`UTF-8`, "json")
|
||||
val `application/json-patch+json` = awfc("json-patch+json", HttpCharsets.`UTF-8`)
|
||||
val `application/lha` = abin("lha", uncompressible, "lha")
|
||||
val `application/lzx` = abin("lzx", uncompressible, "lzx")
|
||||
val `application/mspowerpoint` = abin("mspowerpoint", uncompressible, "pot", "pps", "ppt", "ppz")
|
||||
val `application/msword` = abin("msword", uncompressible, "doc", "dot", "w6w", "wiz", "word", "wri")
|
||||
val `application/octet-stream` = abin("octet-stream", uncompressible, "a", "bin", "class", "dump", "exe", "lhx", "lzh", "o", "psd", "saveme", "zoo")
|
||||
val `application/pdf` = abin("pdf", uncompressible, "pdf")
|
||||
val `application/postscript` = abin("postscript", compressible, "ai", "eps", "ps")
|
||||
val `application/rss+xml` = awoc("rss+xml", "rss")
|
||||
val `application/soap+xml` = awoc("soap+xml")
|
||||
val `application/vnd.api+json` = awfc("vnd.api+json", HttpCharsets.`UTF-8`)
|
||||
val `application/vnd.google-earth.kml+xml` = awoc("vnd.google-earth.kml+xml", "kml")
|
||||
val `application/vnd.google-earth.kmz` = abin("vnd.google-earth.kmz", uncompressible, "kmz")
|
||||
val `application/vnd.ms-fontobject` = abin("vnd.ms-fontobject", compressible, "eot")
|
||||
val `application/vnd.oasis.opendocument.chart` = abin("vnd.oasis.opendocument.chart", compressible, "odc")
|
||||
val `application/vnd.oasis.opendocument.database` = abin("vnd.oasis.opendocument.database", compressible, "odb")
|
||||
val `application/vnd.oasis.opendocument.formula` = abin("vnd.oasis.opendocument.formula", compressible, "odf")
|
||||
val `application/vnd.oasis.opendocument.graphics` = abin("vnd.oasis.opendocument.graphics", compressible, "odg")
|
||||
val `application/vnd.oasis.opendocument.image` = abin("vnd.oasis.opendocument.image", compressible, "odi")
|
||||
val `application/vnd.oasis.opendocument.presentation` = abin("vnd.oasis.opendocument.presentation", compressible, "odp")
|
||||
val `application/vnd.oasis.opendocument.spreadsheet` = abin("vnd.oasis.opendocument.spreadsheet", compressible, "ods")
|
||||
val `application/vnd.oasis.opendocument.text` = abin("vnd.oasis.opendocument.text", compressible, "odt")
|
||||
val `application/vnd.oasis.opendocument.text-master` = abin("vnd.oasis.opendocument.text-master", compressible, "odm", "otm")
|
||||
val `application/vnd.oasis.opendocument.text-web` = abin("vnd.oasis.opendocument.text-web", compressible, "oth")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.presentation` = abin("vnd.openxmlformats-officedocument.presentationml.presentation", compressible, "pptx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.slide` = abin("vnd.openxmlformats-officedocument.presentationml.slide", compressible, "sldx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.slideshow` = abin("vnd.openxmlformats-officedocument.presentationml.slideshow", compressible, "ppsx")
|
||||
val `application/vnd.openxmlformats-officedocument.presentationml.template` = abin("vnd.openxmlformats-officedocument.presentationml.template", compressible, "potx")
|
||||
val `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` = abin("vnd.openxmlformats-officedocument.spreadsheetml.sheet", compressible, "xlsx")
|
||||
val `application/vnd.openxmlformats-officedocument.spreadsheetml.template` = abin("vnd.openxmlformats-officedocument.spreadsheetml.template", compressible, "xltx")
|
||||
val `application/vnd.openxmlformats-officedocument.wordprocessingml.document` = abin("vnd.openxmlformats-officedocument.wordprocessingml.document", compressible, "docx")
|
||||
val `application/vnd.openxmlformats-officedocument.wordprocessingml.template` = abin("vnd.openxmlformats-officedocument.wordprocessingml.template", compressible, "dotx")
|
||||
val `application/x-7z-compressed` = abin("x-7z-compressed", uncompressible, "7z", "s7z")
|
||||
val `application/x-ace-compressed` = abin("x-ace-compressed", uncompressible, "ace")
|
||||
val `application/x-apple-diskimage` = abin("x-apple-diskimage", uncompressible, "dmg")
|
||||
val `application/x-arc-compressed` = abin("x-arc-compressed", uncompressible, "arc")
|
||||
val `application/x-bzip` = abin("x-bzip", uncompressible, "bz")
|
||||
val `application/x-bzip2` = abin("x-bzip2", uncompressible, "boz", "bz2")
|
||||
val `application/x-chrome-extension` = abin("x-chrome-extension", uncompressible, "crx")
|
||||
val `application/x-compress` = abin("x-compress", uncompressible, "z")
|
||||
val `application/x-compressed` = abin("x-compressed", uncompressible, "gz")
|
||||
val `application/x-debian-package` = abin("x-debian-package", compressible, "deb")
|
||||
val `application/x-dvi` = abin("x-dvi", compressible, "dvi")
|
||||
val `application/x-font-truetype` = abin("x-font-truetype", compressible, "ttf")
|
||||
val `application/x-font-opentype` = abin("x-font-opentype", compressible, "otf")
|
||||
val `application/x-gtar` = abin("x-gtar", uncompressible, "gtar")
|
||||
val `application/x-gzip` = abin("x-gzip", uncompressible, "gzip")
|
||||
val `application/x-latex` = awoc("x-latex", "latex", "ltx")
|
||||
val `application/x-rar-compressed` = abin("x-rar-compressed", uncompressible, "rar")
|
||||
val `application/x-redhat-package-manager` = abin("x-redhat-package-manager", uncompressible, "rpm")
|
||||
val `application/x-shockwave-flash` = abin("x-shockwave-flash", uncompressible, "swf")
|
||||
val `application/x-tar` = abin("x-tar", compressible, "tar")
|
||||
val `application/x-tex` = abin("x-tex", compressible, "tex")
|
||||
val `application/x-texinfo` = abin("x-texinfo", compressible, "texi", "texinfo")
|
||||
val `application/x-vrml` = awoc("x-vrml", "vrml")
|
||||
val `application/x-www-form-urlencoded` = awoc("x-www-form-urlencoded")
|
||||
val `application/x-x509-ca-cert` = abin("x-x509-ca-cert", compressible, "der")
|
||||
val `application/x-xpinstall` = abin("x-xpinstall", uncompressible, "xpi")
|
||||
val `application/xhtml+xml` = awoc("xhtml+xml")
|
||||
val `application/xml-dtd` = awoc("xml-dtd")
|
||||
val `application/xml` = awoc("xml")
|
||||
val `application/zip` = abin("zip", uncompressible, "zip")
|
||||
|
||||
val `audio/aiff` = aud("aiff", compressible, "aif", "aifc", "aiff")
|
||||
val `audio/basic` = aud("basic", compressible, "au", "snd")
|
||||
|
|
@ -410,40 +366,34 @@ object MediaTypes extends ObjectRegistry[(String, String), MediaType] {
|
|||
val `audio/xm` = aud("xm", uncompressible, "xm")
|
||||
val `audio/webm` = aud("webm", uncompressible)
|
||||
|
||||
val `image/gif` = img("gif", uncompressible, binary, "gif")
|
||||
val `image/jpeg` = img("jpeg", uncompressible, binary, "jpe", "jpeg", "jpg")
|
||||
val `image/pict` = img("pict", compressible, binary, "pic", "pict")
|
||||
val `image/png` = img("png", uncompressible, binary, "png")
|
||||
val `image/svg+xml` = img("svg+xml", compressible, openEncoding, "svg")
|
||||
val `image/tiff` = img("tiff", compressible, binary, "tif", "tiff")
|
||||
val `image/x-icon` = img("x-icon", compressible, binary, "ico")
|
||||
val `image/x-ms-bmp` = img("x-ms-bmp", compressible, binary, "bmp")
|
||||
val `image/x-pcx` = img("x-pcx", compressible, binary, "pcx")
|
||||
val `image/x-pict` = img("x-pict", compressible, binary, "pct")
|
||||
val `image/x-quicktime` = img("x-quicktime", uncompressible, binary, "qif", "qti", "qtif")
|
||||
val `image/x-rgb` = img("x-rgb", compressible, binary, "rgb")
|
||||
val `image/x-xbitmap` = img("x-xbitmap", compressible, binary, "xbm")
|
||||
val `image/x-xpixmap` = img("x-xpixmap", compressible, binary, "xpm")
|
||||
val `image/webp` = img("webp", uncompressible, binary, "webp")
|
||||
val `image/gif` = img("gif", uncompressible, "gif")
|
||||
val `image/jpeg` = img("jpeg", uncompressible, "jpe", "jpeg", "jpg")
|
||||
val `image/pict` = img("pict", compressible, "pic", "pict")
|
||||
val `image/png` = img("png", uncompressible, "png")
|
||||
val `image/svg+xml` = img("svg+xml", compressible, "svg")
|
||||
val `image/tiff` = img("tiff", compressible, "tif", "tiff")
|
||||
val `image/x-icon` = img("x-icon", compressible, "ico")
|
||||
val `image/x-ms-bmp` = img("x-ms-bmp", compressible, "bmp")
|
||||
val `image/x-pcx` = img("x-pcx", compressible, "pcx")
|
||||
val `image/x-pict` = img("x-pict", compressible, "pct")
|
||||
val `image/x-quicktime` = img("x-quicktime", uncompressible, "qif", "qti", "qtif")
|
||||
val `image/x-rgb` = img("x-rgb", compressible, "rgb")
|
||||
val `image/x-xbitmap` = img("x-xbitmap", compressible, "xbm")
|
||||
val `image/x-xpixmap` = img("x-xpixmap", compressible, "xpm")
|
||||
val `image/webp` = img("webp", uncompressible, "webp")
|
||||
|
||||
val `message/http` = msg("http")
|
||||
val `message/delivery-status` = msg("delivery-status")
|
||||
val `message/rfc822` = msg("rfc822", "eml", "mht", "mhtml", "mime")
|
||||
|
||||
object multipart {
|
||||
def apply(subType: String, params: Map[String, String]): MultipartMediaType = {
|
||||
require(subType != "*", "Cannot create a MediaRange here, use MediaRanges.`multipart/*` instead!")
|
||||
val r = new StringRendering ~~ "multipart/" ~~ subType
|
||||
if (params.nonEmpty) params foreach { case (k, v) ⇒ r ~~ ';' ~~ ' ' ~~ k ~~ '=' ~~# v }
|
||||
new MultipartMediaType(r.get, subType, params)
|
||||
}
|
||||
def mixed (params: Map[String, String]) = apply("mixed", params)
|
||||
def alternative(params: Map[String, String]) = apply("alternative", params)
|
||||
def related (params: Map[String, String]) = apply("related", params)
|
||||
def `form-data`(params: Map[String, String]) = apply("form-data", params)
|
||||
def signed (params: Map[String, String]) = apply("signed", params)
|
||||
def encrypted (params: Map[String, String]) = apply("encrypted", params)
|
||||
def byteRanges (params: Map[String, String]) = apply("byteranges", params)
|
||||
def mixed (params: Map[String, String]) = new MediaType.Multipart("mixed", params)
|
||||
def alternative(params: Map[String, String]) = new MediaType.Multipart("alternative", params)
|
||||
def related (params: Map[String, String]) = new MediaType.Multipart("related", params)
|
||||
def `form-data`(params: Map[String, String]) = new MediaType.Multipart("form-data", params)
|
||||
def signed (params: Map[String, String]) = new MediaType.Multipart("signed", params)
|
||||
def encrypted (params: Map[String, String]) = new MediaType.Multipart("encrypted", params)
|
||||
def byteRanges (params: Map[String, String]) = new MediaType.Multipart("byteranges", params)
|
||||
}
|
||||
|
||||
val `multipart/mixed` = multipart.mixed(Map.empty)
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ import scala.concurrent.{ Future, ExecutionContext }
|
|||
import scala.collection.immutable
|
||||
import scala.util.{ Failure, Success, Try }
|
||||
import akka.stream.Materializer
|
||||
import akka.stream.scaladsl.{ Source }
|
||||
import akka.stream.scaladsl.Source
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
import akka.http.scaladsl.model.headers._
|
||||
import akka.http.impl.engine.rendering.BodyPartRenderer
|
||||
import FastFuture._
|
||||
|
||||
sealed trait Multipart {
|
||||
def mediaType: MultipartMediaType
|
||||
def mediaType: MediaType.Multipart
|
||||
def parts: Source[Multipart.BodyPart, Any]
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +41,7 @@ sealed trait Multipart {
|
|||
parts
|
||||
.transform(() ⇒ BodyPartRenderer.streamed(boundary, charset.nioCharset, partHeadersSizeHint = 128, log))
|
||||
.flatMapConcat(ConstantFun.scalaIdentityFunction)
|
||||
HttpEntity.Chunked(mediaType withBoundary boundary, chunks)
|
||||
HttpEntity.Chunked(mediaType withBoundary boundary withCharset charset, chunks)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ object Multipart {
|
|||
|
||||
override def toEntity(charset: HttpCharset, boundary: String)(implicit log: LoggingAdapter = NoLogging): HttpEntity.Strict = {
|
||||
val data = BodyPartRenderer.strict(strictParts, boundary, charset.nioCharset, partHeadersSizeHint = 128, log)
|
||||
HttpEntity(mediaType withBoundary boundary, data)
|
||||
HttpEntity(mediaType withBoundary boundary withCharset charset, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,27 +91,27 @@ object Multipart {
|
|||
* Basic model for multipart content as defined by http://tools.ietf.org/html/rfc2046.
|
||||
*/
|
||||
sealed abstract class General extends Multipart {
|
||||
def mediaType: MultipartMediaType
|
||||
def mediaType: MediaType.Multipart
|
||||
def parts: Source[General.BodyPart, Any]
|
||||
def toStrict(timeout: FiniteDuration)(implicit ec: ExecutionContext, fm: Materializer): Future[General.Strict] =
|
||||
strictify(parts)(_.toStrict(timeout)).fast.map(General.Strict(mediaType, _))
|
||||
}
|
||||
object General {
|
||||
def apply(mediaType: MultipartMediaType, parts: BodyPart.Strict*): Strict = Strict(mediaType, parts.toVector)
|
||||
def apply(mediaType: MediaType.Multipart, parts: BodyPart.Strict*): Strict = Strict(mediaType, parts.toVector)
|
||||
|
||||
def apply(_mediaType: MultipartMediaType, _parts: Source[BodyPart, Any]): General =
|
||||
def apply(_mediaType: MediaType.Multipart, _parts: Source[BodyPart, Any]): General =
|
||||
new General {
|
||||
def mediaType = _mediaType
|
||||
def parts = _parts
|
||||
override def toString = s"General($mediaType, $parts)"
|
||||
}
|
||||
|
||||
def unapply(value: General): Option[(MultipartMediaType, Source[BodyPart, Any])] = Some(value.mediaType -> value.parts)
|
||||
def unapply(value: General): Option[(MediaType.Multipart, Source[BodyPart, Any])] = Some(value.mediaType -> value.parts)
|
||||
|
||||
/**
|
||||
* Strict [[General]].
|
||||
*/
|
||||
case class Strict(mediaType: MultipartMediaType, strictParts: immutable.Seq[BodyPart.Strict]) extends General with Multipart.Strict {
|
||||
case class Strict(mediaType: MediaType.Multipart, strictParts: immutable.Seq[BodyPart.Strict]) extends General with Multipart.Strict {
|
||||
def parts: Source[BodyPart.Strict, Any] = Source(strictParts)
|
||||
override def toStrict(timeout: FiniteDuration)(implicit ec: ExecutionContext, fm: Materializer) =
|
||||
FastFuture.successful(this)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ object HttpEncodingRange {
|
|||
case class `*`(qValue: Float) extends HttpEncodingRange {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
final def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ "*;q=" ~~ qValue else r ~~ '*'
|
||||
def matches(encoding: HttpEncoding) = qValue > 0f
|
||||
def matches(encoding: HttpEncoding) = true
|
||||
def withQValue(qValue: Float) =
|
||||
if (qValue == 1.0f) `*` else if (qValue != this.qValue) `*`(qValue.toFloat) else this
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ object HttpEncodingRange {
|
|||
|
||||
final case class One(encoding: HttpEncoding, qValue: Float) extends HttpEncodingRange {
|
||||
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
|
||||
def matches(encoding: HttpEncoding) = qValue > 0f && this.encoding.value.equalsIgnoreCase(encoding.value)
|
||||
def matches(encoding: HttpEncoding) = this.encoding.value.equalsIgnoreCase(encoding.value)
|
||||
def withQValue(qValue: Float) = One(encoding, qValue)
|
||||
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ encoding ~~ ";q=" ~~ qValue else r ~~ encoding
|
||||
}
|
||||
|
|
@ -55,7 +55,6 @@ object HttpEncodings extends ObjectRegistry[String, HttpEncoding] {
|
|||
val deflate = register("deflate")
|
||||
val gzip = register("gzip")
|
||||
val identity = register("identity")
|
||||
val `identity;q=MIN` = identity.withQValue(Float.MinPositiveValue)
|
||||
val `x-compress` = register("x-compress")
|
||||
val `x-zip` = register("x-zip")
|
||||
// format: ON
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ class RequestParserSpec extends FreeSpec with Matchers with BeforeAndAfterAll {
|
|||
|Content-Type: application/pdf
|
||||
|Content-Length: 0
|
||||
|
|
||||
|""" should parseTo(HttpRequest(GET, "/data", List(Host("x")), HttpEntity(`application/pdf`, "")))
|
||||
|""" should parseTo(HttpRequest(GET, "/data", List(Host("x")), HttpEntity.empty(`application/pdf`)))
|
||||
closeAfterResponseCompletion shouldEqual Seq(false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.scalatest.{ FreeSpec, Matchers, BeforeAndAfterAll }
|
|||
import org.scalatest.matchers.Matcher
|
||||
import akka.actor.ActorSystem
|
||||
import akka.event.NoLogging
|
||||
import akka.util.ByteString
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.model.headers._
|
||||
import akka.http.impl.util._
|
||||
|
|
@ -99,7 +100,7 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
HttpRequest(PUT, "/abc/xyz", List(
|
||||
RawHeader("X-Fancy", "naa"),
|
||||
RawHeader("Cache-Control", "public"),
|
||||
Host("spray.io")), HttpEntity(ContentTypes.NoContentType, "The content please!")) should renderTo {
|
||||
Host("spray.io")), HttpEntity(ContentTypes.NoContentType, ByteString("The content please!"))) should renderTo {
|
||||
"""PUT /abc/xyz HTTP/1.1
|
||||
|X-Fancy: naa
|
||||
|Cache-Control: public
|
||||
|
|
@ -140,11 +141,11 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
|
||||
"PUT request with empty chunk stream and custom Content-Type" in new TestSetup() {
|
||||
pending // Disabled until #15981 is fixed
|
||||
HttpRequest(PUT, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain`, source())) should renderTo {
|
||||
HttpRequest(PUT, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain(UTF-8)`, source())) should renderTo {
|
||||
"""PUT /abc/xyz HTTP/1.1
|
||||
|Host: test.com:8080
|
||||
|User-Agent: akka-http/1.0.0
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|Content-Length: 0
|
||||
|
|
||||
|"""
|
||||
|
|
@ -152,13 +153,13 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
}
|
||||
|
||||
"POST request with body" in new TestSetup() {
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain`,
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain(UTF-8)`,
|
||||
source("XXXX", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) should renderTo {
|
||||
"""POST /abc/xyz HTTP/1.1
|
||||
|Host: test.com:8080
|
||||
|User-Agent: akka-http/1.0.0
|
||||
|Transfer-Encoding: chunked
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|4
|
||||
|XXXX
|
||||
|
|
@ -177,13 +178,13 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
ChunkStreamPart("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
|
||||
LastChunk)
|
||||
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain`,
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain(UTF-8)`,
|
||||
Source(chunks))) should renderTo {
|
||||
"""POST /abc/xyz HTTP/1.1
|
||||
|Host: test.com:8080
|
||||
|User-Agent: akka-http/1.0.0
|
||||
|Transfer-Encoding: chunked
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|4
|
||||
|XXXX
|
||||
|
|
@ -203,13 +204,13 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
LastChunk,
|
||||
LastChunk)
|
||||
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain`,
|
||||
HttpRequest(POST, "/abc/xyz", entity = Chunked(ContentTypes.`text/plain(UTF-8)`,
|
||||
Source(chunks))) should renderTo {
|
||||
"""POST /abc/xyz HTTP/1.1
|
||||
|Host: test.com:8080
|
||||
|User-Agent: akka-http/1.0.0
|
||||
|Transfer-Encoding: chunked
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|4
|
||||
|XXXX
|
||||
|
|
@ -223,12 +224,12 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
|
||||
"POST request with custom Transfer-Encoding header" in new TestSetup() {
|
||||
HttpRequest(POST, "/abc/xyz", List(`Transfer-Encoding`(TransferEncodings.Extension("fancy"))),
|
||||
entity = Chunked(ContentTypes.`text/plain`, source("XXXX", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) should renderTo {
|
||||
entity = Chunked(ContentTypes.`text/plain(UTF-8)`, source("XXXX", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) should renderTo {
|
||||
"""POST /abc/xyz HTTP/1.1
|
||||
|Transfer-Encoding: fancy, chunked
|
||||
|Host: test.com:8080
|
||||
|User-Agent: akka-http/1.0.0
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|4
|
||||
|XXXX
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class ResponseRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
|
||||
"status 400, a few headers and a body with an explicitly suppressed Content Type header" in new TestSetup() {
|
||||
HttpResponse(400, List(Age(30), Connection("Keep-Alive")),
|
||||
HttpEntity(contentType = ContentTypes.NoContentType, "Small f*ck up overhere!")) should renderTo {
|
||||
HttpEntity(ContentTypes.NoContentType, ByteString("Small f*ck up overhere!"))) should renderTo {
|
||||
"""HTTP/1.1 400 Bad Request
|
||||
|Age: 30
|
||||
|Server: akka-http/1.0.0
|
||||
|
|
@ -202,7 +202,7 @@ class ResponseRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
|
|||
"a response with a Default (streamed with explicit content-length body," - {
|
||||
"status 400 and a few headers" in new TestSetup() {
|
||||
HttpResponse(400, List(Age(30), Connection("Keep-Alive")),
|
||||
entity = Default(contentType = ContentTypes.`text/plain(UTF-8)`, 23, source(ByteString("Small f*ck up overhere!")))) should renderTo {
|
||||
entity = Default(ContentTypes.`text/plain(UTF-8)`, 23, source(ByteString("Small f*ck up overhere!")))) should renderTo {
|
||||
"""HTTP/1.1 400 Bad Request
|
||||
|Age: 30
|
||||
|Server: akka-http/1.0.0
|
||||
|
|
|
|||
|
|
@ -385,12 +385,12 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
|""")
|
||||
inside(expectRequest()) {
|
||||
case HttpRequest(GET, _, _, _, _) ⇒
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Strict(ContentTypes.`text/plain`, ByteString("abcd"))))
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Strict(ContentTypes.`text/plain(UTF-8)`, ByteString("abcd"))))
|
||||
expectResponseWithWipedDate(
|
||||
"""|HTTP/1.1 200 OK
|
||||
|Server: akka-http/test
|
||||
|Date: XXXX
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|Content-Length: 4
|
||||
|
|
||||
|""")
|
||||
|
|
@ -405,14 +405,14 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
val data = TestPublisher.manualProbe[ByteString]()
|
||||
inside(expectRequest()) {
|
||||
case HttpRequest(GET, _, _, _, _) ⇒
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Default(ContentTypes.`text/plain`, 4, Source(data))))
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Default(ContentTypes.`text/plain(UTF-8)`, 4, Source(data))))
|
||||
val dataSub = data.expectSubscription()
|
||||
dataSub.expectCancellation()
|
||||
expectResponseWithWipedDate(
|
||||
"""|HTTP/1.1 200 OK
|
||||
|Server: akka-http/test
|
||||
|Date: XXXX
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|Content-Length: 4
|
||||
|
|
||||
|""")
|
||||
|
|
@ -427,14 +427,14 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
val data = TestPublisher.manualProbe[ByteString]()
|
||||
inside(expectRequest()) {
|
||||
case HttpRequest(GET, _, _, _, _) ⇒
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.CloseDelimited(ContentTypes.`text/plain`, Source(data))))
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.CloseDelimited(ContentTypes.`text/plain(UTF-8)`, Source(data))))
|
||||
val dataSub = data.expectSubscription()
|
||||
dataSub.expectCancellation()
|
||||
expectResponseWithWipedDate(
|
||||
"""|HTTP/1.1 200 OK
|
||||
|Server: akka-http/test
|
||||
|Date: XXXX
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|""")
|
||||
}
|
||||
|
|
@ -450,7 +450,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
val data = TestPublisher.manualProbe[ChunkStreamPart]()
|
||||
inside(expectRequest()) {
|
||||
case HttpRequest(GET, _, _, _, _) ⇒
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Chunked(ContentTypes.`text/plain`, Source(data))))
|
||||
responses.sendNext(HttpResponse(entity = HttpEntity.Chunked(ContentTypes.`text/plain(UTF-8)`, Source(data))))
|
||||
val dataSub = data.expectSubscription()
|
||||
dataSub.expectCancellation()
|
||||
expectResponseWithWipedDate(
|
||||
|
|
@ -458,7 +458,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
|Server: akka-http/test
|
||||
|Date: XXXX
|
||||
|Transfer-Encoding: chunked
|
||||
|Content-Type: text/plain
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|
|
||||
|""")
|
||||
}
|
||||
|
|
@ -473,7 +473,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
val data = TestPublisher.manualProbe[ByteString]()
|
||||
inside(expectRequest()) {
|
||||
case HttpRequest(GET, _, _, _, _) ⇒
|
||||
responses.sendNext(HttpResponse(entity = CloseDelimited(ContentTypes.`text/plain`, Source(data))))
|
||||
responses.sendNext(HttpResponse(entity = CloseDelimited(ContentTypes.`text/plain(UTF-8)`, Source(data))))
|
||||
val dataSub = data.expectSubscription()
|
||||
dataSub.expectCancellation()
|
||||
netOut.expectBytes(1)
|
||||
|
|
@ -884,6 +884,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
"the config setting applied before another attribute (default entity)" in new LengthVerificationTest(maxContentLength = 10) {
|
||||
def nameDataSource(name: String): RequestEntity ⇒ RequestEntity = {
|
||||
case x: HttpEntity.Default ⇒ x.copy(data = x.data named name)
|
||||
case _ ⇒ ??? // prevent a compile-time warning
|
||||
}
|
||||
sendDefaultRequestWithLength(10)
|
||||
expectRequest().mapEntity(nameDataSource("foo")).expectEntity[HttpEntity.Default](10)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import HttpEncodings._
|
|||
import HttpMethods._
|
||||
|
||||
class HttpHeaderSpec extends FreeSpec with Matchers {
|
||||
val `application/vnd.spray` = MediaType.custom("application/vnd.spray", MediaType.Encoding.Binary)
|
||||
val `application/vnd.spray` = MediaType.applicationBinary("vnd.spray", compressible = true)
|
||||
val PROPFIND = HttpMethod.custom("PROPFIND")
|
||||
|
||||
"The HTTP header model must correctly parse and render the headers" - {
|
||||
|
|
@ -38,9 +38,9 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
"Accept: */*, text/*; foo=bar, custom/custom; bar=\"b>az\"" =!=
|
||||
Accept(`*/*`,
|
||||
MediaRange.custom("text", Map("foo" -> "bar")),
|
||||
MediaType.custom("custom", "custom", MediaType.Encoding.Binary, params = Map("bar" -> "b>az")))
|
||||
MediaType.customBinary("custom", "custom", compressible = true, params = Map("bar" -> "b>az")))
|
||||
"Accept: application/*+xml; version=2" =!=
|
||||
Accept(MediaType.custom("application", "*+xml", MediaType.Encoding.Binary, params = Map("version" -> "2")))
|
||||
Accept(MediaType.customBinary("application", "*+xml", compressible = true, params = Map("version" -> "2")))
|
||||
}
|
||||
|
||||
"Accept-Charset" in {
|
||||
|
|
@ -197,17 +197,18 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
"Content-Type: text/plain; charset=utf8" =!=
|
||||
`Content-Type`(ContentType(`text/plain`, `UTF-8`)).renderedTo("text/plain; charset=UTF-8")
|
||||
"Content-Type: text/xml2; version=3; charset=windows-1252" =!=
|
||||
`Content-Type`(ContentType(MediaType.custom("text", "xml2", encoding = MediaType.Encoding.Open,
|
||||
params = Map("version" -> "3")), HttpCharsets.getForKey("windows-1252")))
|
||||
`Content-Type`(MediaType.customWithOpenCharset("text", "xml2", params = Map("version" -> "3"))
|
||||
withCharset HttpCharsets.getForKey("windows-1252").get)
|
||||
"Content-Type: text/plain; charset=fancy-pants" =!=
|
||||
`Content-Type`(ContentType(`text/plain`, HttpCharset.custom("fancy-pants")))
|
||||
`Content-Type`(`text/plain` withCharset HttpCharset.custom("fancy-pants"))
|
||||
"Content-Type: multipart/mixed; boundary=ABC123" =!=
|
||||
`Content-Type`(ContentType(`multipart/mixed` withBoundary "ABC123"))
|
||||
`Content-Type`(`multipart/mixed` withBoundary "ABC123" withCharset `UTF-8`)
|
||||
.renderedTo("multipart/mixed; boundary=ABC123; charset=UTF-8")
|
||||
"Content-Type: multipart/mixed; boundary=\"ABC/123\"" =!=
|
||||
`Content-Type`(ContentType(`multipart/mixed` withBoundary "ABC/123"))
|
||||
`Content-Type`(`multipart/mixed` withBoundary "ABC/123" withCharset `UTF-8`)
|
||||
.renderedTo("""multipart/mixed; boundary="ABC/123"; charset=UTF-8""")
|
||||
"Content-Type: application/*" =!=
|
||||
`Content-Type`(ContentType(MediaType.custom("application", "*", MediaType.Encoding.Binary,
|
||||
allowArbitrarySubtypes = true)))
|
||||
`Content-Type`(MediaType.customBinary("application", "*", compressible = false, allowArbitrarySubtypes = true))
|
||||
}
|
||||
|
||||
"Content-Range" in {
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
|
||||
try {
|
||||
def runIdleRequest(uri: Uri): Future[HttpResponse] = {
|
||||
val itNeverEnds = Chunked.fromData(ContentTypes.`text/plain`, Source.maybe[ByteString])
|
||||
val itNeverEnds = Chunked.fromData(ContentTypes.`text/plain(UTF-8)`, Source.maybe[ByteString])
|
||||
Http().outgoingConnection(hostname, port)
|
||||
.runWith(Source.single(HttpRequest(PUT, uri, entity = itNeverEnds)), Sink.head)
|
||||
._2
|
||||
|
|
@ -197,7 +197,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
|
||||
try {
|
||||
def runRequest(uri: Uri): Future[HttpResponse] = {
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain`, Source.maybe[ByteString])
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain(UTF-8)`, Source.maybe[ByteString])
|
||||
Http().outgoingConnection(hostname, port, settings = clientSettings)
|
||||
.runWith(Source.single(HttpRequest(POST, uri, entity = itNeverSends)), Sink.head)
|
||||
._2
|
||||
|
|
@ -232,7 +232,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
val pool = Http().cachedHostConnectionPool[Int](hostname, port, clientPoolSettings)
|
||||
|
||||
def runRequest(uri: Uri): Future[(Try[HttpResponse], Int)] = {
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain`, Source.maybe[ByteString])
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain(UTF-8)`, Source.maybe[ByteString])
|
||||
Source.single(HttpRequest(POST, uri, entity = itNeverSends) -> 1)
|
||||
.via(pool)
|
||||
.runWith(Sink.head)
|
||||
|
|
@ -265,7 +265,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
|
||||
try {
|
||||
def runRequest(uri: Uri): Future[HttpResponse] = {
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain`, Source.maybe[ByteString])
|
||||
val itNeverSends = Chunked.fromData(ContentTypes.`text/plain(UTF-8)`, Source.maybe[ByteString])
|
||||
Http().singleRequest(HttpRequest(POST, uri, entity = itNeverSends), settings = clientPoolSettings)
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +368,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
val (serverIn, serverOut) = acceptConnection()
|
||||
|
||||
val chunks = List(Chunk("abc"), Chunk("defg"), Chunk("hijkl"), LastChunk)
|
||||
val chunkedContentType: ContentType = MediaTypes.`application/base64`
|
||||
val chunkedContentType: ContentType = MediaTypes.`application/base64` withCharset HttpCharsets.`UTF-8`
|
||||
val chunkedEntity = HttpEntity.Chunked(chunkedContentType, Source(chunks))
|
||||
|
||||
val clientOutSub = clientOut.expectSubscription()
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ object TestServer extends App {
|
|||
////////////// helpers //////////////
|
||||
|
||||
lazy val index = HttpResponse(
|
||||
entity = HttpEntity(MediaTypes.`text/html`,
|
||||
entity = HttpEntity(ContentTypes.`text/html(UTF-8)`,
|
||||
"""|<html>
|
||||
| <body>
|
||||
| <h1>Say hello to <i>akka-http-core</i>!</h1>
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class HttpModelIntegrationSpec extends WordSpec with Matchers with BeforeAndAfte
|
|||
val contentType = convertedHeaders.collectFirst {
|
||||
case ct: `Content-Type` ⇒ ct.contentType
|
||||
}
|
||||
contentType shouldEqual Some(ContentTypes.`text/plain`)
|
||||
contentType shouldEqual Some(ContentTypes.`text/plain(UTF-8)`)
|
||||
|
||||
val contentLength = convertedHeaders.collectFirst {
|
||||
case cl: `Content-Length` ⇒ cl.length
|
||||
|
|
@ -207,7 +207,7 @@ class HttpModelIntegrationSpec extends WordSpec with Matchers with BeforeAndAfte
|
|||
// to be able to directly create a ContentType and ContentLength
|
||||
// headers.
|
||||
ExampleLibrary.contentLength(3)
|
||||
ExampleLibrary.contentType(ContentTypes.`text/plain`)
|
||||
ExampleLibrary.contentType(ContentTypes.`text/plain(UTF-8)`)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue