1
18
19 package io.undertow.server.handlers.encoding;
20
21 import io.undertow.predicate.Predicate;
22 import io.undertow.predicate.Predicates;
23 import io.undertow.server.HttpServerExchange;
24 import io.undertow.util.CopyOnWriteMap;
25 import io.undertow.util.Headers;
26 import io.undertow.util.QValueParser;
27
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Map;
32
33
38 public class ContentEncodingRepository {
39
40 public static final String IDENTITY = "identity";
41 public static final EncodingMapping IDENTITY_ENCODING = new EncodingMapping(IDENTITY, ContentEncodingProvider.IDENTITY, 0, Predicates.truePredicate());
42
43 private final Map<String, EncodingMapping> encodingMap = new CopyOnWriteMap<>();
44
45
46 public AllowedContentEncodings getContentEncodings(final HttpServerExchange exchange) {
47 final List<String> res = exchange.getRequestHeaders().get(Headers.ACCEPT_ENCODING);
48 if (res == null || res.isEmpty()) {
49 return null;
50 }
51 final List<EncodingMapping> resultingMappings = new ArrayList<>();
52 final List<List<QValueParser.QValueResult>> found = QValueParser.parse(res);
53 for (List<QValueParser.QValueResult> result : found) {
54 List<EncodingMapping> available = new ArrayList<>();
55 boolean includesIdentity = false;
56 boolean isQValue0 = false;
57
58 for (final QValueParser.QValueResult value : result) {
59 EncodingMapping encoding;
60 if (value.getValue().equals("*")) {
61 includesIdentity = true;
62 encoding = IDENTITY_ENCODING;
63 } else {
64 encoding = encodingMap.get(value.getValue());
65 if(encoding == null && IDENTITY.equals(value.getValue())) {
66 encoding = IDENTITY_ENCODING;
67 }
68 }
69 if (value.isQValueZero()) {
70 isQValue0 = true;
71 }
72 if (encoding != null) {
73 available.add(encoding);
74 }
75 }
76 if (isQValue0) {
77 if (resultingMappings.isEmpty()) {
78 if (includesIdentity) {
79 return new AllowedContentEncodings(exchange, Collections.<EncodingMapping>emptyList());
80 } else {
81 return null;
82 }
83 }
84 } else if (!available.isEmpty()) {
85 Collections.sort(available, Collections.reverseOrder());
86 resultingMappings.addAll(available);
87 }
88 }
89 if (!resultingMappings.isEmpty()) {
90 return new AllowedContentEncodings(exchange, resultingMappings);
91 }
92 return null;
93 }
94
95 public synchronized ContentEncodingRepository addEncodingHandler(final String encoding, final ContentEncodingProvider encoder, int priority) {
96 addEncodingHandler(encoding, encoder, priority, Predicates.truePredicate());
97 return this;
98 }
99
100 public synchronized ContentEncodingRepository addEncodingHandler(final String encoding, final ContentEncodingProvider encoder, int priority, final Predicate enabledPredicate) {
101 this.encodingMap.put(encoding, new EncodingMapping(encoding, encoder, priority, enabledPredicate));
102 return this;
103 }
104
105 public synchronized ContentEncodingRepository removeEncodingHandler(final String encoding) {
106 encodingMap.remove(encoding);
107 return this;
108 }
109
110 }
111