Package org.microproxy.http
Class HttpBodies
java.lang.Object
org.microproxy.http.HttpBodies
Reads and rewrites the bodies of buffered messages (
FullHttpMessage) in filters,
taking care of Content-Encoding and charsets so filters don't have to.
if (o instanceof FullHttpResponse res && HttpBodies.isText(res) && HttpBodies.canDecode(res)) {
String html = HttpBodies.text(res);
HttpBodies.setText(res, html.replace("</body>", "<script src=/x.js></script></body>"));
}
gzip, x-gzip, deflate (zlib-wrapped or raw) and br (with a
bundled copy of the pure-Java Brotli codec jaybrotli) can be decoded, and so can zstd
when the optional zstd-decoder module is on the class path. Others, such as dictionary
codings (dcb, dcz), are reported by canDecode(org.microproxy.http.HttpMessage), and restrictAcceptEncoding(org.microproxy.http.HttpRequest) keeps servers from choosing them. Decoding is capped (64 MiB by
default) to defuse compression bombs. Rewriting a body re-applies the original coding (Brotli
at quality 5; zstd bodies are re-encoded as gzip, since there is no
pure-Java zstd encoder) and drops validators (ETag, Content-MD5) that no longer
match; Content-Length is fixed when the message is written.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe Brotli quality (0 to 11) thatencode(java.lang.String, byte[])and rewrittenbrbodies use, with jaybrotli's default strategies: on HTML and JSON of 10 KB to 1 MB it runs at about 10 to 35 MB/s, and its output is mostly 1 to 14% smaller than gzip's default level (at worst 2% larger).Content codings this class can decode:gzip,x-gzip,deflateandbr, pluszstdwhen thezstd-decodermodule is on the class path.static final intDefault cap on decoded body size. -
Method Summary
Modifier and TypeMethodDescriptionstatic booleancanDecode(HttpMessage message) Whether every content coding ofmessagecan be decoded.static Charsetcharset(HttpMessage message, Charset fallback) Thecharsetparameter ofContent-Type, orfallbackwhen absent, unknown or malformed.contentEncodings(HttpMessage message) The content codings applied tomessage, outermost last (identityomitted).static byte[]Removes one content coding fromdata, asdecoded(FullHttpMessage, int)does for each coding of a message.static byte[]decoded(FullHttpMessage message) The body with all content codings removed.static byte[]decoded(FullHttpMessage message, int maxDecodedBytes) Removes all content codings with a limit on each decompression stage.static byte[]decodedPrefix(FullHttpMessage message, int maxBytes) The firstmaxBytesof the body with all content codings removed, for previews and logs: unlikedecoded(FullHttpMessage, int), a longer decoded body is cut short rather than an error, and only that much is ever decoded.static byte[]Applies one content coding todata:gzip(orx-gzip),deflate(zlib-wrapped) orbr(atBROTLI_QUALITY), the codings this class can produce.static booleanisText(HttpMessage message) Whether the media type is textual:text/*, JSON, XML, JavaScript or form data.static StringmediaType(HttpMessage message) The media type ofContent-Typein lower case, without parameters, or "".static voidremoveContentEncoding(FullHttpMessage message) Decodes the body and removesContent-Encoding, so later filters see plain bytes.static voidrestrictAcceptEncoding(HttpRequest request) Removes content codings this class cannot decode (e.g.static voidsetDecoded(FullHttpMessage message, byte[] decodedBody) Replaces the body withdecodedBody, re-applying the message's content codings, and removes validators that described the old body.static voidsetText(FullHttpMessage message, String text) Replaces the body withtextin the message's charset (UTF-8 when none is declared).static Stringtext(FullHttpMessage message) The decoded body as text, in the message's charset (UTF-8 when none is declared).
-
Field Details
-
DEFAULT_MAX_DECODED_BYTES
public static final int DEFAULT_MAX_DECODED_BYTESDefault cap on decoded body size.- See Also:
-
DECODABLE
Content codings this class can decode:gzip,x-gzip,deflateandbr, pluszstdwhen thezstd-decodermodule is on the class path. -
BROTLI_QUALITY
public static final int BROTLI_QUALITYThe Brotli quality (0 to 11) thatencode(java.lang.String, byte[])and rewrittenbrbodies use, with jaybrotli's default strategies: on HTML and JSON of 10 KB to 1 MB it runs at about 10 to 35 MB/s, and its output is mostly 1 to 14% smaller than gzip's default level (at worst 2% larger). Qualities 4 and 6 come out within 1% of it; the higher qualities and the alternative strategies trade too much speed for what they save.- See Also:
-
-
Method Details
-
contentEncodings
The content codings applied tomessage, outermost last (identityomitted).- Parameters:
message- the message whose body and headers are inspected- Returns:
- the lower-case content codings in application order, excluding identity
-
canDecode
Whether every content coding ofmessagecan be decoded.- Parameters:
message- the message whose body and headers are inspected- Returns:
- whether all declared content codings are supported
-
decoded
The body with all content codings removed.- Parameters:
message- the message whose body and headers are inspected- Returns:
- the body bytes after all content codings are removed
- Throws:
IOException- if a coding is unsupported, corrupt, or exceeds the default decoding limit
-
decoded
Removes all content codings with a limit on each decompression stage.- Parameters:
message- the message whose body and headers are inspectedmaxDecodedBytes- the maximum output size in bytes for each decompression stage- Returns:
- the body bytes after all content codings are removed
- Throws:
IOException- if a coding is unsupported, corrupt, or exceeds the decoding limit
-
decodedPrefix
The firstmaxBytesof the body with all content codings removed, for previews and logs: unlikedecoded(FullHttpMessage, int), a longer decoded body is cut short rather than an error, and only that much is ever decoded.- Parameters:
message- the message whose body and headers are inspectedmaxBytes- the maximum prefix length; nonpositive values produce an empty result- Returns:
- up to maxBytes decoded body bytes
- Throws:
IOException- if a coding is unsupported or the decoded prefix cannot be read
-
setDecoded
Replaces the body withdecodedBody, re-applying the message's content codings, and removes validators that described the old body.- Parameters:
message- the message to updatedecodedBody- the replacement bytes before applying content codings- Throws:
IOException- if a content coding is unsupported or encoding fails
-
removeContentEncoding
Decodes the body and removesContent-Encoding, so later filters see plain bytes.- Parameters:
message- the message to decode and update- Throws:
IOException- if a coding is unsupported, corrupt, or exceeds the default decoding limit
-
restrictAcceptEncoding
Removes content codings this class cannot decode (e.g.dcb) from the request'sAccept-Encoding, keeping quality values, so the server picks one that filters can read. Leavesidentitywhen nothing else remains.- Parameters:
request- the request whose accepted codings are restricted
-
text
The decoded body as text, in the message's charset (UTF-8 when none is declared).- Parameters:
message- the message whose body and headers are inspected- Returns:
- the decoded body interpreted in the declared charset, or UTF-8 by default
- Throws:
IOException- if a coding is unsupported, corrupt, or exceeds the default decoding limit
-
setText
Replaces the body withtextin the message's charset (UTF-8 when none is declared).- Parameters:
message- the message to updatetext- the replacement text before charset encoding and content coding- Throws:
IOException- if a content coding is unsupported or encoding fails
-
charset
Thecharsetparameter ofContent-Type, orfallbackwhen absent, unknown or malformed.- Parameters:
message- the message whose Content-Type is inspectedfallback- the charset to use when the parameter cannot be resolved- Returns:
- the declared charset, or fallback if unavailable
-
mediaType
The media type ofContent-Typein lower case, without parameters, or "".- Parameters:
message- the message whose Content-Type is inspected- Returns:
- the lower-case media type without parameters, or an empty string if absent
-
isText
Whether the media type is textual:text/*, JSON, XML, JavaScript or form data.- Parameters:
message- the message whose media type is inspected- Returns:
- whether the media type is recognized as textual
-
decode
Removes one content coding fromdata, asdecoded(FullHttpMessage, int)does for each coding of a message. Also used for gRPC messages, which are compressed one by one with the coding theirgrpc-encodingnames.- Parameters:
coding- the coding, in lower case:gzip,x-gzip,deflate(zlib-wrapped or raw),br, orzstdwhen the module is presentdata- the encoded bytesmax- the maximum decoded size in bytes- Returns:
- the decoded bytes
- Throws:
IOException- if the coding is unsupported, the data corrupt, or the result larger thanmax
-
encode
Applies one content coding todata:gzip(orx-gzip),deflate(zlib-wrapped) orbr(atBROTLI_QUALITY), the codings this class can produce.- Parameters:
coding- the coding, in lower casedata- the bytes to encode- Returns:
- the encoded bytes
- Throws:
IOException- if the coding is not one of those
-