Skip to content

Commit a334940

Browse files
committed
[UNDERTOW-1735] add reason-phrase handler and make response-code obey doc contract of one-by-one execution
1 parent c6ad90c commit a334940

File tree

7 files changed

+188
-2
lines changed

7 files changed

+188
-2
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* JBoss, Home of Professional Open Source.
3+
* Copyright 2022 Red Hat, Inc., and individual contributors
4+
* as indicated by the @author tags.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package io.undertow.server.handlers;
20+
21+
import io.undertow.UndertowLogger;
22+
import io.undertow.server.HttpHandler;
23+
import io.undertow.server.HttpServerExchange;
24+
25+
/**
26+
* A handler which simply sets a response code.
27+
*
28+
* @author <a href="mailto:[email protected]">Bartosz Baranowski</a>
29+
*/
30+
public final class ReasonPhraseHandler implements HttpHandler {
31+
32+
private static final boolean debugEnabled;
33+
34+
static {
35+
debugEnabled = UndertowLogger.PREDICATE_LOGGER.isDebugEnabled();
36+
}
37+
38+
private final String reasonPhrase;
39+
40+
private final HttpHandler next;
41+
/**
42+
* Construct a new instance.
43+
*
44+
* @param reasonPhrase the reason phrase to be set in status line
45+
*/
46+
public ReasonPhraseHandler(final HttpHandler next, final String reasonPhrase) {
47+
this.next = next;
48+
this.reasonPhrase = reasonPhrase;
49+
}
50+
51+
@Override
52+
public void handleRequest(final HttpServerExchange exchange) throws Exception {
53+
exchange.setReasonPhrase(reasonPhrase);
54+
if(debugEnabled) {
55+
UndertowLogger.PREDICATE_LOGGER.debugf("Reason phrase set to [%s] for %s.", this.reasonPhrase, exchange);
56+
}
57+
if(next != null) {
58+
next.handleRequest(exchange);
59+
}
60+
}
61+
62+
@Override
63+
public String toString() {
64+
return "reason-phrase( " + this.reasonPhrase + " )";
65+
}
66+
}

core/src/main/java/io/undertow/server/handlers/ResponseCodeHandler.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,34 @@ public final class ResponseCodeHandler implements HttpHandler {
6464

6565
private final int responseCode;
6666

67+
private HttpHandler next;
6768
/**
6869
* Construct a new instance.
6970
*
7071
* @param responseCode the response code to set
72+
* @param next next handler
7173
*/
72-
public ResponseCodeHandler(final int responseCode) {
74+
public ResponseCodeHandler(final HttpHandler next, final int responseCode) {
7375
this.responseCode = responseCode;
76+
this.next = next;
77+
}
78+
79+
/**
80+
* Construct a new instance.
81+
*
82+
* @param responseCode the response code to set
83+
* @param next next handler
84+
*/
85+
public ResponseCodeHandler(final int responseCode) {
86+
this(null,responseCode);
87+
}
88+
89+
public HttpHandler getNext() {
90+
return next;
91+
}
92+
93+
public void setNext(HttpHandler next) {
94+
this.next = next;
7495
}
7596

7697
@Override
@@ -79,6 +100,9 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception {
79100
if(debugEnabled) {
80101
UndertowLogger.PREDICATE_LOGGER.debugf("Response code set to [%s] for %s.", responseCode, exchange);
81102
}
103+
if(next != null) {
104+
next.handleRequest(exchange);
105+
}
82106
}
83107

84108
@Override
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* JBoss, Home of Professional Open Source.
3+
* Copyright 2022 Red Hat, Inc., and individual contributors
4+
* as indicated by the @author tags.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package io.undertow.server.handlers.builder;
20+
21+
import io.undertow.server.HandlerWrapper;
22+
import io.undertow.server.HttpHandler;
23+
import io.undertow.server.handlers.ReasonPhraseHandler;
24+
25+
import java.util.HashMap;
26+
import java.util.HashSet;
27+
import java.util.Map;
28+
import java.util.Set;
29+
30+
/**
31+
* @author Bartosz Baranowski
32+
*/
33+
public class ReasonPhraseHandlerBuilder implements HandlerBuilder {
34+
@Override
35+
public String name() {
36+
return "reason-phrase";
37+
}
38+
39+
@Override
40+
public Map<String, Class<?>> parameters() {
41+
Map<String, Class<?>> parameters = new HashMap<>();
42+
parameters.put("value", String.class);
43+
return parameters;
44+
}
45+
46+
@Override
47+
public Set<String> requiredParameters() {
48+
final Set<String> req = new HashSet<>();
49+
req.add("value");
50+
return req;
51+
}
52+
53+
@Override
54+
public String defaultParameter() {
55+
return "value";
56+
}
57+
58+
@Override
59+
public HandlerWrapper build(final Map<String, Object> config) {
60+
final String value = (String) config.get("value");
61+
return new HandlerWrapper() {
62+
@Override
63+
public HttpHandler wrap(HttpHandler handler) {
64+
return new ReasonPhraseHandler(handler, value);
65+
}
66+
};
67+
}
68+
}

core/src/main/java/io/undertow/server/handlers/builder/ResponseCodeHandlerBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public HandlerWrapper build(final Map<String, Object> config) {
6161
return new HandlerWrapper() {
6262
@Override
6363
public HttpHandler wrap(HttpHandler handler) {
64-
return new ResponseCodeHandler(value);
64+
return new ResponseCodeHandler(handler, value);
6565
}
6666
};
6767
}

core/src/main/resources/META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ io.undertow.server.handlers.HttpContinueAcceptingHandler$Builder
4343
io.undertow.server.handlers.form.EagerFormParsingHandler$Builder
4444
io.undertow.server.handlers.SameSiteCookieHandler$Builder
4545
io.undertow.server.handlers.SetErrorHandler$Builder
46+
io.undertow.server.handlers.builder.ReasonPhraseHandlerBuilder

core/src/test/java/io/undertow/predicate/PredicateParsingTestCase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,5 @@ private void expect(String string, boolean result1, boolean result2) {
141141
throw new RuntimeException("String " + string, ex);
142142
}
143143
}
144+
144145
}

core/src/test/java/io/undertow/server/handlers/PredicatedHandlersTestCase.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,30 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
145145
client.getConnectionManager().shutdown();
146146
}
147147
}
148+
149+
@Test
150+
public void testReasonPhrase() throws IOException {
151+
DefaultServer.setRootHandler(
152+
Handlers.predicates(
153+
154+
PredicatedHandlersParser.parse(
155+
"path('/test') -> reason-phrase('test-my-patience');response-code(480)", getClass().getClassLoader()), new HttpHandler() {
156+
@Override
157+
public void handleRequest(HttpServerExchange exchange) throws Exception {
158+
exchange.getResponseSender().send(exchange.getRelativePath());
159+
}
160+
}));
161+
TestHttpClient client = new TestHttpClient();
162+
try {
163+
HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/test");
164+
165+
HttpResponse result = client.execute(get);
166+
Assert.assertEquals("test-my-patience", result.getStatusLine().getReasonPhrase());
167+
Assert.assertEquals(480, result.getStatusLine().getStatusCode());
168+
169+
} finally {
170+
client.getConnectionManager().shutdown();
171+
}
172+
173+
}
148174
}

0 commit comments

Comments
 (0)