diff --git a/core/src/main/java/io/undertow/server/handlers/ReasonPhraseHandler.java b/core/src/main/java/io/undertow/server/handlers/ReasonPhraseHandler.java index 7ea9655a9f..1b19d3db6b 100644 --- a/core/src/main/java/io/undertow/server/handlers/ReasonPhraseHandler.java +++ b/core/src/main/java/io/undertow/server/handlers/ReasonPhraseHandler.java @@ -18,9 +18,16 @@ package io.undertow.server.handlers; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import io.undertow.UndertowLogger; +import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.server.handlers.builder.HandlerBuilder; /** * A handler which simply sets a response code. @@ -63,4 +70,41 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception { public String toString() { return "reason-phrase( " + this.reasonPhrase + " )"; } + + public static class Builder implements HandlerBuilder { + @Override + public String name() { + return "reason-phrase"; + } + + @Override + public Map> parameters() { + Map> parameters = new HashMap<>(); + parameters.put("value", String.class); + return parameters; + } + + @Override + public Set requiredParameters() { + final Set req = new HashSet<>(); + req.add("value"); + return req; + } + + @Override + public String defaultParameter() { + return "value"; + } + + @Override + public HandlerWrapper build(final Map config) { + final String value = (String) config.get("value"); + return new HandlerWrapper() { + @Override + public HttpHandler wrap(HttpHandler handler) { + return new ReasonPhraseHandler(handler, value); + } + }; + } + } } diff --git a/core/src/main/java/io/undertow/server/handlers/ResponseCodeHandler.java b/core/src/main/java/io/undertow/server/handlers/ResponseCodeHandler.java index 19f43354ad..19f8b1a6c7 100644 --- a/core/src/main/java/io/undertow/server/handlers/ResponseCodeHandler.java +++ b/core/src/main/java/io/undertow/server/handlers/ResponseCodeHandler.java @@ -18,9 +18,16 @@ package io.undertow.server.handlers; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import io.undertow.UndertowLogger; +import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.server.handlers.builder.HandlerBuilder; /** * A handler which simply sets a response code. @@ -111,4 +118,47 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception { public String toString() { return "response-code( " + this.responseCode + " )"; } + + public static class Builder implements HandlerBuilder { + + @Override + public String name() { + return "response-code"; + } + + @Override + public Map> parameters() { + Map> parameters = new HashMap<>(); + parameters.put("value", Integer.class); + return parameters; + } + + @Override + public Set requiredParameters() { + final Set req = new HashSet<>(); + req.add("value"); + return req; + } + + @Override + public String defaultParameter() { + return "value"; + } + + @Override + public HandlerWrapper build(final Map config) { + final Integer value = (Integer) config.get("value"); + return new HandlerWrapper() { + @Override + public HttpHandler wrap(HttpHandler handler) { + return new ResponseCodeHandler(handler, value); + } + }; + } + + @Override + public int priority() { + return 0; + } + } } diff --git a/core/src/main/java/io/undertow/server/handlers/ResponseHandler.java b/core/src/main/java/io/undertow/server/handlers/ResponseHandler.java index a5cfe359b9..85c9a7b595 100644 --- a/core/src/main/java/io/undertow/server/handlers/ResponseHandler.java +++ b/core/src/main/java/io/undertow/server/handlers/ResponseHandler.java @@ -17,10 +17,17 @@ */ package io.undertow.server.handlers; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import io.undertow.UndertowLogger; import io.undertow.UndertowMessages; +import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.server.handlers.builder.HandlerBuilder; import io.undertow.util.HeaderMap; import io.undertow.util.Headers; @@ -106,4 +113,56 @@ public String toString() { + ((this.body != null) ? ", type='" + this.type + "', body='" + this.body + "'" : "") + " )"; } + public static class Builder implements HandlerBuilder { + + @Override + public String name() { + return "response"; + } + + @Override + public Map> parameters() { + Map> parameters = new HashMap<>(); + parameters.put("code", Integer.class); + parameters.put("reason", String.class); + parameters.put("type", String.class); + parameters.put("body", String.class); + return parameters; + } + + @Override + public Set requiredParameters() { + final Set req = new HashSet<>(); + req.add("code"); + return req; + } + + @Override + public String defaultParameter() { + // default parameter - name(paramValue) not supported + return null; + } + + @Override + public HandlerWrapper build(final Map config) { + final Integer code = (Integer) config.get("code"); + final String reason = (String) config.get("reason"); + final String type = (String) config.get("type"); + final String body = (String) config.get("body"); + return new HandlerWrapper() { + @Override + public HttpHandler wrap(HttpHandler handler) { + if (body == null) { + return new ResponseHandler(code, reason); + } else { + if (type == null) { + return new ResponseHandler(code, reason, body); + } else { + return new ResponseHandler(code, reason, body, type); + } + } + } + }; + } + } } diff --git a/core/src/main/java/io/undertow/server/handlers/RewriteHandler.java b/core/src/main/java/io/undertow/server/handlers/RewriteHandler.java new file mode 100644 index 0000000000..99fce0ef26 --- /dev/null +++ b/core/src/main/java/io/undertow/server/handlers/RewriteHandler.java @@ -0,0 +1,126 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.undertow.server.handlers; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import io.undertow.UndertowLogger; +import io.undertow.attribute.ConstantExchangeAttribute; +import io.undertow.attribute.ExchangeAttribute; +import io.undertow.attribute.ExchangeAttributes; +import io.undertow.attribute.ReadOnlyAttributeException; +import io.undertow.server.HandlerWrapper; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.server.handlers.builder.HandlerBuilder; + +/** + * @author Bartosz Baranowski + * @author Stuart Douglas + */ +public class RewriteHandler extends SetAttributeHandler { + + public RewriteHandler(HttpHandler next, ExchangeAttribute value) { + super(next, ExchangeAttributes.relativePath(), value); + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + UndertowLogger.PREDICATE_LOGGER.debugf("Request rewritten to [%s] for %s.", getValue().readAttribute(exchange), + exchange); + super.handleRequest(exchange); + } + + @Override + public String toString() { + return "rewrite( '" + getValue().toString() + "' )"; + } + + public static class Builder implements HandlerBuilder { + + @Override + public String name() { + return "rewrite"; + } + + @Override + public Map> parameters() { + return Collections.> singletonMap("value", ExchangeAttribute.class); + } + + @Override + public Set requiredParameters() { + return Collections.singleton("value"); + } + + @Override + public String defaultParameter() { + return "value"; + } + + @Override + public HandlerWrapper build(final Map config) { + final ExchangeAttribute configValue = (ExchangeAttribute) config.get("value"); + ExchangeAttribute tmpValue = null; + if (configValue instanceof ConstantExchangeAttribute) { + tmpValue = new ConstantExchangeAttribute(normalize(configValue.readAttribute(null))); + } else { + tmpValue = new ExchangeAttribute() { + + @Override + public String readAttribute(HttpServerExchange exchange) { + return normalize(configValue.readAttribute(exchange)); + } + + @Override + public void writeAttribute(HttpServerExchange exchange, String newValue) throws ReadOnlyAttributeException { + throw new ReadOnlyAttributeException("constant", newValue); + } + + public String toString() { + return "NDA"; + }; + }; + } + final ExchangeAttribute value = tmpValue; + + return new HandlerWrapper() { + @Override + public HttpHandler wrap(HttpHandler handler) { + return new RewriteHandler(handler, value); + } + + }; + } + + @Override + public int priority() { + return 0; + } + + private String normalize(final String readAttribute) { + if (readAttribute.startsWith("/")) { + return readAttribute; + } else { + return "/" + readAttribute; + } + } + } +} diff --git a/core/src/main/java/io/undertow/server/handlers/builder/ReasonPhraseHandlerBuilder.java b/core/src/main/java/io/undertow/server/handlers/builder/ReasonPhraseHandlerBuilder.java index b0ea220131..07376ecc35 100644 --- a/core/src/main/java/io/undertow/server/handlers/builder/ReasonPhraseHandlerBuilder.java +++ b/core/src/main/java/io/undertow/server/handlers/builder/ReasonPhraseHandlerBuilder.java @@ -29,6 +29,8 @@ /** * @author Bartosz Baranowski + * @see {@link ReasonPhraseHandler#Builder} + * @Deprecated(since = "2.5.0", forRemoval = true) */ public class ReasonPhraseHandlerBuilder implements HandlerBuilder { @Override diff --git a/core/src/main/java/io/undertow/server/handlers/builder/ResponseCodeHandlerBuilder.java b/core/src/main/java/io/undertow/server/handlers/builder/ResponseCodeHandlerBuilder.java index 0387989fc4..c85eddd545 100644 --- a/core/src/main/java/io/undertow/server/handlers/builder/ResponseCodeHandlerBuilder.java +++ b/core/src/main/java/io/undertow/server/handlers/builder/ResponseCodeHandlerBuilder.java @@ -29,6 +29,8 @@ /** * @author Stuart Douglas + * @see {@link ResponseCodeHandler#Builder} + * @Deprecated(since = "2.5.0", forRemoval = true) */ public class ResponseCodeHandlerBuilder implements HandlerBuilder { @Override diff --git a/core/src/main/java/io/undertow/server/handlers/builder/ResponseHandlerBuilder.java b/core/src/main/java/io/undertow/server/handlers/builder/ResponseHandlerBuilder.java index 111f31d9f2..026af8d3f8 100644 --- a/core/src/main/java/io/undertow/server/handlers/builder/ResponseHandlerBuilder.java +++ b/core/src/main/java/io/undertow/server/handlers/builder/ResponseHandlerBuilder.java @@ -25,10 +25,13 @@ import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; +import io.undertow.server.handlers.ResponseCodeHandler; import io.undertow.server.handlers.ResponseHandler; /** * @author Bartosz Baranowski + * @see {@link ResponseCodeHandler#Builder} + * @Deprecated(since = "2.5.0", forRemoval = true) */ public class ResponseHandlerBuilder implements HandlerBuilder { @Override diff --git a/core/src/main/java/io/undertow/server/handlers/builder/RewriteHandlerBuilder.java b/core/src/main/java/io/undertow/server/handlers/builder/RewriteHandlerBuilder.java index 8612c4b716..0cefb2139c 100644 --- a/core/src/main/java/io/undertow/server/handlers/builder/RewriteHandlerBuilder.java +++ b/core/src/main/java/io/undertow/server/handlers/builder/RewriteHandlerBuilder.java @@ -18,6 +18,11 @@ package io.undertow.server.handlers.builder; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import io.undertow.UndertowLogger; import io.undertow.attribute.ConstantExchangeAttribute; import io.undertow.attribute.ExchangeAttribute; import io.undertow.attribute.ExchangeAttributes; @@ -25,15 +30,13 @@ import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.server.handlers.RewriteHandler; import io.undertow.server.handlers.SetAttributeHandler; -import io.undertow.UndertowLogger; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; /** * @author Stuart Douglas + * @see {@link RewriteHandler#Builder} + * @Deprecated(since = "2.5.0", forRemoval = true) */ public class RewriteHandlerBuilder implements HandlerBuilder { @Override diff --git a/core/src/main/resources/META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder b/core/src/main/resources/META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder index 70f45c59c5..02aee10ec6 100644 --- a/core/src/main/resources/META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder +++ b/core/src/main/resources/META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder @@ -1,7 +1,7 @@ -io.undertow.server.handlers.builder.RewriteHandlerBuilder +io.undertow.server.handlers.RewriteHandler$Builder io.undertow.server.handlers.SetAttributeHandler$Builder io.undertow.server.handlers.SetAttributeHandler$ClearBuilder -io.undertow.server.handlers.builder.ResponseCodeHandlerBuilder +io.undertow.server.handlers.ResponseCodeHandler$Builder io.undertow.server.handlers.DisableCacheHandler$Builder io.undertow.server.handlers.ProxyPeerAddressHandler$Builder io.undertow.server.handlers.proxy.ProxyHandlerBuilder @@ -43,5 +43,5 @@ io.undertow.server.handlers.HttpContinueAcceptingHandler$Builder io.undertow.server.handlers.form.EagerFormParsingHandler$Builder io.undertow.server.handlers.SameSiteCookieHandler$Builder io.undertow.server.handlers.SetErrorHandler$Builder -io.undertow.server.handlers.builder.ReasonPhraseHandlerBuilder -io.undertow.server.handlers.builder.ResponseHandlerBuilder +io.undertow.server.handlers.ReasonPhraseHandler$Builder +io.undertow.server.handlers.ResponseHandler$Builder