diff --git a/gradle.properties b/gradle.properties
index 2b799a0..4422758 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
group = org.xbib
name = netty-http
-version = 4.1.85.0
+version = 4.1.90.0
org.gradle.warning.mode = ALL
diff --git a/gradle/test/junit5.gradle b/gradle/test/junit5.gradle
index 52a3d63..1de8bec 100644
--- a/gradle/test/junit5.gradle
+++ b/gradle/test/junit5.gradle
@@ -7,7 +7,7 @@ dependencies {
test {
useJUnitPlatform()
- failFast = true
+ failFast = false
maxHeapSize '1g'
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
testLogging {
diff --git a/netty-http-client-api/src/main/java/org/xbib/netty/http/client/api/Request.java b/netty-http-client-api/src/main/java/org/xbib/netty/http/client/api/Request.java
index 9aef6c2..c5437fc 100644
--- a/netty-http-client-api/src/main/java/org/xbib/netty/http/client/api/Request.java
+++ b/netty-http-client-api/src/main/java/org/xbib/netty/http/client/api/Request.java
@@ -42,7 +42,7 @@ import java.util.concurrent.CompletableFuture;
/**
* HTTP client request.
*/
-public final class Request implements AutoCloseable {
+public final class Request {
private final URL url;
@@ -202,7 +202,6 @@ public final class Request implements AutoCloseable {
}
}
- @Override
public void close() throws IOException {
release();
}
diff --git a/netty-http-client-rest/src/main/java/org/xbib/netty/http/client/rest/RestClient.java b/netty-http-client-rest/src/main/java/org/xbib/netty/http/client/rest/RestClient.java
index f1f0612..4b8e2ca 100644
--- a/netty-http-client-rest/src/main/java/org/xbib/netty/http/client/rest/RestClient.java
+++ b/netty-http-client-rest/src/main/java/org/xbib/netty/http/client/rest/RestClient.java
@@ -63,21 +63,19 @@ public class RestClient {
HttpMethod httpMethod) throws IOException {
URL url = URL.create(urlString);
RestClient restClient = new RestClient();
- try (Client client = Client.builder()
+ Client client = Client.builder()
.setThreadCount(2) // for redirect
- .build()) {
- Request.Builder requestBuilder = Request.builder(httpMethod).url(url);
- if (body != null) {
- ByteBuf byteBuf = client.getByteBufAllocator().buffer();
- byteBuf.writeCharSequence(body, charset);
- requestBuilder.content(byteBuf);
- }
- client.newTransport(HttpAddress.http1(url))
- .execute(requestBuilder.setResponseListener(restClient::setResponse).build())
- .close();
- } catch (Exception e) {
- throw new IOException(e);
+ .build();
+ Request.Builder requestBuilder = Request.builder(httpMethod).url(url);
+ if (body != null) {
+ ByteBuf byteBuf = client.getByteBufAllocator().buffer();
+ byteBuf.writeCharSequence(body, charset);
+ requestBuilder.content(byteBuf);
}
+ client.newTransport(HttpAddress.http1(url))
+ .execute(requestBuilder.setResponseListener(restClient::setResponse).build())
+ .close();
+ client.close();
return restClient;
}
}
diff --git a/netty-http-client/src/main/java/org/xbib/netty/http/client/Client.java b/netty-http-client/src/main/java/org/xbib/netty/http/client/Client.java
index 5674bf3..af2ee58 100644
--- a/netty-http-client/src/main/java/org/xbib/netty/http/client/Client.java
+++ b/netty-http-client/src/main/java/org/xbib/netty/http/client/Client.java
@@ -61,7 +61,7 @@ import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
-public final class Client implements AutoCloseable {
+public final class Client {
private static final Logger logger = Logger.getLogger(Client.class.getName());
@@ -366,7 +366,6 @@ public final class Client implements AutoCloseable {
closeAndRemove(transport);
}
- @Override
public void close() throws IOException {
shutdownGracefully();
}
diff --git a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/RequestBuilderTest.java b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/RequestBuilderTest.java
index 384b5e7..7413e5c 100644
--- a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/RequestBuilderTest.java
+++ b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/RequestBuilderTest.java
@@ -128,17 +128,21 @@ class RequestBuilderTest {
.url("https://google.com? a = b")
.build();
assertEquals("google.com", request.url().getHost());
- assertEquals("https://google.com?%20a%20=%20b", request.absolute());
- assertEquals("?%20a%20=%20b", request.relative());
+ assertEquals("https://google.com? a = b", request.absolute());
+ assertEquals("? a = b", request.relative());
+ assertEquals(" a = b", request.url().getQuery());
+ assertEquals(" a = b", request.url().getDecodedQuery());
assertEquals("https://google.com? a = b", request.url().toString());
- assertEquals("https://google.com?%20a%20=%20b", request.url().toExternalForm());
+ assertEquals("https://google.com? a = b", request.url().toExternalForm());
request = Request.get()
.url("https://google.com?%20a%20=%20b")
.build();
assertEquals("google.com", request.url().getHost());
assertEquals("https://google.com?%20a%20=%20b", request.absolute());
assertEquals("?%20a%20=%20b", request.relative());
- assertEquals("https://google.com? a = b", request.url().toString());
+ assertEquals("%20a%20=%20b", request.url().getQuery());
+ assertEquals(" a = b", request.url().getDecodedQuery());
+ assertEquals("https://google.com?%20a%20=%20b", request.url().toString());
assertEquals("https://google.com?%20a%20=%20b", request.url().toExternalForm());
}
@@ -149,6 +153,10 @@ class RequestBuilderTest {
requestBuilder.addParameter("param" + i, "value" + i);
}
Request request = requestBuilder.build();
- assertEquals(18276, request.absolute().length());
+ assertEquals(37796, request.absolute().length());
+ Request parsedRequest = Request.get()
+ .url(request.url())
+ .build();
+ assertEquals(37796, parsedRequest.absolute().length());
}
}
diff --git a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http1/FileDescriptorLeakTest.java b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http1/FileDescriptorLeakTest.java
index 394e63e..19225a8 100644
--- a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http1/FileDescriptorLeakTest.java
+++ b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http1/FileDescriptorLeakTest.java
@@ -22,14 +22,14 @@ class FileDescriptorLeakTest {
if (os instanceof UnixOperatingSystemMXBean) {
logger.info("before: number of open file descriptor : " + ((UnixOperatingSystemMXBean) os).getOpenFileDescriptorCount());
}
- try (Client client = Client.builder().setThreadCount(1).build()) {
- Request request = Request.get().url("http://xbib.org")
- .setResponseListener(resp -> {
- logger.log(Level.INFO, "status = " + resp.getStatus());
- })
- .build();
- client.execute(request);
- }
+ Client client = Client.builder().setThreadCount(1).build();
+ Request request = Request.get().url("http://xbib.org")
+ .setResponseListener(resp -> {
+ logger.log(Level.INFO, "status = " + resp.getStatus());
+ })
+ .build();
+ client.execute(request);
+ client.close();
if (os instanceof UnixOperatingSystemMXBean){
logger.info("after: number of open file descriptor : " + ((UnixOperatingSystemMXBean) os).getOpenFileDescriptorCount());
}
diff --git a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http2/XbibTest.java b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http2/XbibTest.java
index 8075f29..be38479 100644
--- a/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http2/XbibTest.java
+++ b/netty-http-client/src/test/java/org/xbib/netty/http/client/test/http2/XbibTest.java
@@ -13,17 +13,17 @@ public class XbibTest {
@Test
void testXbib() throws Exception {
- try (Client client = Client.builder()
+ Client client = Client.builder()
.enableDebug()
- .build()) {
- Request request = Request.get()
- .url("https://xbib.org/")
- .setVersion("HTTP/2.0")
- .setResponseListener(resp -> logger.log(Level.INFO, "got HTTP/2 response: " +
- resp.getHeaders() + resp.getBodyAsString(StandardCharsets.UTF_8)))
- .build();
- client.execute(request).get().close();
- }
+ .build();
+ Request request = Request.get()
+ .url("https://xbib.org/")
+ .setVersion("HTTP/2.0")
+ .setResponseListener(resp -> logger.log(Level.INFO, "got HTTP/2 response: " +
+ resp.getHeaders() + resp.getBodyAsString(StandardCharsets.UTF_8)))
+ .build();
+ client.execute(request).get().close();
+ client.close();
}
}
diff --git a/netty-http-common/src/main/java/org/xbib/netty/http/common/HttpParameters.java b/netty-http-common/src/main/java/org/xbib/netty/http/common/HttpParameters.java
index 29f6d0a..215cff8 100644
--- a/netty-http-common/src/main/java/org/xbib/netty/http/common/HttpParameters.java
+++ b/netty-http-common/src/main/java/org/xbib/netty/http/common/HttpParameters.java
@@ -1,9 +1,13 @@
package org.xbib.netty.http.common;
import io.netty.handler.codec.http.HttpHeaderValues;
+import org.xbib.datastructures.common.MultiMap;
+import org.xbib.datastructures.common.Pair;
+import org.xbib.datastructures.common.TreeMultiMap;
+import org.xbib.net.PercentDecoder;
import org.xbib.net.PercentEncoder;
import org.xbib.net.PercentEncoders;
-import org.xbib.netty.http.common.util.CaseInsensitiveParameters;
+
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.MalformedInputException;
@@ -13,26 +17,26 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
- * A limited multi-map of HTTP request parameters. Each key references a
- * limited set of parameters collected from the request during message
- * signing. Parameter values are sorted as per
- * OAuth specification.
+ * A multi-map of HTTP request parameters. Each key references a
+ * set of parameters collected from the request during message
+ * signing.
* Every key/value pair will be percent-encoded upon insertion.
- * This class has special semantics tailored to
- * being useful for message signing; it's not a general purpose collection class
- * to handle request parameters.
*/
-public class HttpParameters extends CaseInsensitiveParameters {
+@SuppressWarnings("serial")
+public class HttpParameters {
- private static final String EQUALS = "=";
+ private static final Logger logger = Logger.getLogger(HttpParameters.class.getName());
- private static final String AMPERSAND = "&";
+ private static final char EQUAL_CHAR = '=';
+ private static final char AMPERSAND_CHAR = '&';
- private final int sizeLimit;
+ private final MultiMap multiMap;
- private final int elementSizeLimit;
+ private final PercentDecoder percentDecoder;
private final PercentEncoder percentEncoder;
@@ -41,24 +45,16 @@ public class HttpParameters extends CaseInsensitiveParameters {
private final Charset encoding;
public HttpParameters() {
- this(1024, 1024, 65536,
- HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED, StandardCharsets.UTF_8);
+ this(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED, StandardCharsets.UTF_8);
}
public HttpParameters(CharSequence contentType) {
- this(1024, 1024, 65536,
- contentType, StandardCharsets.UTF_8);
+ this(contentType, StandardCharsets.UTF_8);
}
public HttpParameters(CharSequence contentType, Charset charset) {
- this(1024, 1024, 65536,
- contentType, charset);
- }
-
- public HttpParameters(int maxParam, int sizeLimit, int elementSizeLimit,
- CharSequence contentType, Charset charset) {
- this.sizeLimit = sizeLimit;
- this.elementSizeLimit = elementSizeLimit;
+ this.multiMap = new TreeMultiMap<>();
+ this.percentDecoder = new PercentDecoder();
this.percentEncoder = PercentEncoders.getQueryEncoder(charset);
this.contentType = contentType;
this.encoding = charset;
@@ -72,12 +68,26 @@ public class HttpParameters extends CaseInsensitiveParameters {
return encoding;
}
- public Collection put(String key, Collection values, boolean percentEncode) {
- remove(key);
+ public String get(String key) {
+ Collection collection = multiMap.get(key);
+ if (collection != null) {
+ Iterator iterator = collection.iterator();
+ if (iterator.hasNext()) {
+ return iterator.next();
+ }
+ }
+ return null;
+ }
+
+ public Collection getAll(String key) {
+ return multiMap.get(key);
+ }
+
+ public void put(String key, Collection values, boolean percentEncode) {
+ multiMap.remove(key);
for (String v : values) {
add(key, v, percentEncode);
}
- return getAll(key);
}
/**
@@ -121,7 +131,7 @@ public class HttpParameters extends CaseInsensitiveParameters {
try {
String k = percentEncode ? percentEncoder.encode(key) : key;
String v = percentEncode ? percentEncoder.encode(value) : value;
- super.add(k, v);
+ multiMap.put(k, v);
} catch (CharacterCodingException e) {
throw new IllegalArgumentException(e);
}
@@ -130,10 +140,10 @@ public class HttpParameters extends CaseInsensitiveParameters {
public String getAsQueryString(boolean percentEncode) throws MalformedInputException, UnmappableCharacterException {
List list = new ArrayList<>();
- for (String key : super.names()) {
+ for (String key : multiMap.keySet()) {
list.add(getAsQueryString(key, percentEncode));
}
- return String.join(AMPERSAND, list);
+ return String.join(String.valueOf(AMPERSAND_CHAR), list);
}
/**
@@ -164,20 +174,46 @@ public class HttpParameters extends CaseInsensitiveParameters {
public String getAsQueryString(String key, boolean percentEncode)
throws MalformedInputException, UnmappableCharacterException {
String k = percentEncode ? percentEncoder.encode(key) : key;
- Collection values = getAll(k);
- if (values == null) {
- return k + EQUALS;
- }
+ Collection values = multiMap.asMap().get(key);
Iterator it = values.iterator();
StringBuilder sb = new StringBuilder();
while (it.hasNext()) {
String v = it.next();
v = percentEncode ? percentEncoder.encode(v) : v;
- sb.append(k).append(EQUALS).append(v);
+ sb.append(k).append(EQUAL_CHAR).append(v);
if (it.hasNext()) {
- sb.append(AMPERSAND);
+ sb.append(AMPERSAND_CHAR);
}
}
return sb.toString();
}
+
+ public void addPercentEncodedBody(String body) {
+ if (body == null) {
+ return;
+ }
+ // watch out for "plus" encoding, replace it with a space character
+ String s = body.replace('+', ' ');
+ while (s != null) {
+ Pair pairs = indexOf(AMPERSAND_CHAR, s);
+ Pair pair = indexOf(EQUAL_CHAR, pairs.getKey());
+ if (pair.getKey() != null && !pair.getKey().isEmpty()) {
+ try {
+ String key = percentDecoder.decode(pair.getKey());
+ String value = pair.getValue() instanceof CharSequence ? percentDecoder.decode((CharSequence) pair.getValue()) : pair.getValue().toString();
+ addRaw(key, value);
+ } catch (MalformedInputException | UnmappableCharacterException e) {
+ logger.log(Level.WARNING, "unable to decode parameter in body: " + e.getMessage(), e);
+ }
+ }
+ s = pairs.getValue() !=null ? pairs.getValue().toString() : null;
+ }
+ }
+
+ private static Pair indexOf(char ch, String input) {
+ int i = input.indexOf(ch);
+ String k = i >= 0 ? input.substring(0, i) : input;
+ Object v = i >= 0 ? input.substring(i + 1) : null;
+ return Pair.of(k, v);
+ }
}
diff --git a/netty-http-common/src/test/resources/logging.properties b/netty-http-common/src/test/resources/logging.properties
new file mode 100644
index 0000000..d9913d4
--- /dev/null
+++ b/netty-http-common/src/test/resources/logging.properties
@@ -0,0 +1,5 @@
+handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+.level=ALL
+java.util.logging.ConsoleHandler.level=ALL
+java.util.logging.ConsoleHandler.formatter=org.xbib.net.util.ThreadLoggingFormatter
+jdk.event.security.level=INFO
diff --git a/netty-http-server/src/main/java/org/xbib/netty/http/server/HttpServerRequest.java b/netty-http-server/src/main/java/org/xbib/netty/http/server/HttpServerRequest.java
index 2b8d68d..4f428d9 100644
--- a/netty-http-server/src/main/java/org/xbib/netty/http/server/HttpServerRequest.java
+++ b/netty-http-server/src/main/java/org/xbib/netty/http/server/HttpServerRequest.java
@@ -7,10 +7,6 @@ import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpUtil;
-import org.xbib.datastructures.common.Pair;
-import org.xbib.net.Parameter;
-import org.xbib.net.ParameterBuilder;
-import org.xbib.net.PercentDecoder;
import org.xbib.net.URL;
import org.xbib.netty.http.common.HttpParameters;
import org.xbib.netty.http.server.api.Domain;
@@ -363,42 +359,31 @@ public class HttpServerRequest implements ServerRequest {
public ServerRequest build() {
// build URL and parameters
Charset charset = HttpUtil.getCharset(fullHttpRequest, StandardCharsets.UTF_8);
+ CharSequence mimeType = HttpUtil.getMimeType(fullHttpRequest);
+ this.parameters = new HttpParameters(mimeType, charset);
// creates path, query params, fragment
this.url = URL.builder()
.charset(charset, CodingErrorAction.REPLACE)
.path(fullHttpRequest.uri()) // creates path, query params, fragment
.build();
- ParameterBuilder queryParameters = Parameter.builder();
- //url.getQueryParams();
- CharSequence mimeType = HttpUtil.getMimeType(fullHttpRequest);
- ByteBuf byteBuf = fullHttpRequest.content();
- if (byteBuf != null) {
- if (fullHttpRequest.method().equals(HttpMethod.POST)) {
- String params;
+ url.getQueryParams().forEach(p -> parameters.add(p.getKey(), p.getValue().toString()));
+ if (fullHttpRequest.method().equals(HttpMethod.POST)) {
+ ByteBuf byteBuf = fullHttpRequest.content();
+ if (byteBuf != null) {
+ Charset htmlCharset = HttpUtil.getCharset(fullHttpRequest, StandardCharsets.ISO_8859_1);
+ String body = byteBuf.toString(htmlCharset);
// https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
if (mimeType != null && HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED.toString().equals(mimeType.toString())) {
- Charset htmlCharset = HttpUtil.getCharset(fullHttpRequest, StandardCharsets.ISO_8859_1);
- params = byteBuf.toString(htmlCharset).replace('+', ' ');
- if (logger.isLoggable(Level.FINER)) {
- logger.log(Level.FINER, "html form, charset = " + htmlCharset + " param body = " + params);
- }
- queryParameters.addPercentEncodedBody(params);
+ logger.log(Level.INFO, "html form, charset = " + htmlCharset + " body = " + body);
+ parameters.addPercentEncodedBody(body);
+ } else {
+ logger.log(Level.WARNING, "unable to process POST request, mime type = " + mimeType);
}
+ } else {
+ logger.log(Level.WARNING, "unable to process POST request,body is empty");
}
}
- // copy to HTTP parameters but percent-decoded (looks very clumsy)
- PercentDecoder percentDecoder = new PercentDecoder(charset.newDecoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE));
- this.parameters = new HttpParameters(mimeType, charset);
- for (Pair pair : queryParameters.build()) {
- try {
- parameters.addRaw(percentDecoder.decode(pair.getKey()), percentDecoder.decode(pair.getValue().toString()));
- } catch (Exception e) {
- // does not happen
- throw new IllegalArgumentException(pair.toString());
- }
- }
+ logger.log(Level.FINER, "HTTP server complete");
return new HttpServerRequest(this);
}
diff --git a/netty-http-server/src/main/java/org/xbib/netty/http/server/Server.java b/netty-http-server/src/main/java/org/xbib/netty/http/server/Server.java
index 6dd02f9..7e289e7 100644
--- a/netty-http-server/src/main/java/org/xbib/netty/http/server/Server.java
+++ b/netty-http-server/src/main/java/org/xbib/netty/http/server/Server.java
@@ -56,7 +56,7 @@ import java.util.logging.Logger;
/**
* HTTP server.
*/
-public final class Server implements AutoCloseable {
+public final class Server {
private static final Logger logger = Logger.getLogger(Server.class.getName());
@@ -168,7 +168,6 @@ public final class Server implements AutoCloseable {
accept().channel().closeFuture().sync();
}
- @Override
public void close() {
try {
shutdownGracefully();
diff --git a/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http1/PostTest.java b/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http1/PostTest.java
index 050a007..8c53e4a 100644
--- a/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http1/PostTest.java
+++ b/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http1/PostTest.java
@@ -1,5 +1,6 @@
package org.xbib.netty.http.server.test.http1;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -34,7 +35,9 @@ class PostTest {
HttpServerDomain domain = HttpServerDomain.builder(httpAddress)
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
- logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ logger.log(Level.INFO, "server got request " + parameters +
+ " body = " + req.getContent(StandardCharsets.UTF_8) +
+ " withspace = " + parameters.get("withspace"));
if ("Hello World".equals(parameters.get("withspace"))) {
success2.set(true);
}
@@ -86,7 +89,7 @@ class PostTest {
HttpServerDomain domain = HttpServerDomain.builder(httpAddress)
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
- logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ logger.log(Level.INFO, "server got request " + parameters + " body = " + req.getContent(StandardCharsets.UTF_8));
if ("Hello World".equals(parameters.get("withspace"))) {
success2.set(true);
}
@@ -128,7 +131,7 @@ class PostTest {
}
@Test
- void testFormPostHttp1() throws Exception {
+ void testFormPostHttp1WithCorrectContentType() throws Exception {
final AtomicBoolean success1 = new AtomicBoolean(false);
final AtomicBoolean success2 = new AtomicBoolean(false);
final AtomicBoolean success3 = new AtomicBoolean(false);
@@ -137,7 +140,7 @@ class PostTest {
HttpServerDomain domain = HttpServerDomain.builder(httpAddress)
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
- logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ logger.log(Level.INFO, "server got request " + parameters + " body = " + req.getContent(StandardCharsets.UTF_8));
if ("Hello World".equals(parameters.get("withplus"))) {
success2.set(true);
}
@@ -164,6 +167,7 @@ class PostTest {
};
Request postRequest = Request.post().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/post/test.txt"))
+ // the corrent content type
.contentType(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED, StandardCharsets.UTF_8)
.addParameter("a", "b")
// test 'plus' encoding
@@ -185,7 +189,7 @@ class PostTest {
}
@Test
- void testTextPlainPostHttp1() throws Exception {
+ void testTextPlainPostHttp1MustFail() throws Exception {
final AtomicBoolean success1 = new AtomicBoolean(false);
final AtomicBoolean success2 = new AtomicBoolean(false);
final AtomicBoolean success3 = new AtomicBoolean(false);
@@ -194,7 +198,7 @@ class PostTest {
HttpServerDomain domain = HttpServerDomain.builder(httpAddress)
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
- logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ logger.log(Level.INFO, "server got request " + parameters + " body = " + req.getContent(StandardCharsets.UTF_8));
if ("Hello World".equals(parameters.get("withoutplus"))) {
success2.set(true);
}
@@ -223,7 +227,7 @@ class PostTest {
.setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/post/test.txt"))
.contentType(HttpHeaderValues.TEXT_PLAIN, StandardCharsets.UTF_8)
- // you can not pass form parameters on content type "text/plain"
+ // you can not pass form parameters on content type "text/plain" :-)
.addParameter("a", "b")
.addParameter("my param", "my value")
.addParameter("withoutplus", "Hello World")
@@ -237,9 +241,9 @@ class PostTest {
logger.log(Level.INFO, "server and client shut down");
}
assertTrue(success1.get());
- assertTrue(success2.get());
- assertTrue(success3.get());
- assertTrue(success4.get());
+ assertFalse(success2.get());
+ assertFalse(success3.get());
+ assertFalse(success4.get());
}
@Test
@@ -252,10 +256,11 @@ class PostTest {
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ // unable to decode without underflow
if ("myÿvalue".equals(parameters.get("my param"))) {
success1.set(true);
}
- if ("bÿc".equals(parameters.get("a"))) {
+ if ("b%25YYc".equals(parameters.get("a"))) {
success2.set(true);
}
resp.getBuilder().setStatus(HttpResponseStatus.OK.code()).build().flush();
@@ -285,9 +290,8 @@ class PostTest {
client.shutdownGracefully();
logger.log(Level.INFO, "server and client shut down");
}
- assertTrue(success1.get());
+ assertFalse(success1.get());
assertTrue(success2.get());
assertTrue(success3.get());
}
-
}
diff --git a/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http2/PostTest.java b/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http2/PostTest.java
index bc449bc..2000022 100644
--- a/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http2/PostTest.java
+++ b/netty-http-server/src/test/java/org/xbib/netty/http/server/test/http2/PostTest.java
@@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(NettyHttpTestExtension.class)
@@ -240,9 +241,9 @@ class PostTest {
logger.log(Level.INFO, "server and client shut down");
}
assertTrue(success1.get());
- assertTrue(success2.get());
- assertTrue(success3.get());
- assertTrue(success4.get());
+ assertFalse(success2.get());
+ assertFalse(success3.get());
+ assertFalse(success4.get());
}
@Test
@@ -255,10 +256,11 @@ class PostTest {
.singleEndpoint("/post", "/**", (req, resp) -> {
HttpParameters parameters = req.getParameters();
logger.log(Level.INFO, "got request " + parameters.toString() + ", sending OK");
+ // unable to decode
if ("myÿvalue".equals(parameters.get("my param"))) {
success1.set(true);
}
- if ("bÿc".equals(parameters.get("a"))) {
+ if ("b%25YYc".equals(parameters.get("a"))) {
success2.set(true);
}
resp.getBuilder().setStatus(HttpResponseStatus.OK.code()).build().flush();
@@ -289,7 +291,7 @@ class PostTest {
client.shutdownGracefully();
logger.log(Level.INFO, "server and client shut down");
}
- assertTrue(success1.get());
+ assertFalse(success1.get());
assertTrue(success2.get());
assertTrue(success3.get());
}
diff --git a/netty-http-server/src/test/resources/logging.properties b/netty-http-server/src/test/resources/logging.properties
new file mode 100644
index 0000000..d9913d4
--- /dev/null
+++ b/netty-http-server/src/test/resources/logging.properties
@@ -0,0 +1,5 @@
+handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+.level=ALL
+java.util.logging.ConsoleHandler.level=ALL
+java.util.logging.ConsoleHandler.formatter=org.xbib.net.util.ThreadLoggingFormatter
+jdk.event.security.level=INFO
diff --git a/settings.gradle b/settings.gradle
index a39d844..e611dc8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -10,11 +10,11 @@ dependencyResolutionManagement {
versionCatalogs {
libs {
version('gradle', '7.5.1')
- version('groovy', '3.0.10')
- version('spock', '2.0-groovy-3.0')
- version('junit', '5.9.1')
- version('netty', '4.1.85.Final')
- version('netty-tcnative', '2.0.54.Final')
+ version('groovy', '4.0.11')
+ version('spock', '2.4-M1-groovy-4.0')
+ version('junit', '5.9.2')
+ version('netty', '4.1.90.Final')
+ version('netty-tcnative', '2.0.59.Final')
library('groovy-core', 'org.codehaus.groovy', 'groovy').versionRef('groovy')
library('spock-core', 'org.spockframework', 'spock-core').versionRef('spock')
library('spock-junit4', 'org.spockframework', 'spock-junit4').versionRef('spock')
@@ -27,13 +27,13 @@ dependencyResolutionManagement {
library('netty-epoll', 'io.netty', 'netty-transport-native-epoll').versionRef('netty')
library('netty-kqueue', 'io.netty', 'netty-transport-native-kqueue').versionRef('netty')
library('netty-boringssl', 'io.netty', 'netty-tcnative-boringssl-static').versionRef('netty-tcnative')
- library('net', 'org.xbib', 'net').version('3.0.2')
- library('net-path', 'org.xbib', 'net-path').version('3.0.2')
library('bouncycastle', 'org.bouncycastle', 'bcpkix-jdk18on').version('1.72')
library('conscrypt', 'org.conscrypt', 'conscrypt-openjdk-uber').version('2.5.2')
library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.12.7')
- library('guice', 'org.xbib', 'guice').version('5.0.1.0')
library('javassist', 'org.javassist', 'javassist').version('3.29.1-GA')
+ library('guice', 'org.xbib', 'guice').version('5.0.1.0')
+ library('net', 'org.xbib', 'net').version('3.1.0')
+ library('net-path', 'org.xbib', 'net-path').version('3.1.0')
}
}
}