Skip to content

Commit f887290

Browse files
committed
Re-implement compression options check in Java
The Clojure implementation needed a hacky workaround[1] which felt too fragile after all. [1] Due to https://clojure.atlassian.net/browse/CLJ-2842
1 parent eace7fa commit f887290

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

src-java/aleph/http/AlephCompressionOptions.java

+32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package aleph.http;
22

33
import io.netty.handler.codec.compression.BrotliOptions;
4+
import io.netty.handler.codec.compression.CompressionOptions;
45
import io.netty.handler.codec.compression.DeflateOptions;
56
import io.netty.handler.codec.compression.GzipOptions;
67
import io.netty.handler.codec.compression.SnappyOptions;
@@ -39,4 +40,35 @@ public static GzipOptions gzip() {
3940
public static DeflateOptions deflate() {
4041
return StandardCompressionOptions.deflate();
4142
}
43+
44+
private static boolean containsInstanceOf(CompressionOptions[] options, Class optionClass) {
45+
for (CompressionOptions o : options) {
46+
// NOTE: Can't use optionClass.instanceOf(o) because GzipOptions inherits from
47+
// DeflateOptions which yields false positives.
48+
if (optionClass == o.getClass()) {
49+
return true;
50+
}
51+
}
52+
return false;
53+
}
54+
55+
public static boolean hasBrotli(CompressionOptions[] options) {
56+
return containsInstanceOf(options, BrotliOptions.class);
57+
}
58+
59+
public static boolean hasZstd(CompressionOptions[] options) {
60+
return containsInstanceOf(options, ZstdOptions.class);
61+
}
62+
63+
public static boolean hasSnappy(CompressionOptions[] options) {
64+
return containsInstanceOf(options, SnappyOptions.class);
65+
}
66+
67+
public static boolean hasGzip(CompressionOptions[] options) {
68+
return containsInstanceOf(options, GzipOptions.class);
69+
}
70+
71+
public static boolean hasDeflate(CompressionOptions[] options) {
72+
return containsInstanceOf(options, DeflateOptions.class);
73+
}
4274
}

src/aleph/http/compression.clj

+5-26
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,6 @@
3737
(def ^:private ^AsciiString head-method (AsciiString. "HEAD"))
3838
(def ^:private ^AsciiString connect-method (AsciiString. "CONNECT"))
3939

40-
(defn- contains-class?
41-
"Returns true if the class is in the array"
42-
[^"[Lio.netty.handler.codec.compression.CompressionOptions;" a ^Class klazz]
43-
(let [len (alength a)]
44-
(loop [i 0]
45-
(if (>= i len)
46-
false
47-
(if (.equals klazz (class (aget ^"[Lio.netty.handler.codec.compression.CompressionOptions;" a i)))
48-
true
49-
(recur (unchecked-inc-int i)))))))
50-
5140
(def ^"[Lio.netty.handler.codec.compression.CompressionOptions;"
5241
available-compressor-options
5342
"A Java array of all available compressor options"
@@ -77,16 +66,6 @@
7766

7867
(defrecord Qvals [^double star ^double br ^double snappy ^double zstd ^double gzip ^double deflate])
7968

80-
;; We can't reference these options classes directly in `choose-codec` since the compiler would try
81-
;; to initialize them even when the necessary dependencies aren't available, resulting in an
82-
;; error. Indirectly referencing them like this works, though. See
83-
;; https://github.com/clj-commons/aleph/issues/703
84-
(def brotli-options-class
85-
BrotliOptions)
86-
87-
(def zstd-options-class
88-
ZstdOptions)
89-
9069
(defn choose-codec
9170
"Based on Netty's algorithm, which only compares with the next-best option.
9271
E.g., Brotli's q-value is only compared with zstd, not gzip or deflate.
@@ -103,26 +82,26 @@
10382
;; some encodings were listed
10483
(cond (and (p/not== br -1.0)
10584
(p/>= br zstd)
106-
(contains-class? compressor-options brotli-options-class))
85+
(AlephCompressionOptions/hasBrotli compressor-options))
10786
"br"
10887

10988
(and (p/not== zstd -1.0)
11089
(p/>= zstd snappy)
111-
(contains-class? compressor-options zstd-options-class))
90+
(AlephCompressionOptions/hasZstd compressor-options))
11291
"zstd"
11392

11493
(and (p/not== snappy -1.0)
11594
(p/>= snappy gzip)
116-
(contains-class? compressor-options SnappyOptions))
95+
(AlephCompressionOptions/hasSnappy compressor-options))
11796
"snappy"
11897

11998
(and (p/not== gzip -1.0)
12099
(p/>= gzip deflate)
121-
(contains-class? compressor-options GzipOptions))
100+
(AlephCompressionOptions/hasGzip compressor-options))
122101
"gzip"
123102

124103
(and (p/not== deflate -1.0)
125-
(contains-class? compressor-options DeflateOptions))
104+
(AlephCompressionOptions/hasDeflate compressor-options))
126105
"deflate")
127106

128107
;; no named encodings were listed, so we'll apply *'s qval to unset ones

0 commit comments

Comments
 (0)