Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/11.0.x' into 12.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
joakime committed Jul 23, 2024
2 parents f6c0e34 + 17c4c3d commit 08b751b
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 1 deletion.
1 change: 1 addition & 0 deletions embedded/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* [`form-post/`](form-post/) - Handling forms (query, or `application/x-www-form-urlencoded` or `multipart/form-data`) with Jetty Core
* [`http-config/`](http-config/) - Using `HttpConfiguration`
* [`jndi/`](jndi/) - Using `JNDI` from EE10 Servlet environment
* [`limited-requests/`](limited-requests/) - Creating a `Handler.Wrapper` to limit the number of pipelined requests in a single HTTP/1 connection
* [`logging-java-util-logging/`](logging-java-util-logging/) - Using `java.util.logging` from Jetty Core
* [`logging-mixed/`](logging-mixed/) - Using multiple Logging APIs from Jetty Core
* [`logging-slf4j/`](logging-slf4j/) - Using `org.slf4j` from Jetty Core
Expand Down
2 changes: 1 addition & 1 deletion embedded/ee10-jsp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<name>Jetty Examples :: Jetty 12.0.x :: Embedded :: JSP</name>

<properties>
<logback.version>1.4.14</logback.version>
<logback.version>1.5.6</logback.version>
<maven.exec.plugin.version>3.3.0</maven.exec.plugin.version>
<slf4j.version>2.0.13</slf4j.version>
</properties>
Expand Down
39 changes: 39 additions & 0 deletions embedded/limited-requests/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty.examples.embedded</groupId>
<artifactId>jetty-embedded-examples</artifactId>
<version>12.0.x</version>
</parent>
<artifactId>limited-requests</artifactId>
<version>12.0.x</version>
<packaging>jar</packaging>
<name>Jetty Examples :: Jetty 12.0.x :: Embedded :: Limited Requests</name>

<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<version>${jetty-test-helper.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package examples;

import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.Callback;

public class LimitedRequestsExample
{
public static void main(String[] args) throws Exception
{
Server server = newServer(8080);
server.start();
server.join();
}

public static Server newServer(int port)
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(port);

LimitedRequestsWrapper limitedRequestsWrapper = new LimitedRequestsWrapper();
limitedRequestsWrapper.setMaxRequests(5);

server.addConnector(connector);

limitedRequestsWrapper.setHandler(new HelloHandler());

server.setHandler(limitedRequestsWrapper);
return server;
}

private static class HelloHandler extends Handler.Abstract
{
@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception
{
response.setStatus(200);
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain;charset=utf-8");
Content.Sink.write(response, true, "Hello World", callback);
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package examples;

import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;

public class LimitedRequestsWrapper extends Handler.Wrapper
{
private int maxRequests = 10;

public int getMaxRequests()
{
return maxRequests;
}

public void setMaxRequests(int maxRequests)
{
this.maxRequests = maxRequests;
}

@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception
{
Response resp = response;

// Only perform "Connection: close" on HTTP/1.1 or HTTP/1.0 (not HTTP/2 or HTTP/3)
if (request.getConnectionMetaData().getHttpVersion().getVersion() <= 11)
{
long requests = request.getConnectionMetaData().getConnection().getMessagesIn();
// After X responses, forcibly set connection close on response
if (requests >= maxRequests)
{
resp = new ConnectionCloseWrapper(request, response);
}
}
return super.handle(request, resp, callback);
}

private static class ConnectionCloseWrapper extends Response.Wrapper
{
private HttpFields.Mutable httpFields;

public ConnectionCloseWrapper(Request request, Response wrapped)
{
super(request, wrapped);

httpFields = new HttpFields.Mutable.Wrapper(wrapped.getHeaders())
{
@Override
public HttpField onAddField(HttpField field)
{
if (field.getHeader() == HttpHeader.CONNECTION)
{
if (!field.getValue().equalsIgnoreCase("close"))
throw new HttpException.RuntimeException(HttpStatus.INTERNAL_SERVER_ERROR_500, "Connection count exceeded, close is forced");
}
return super.onAddField(field);
}
};
httpFields.put(HttpHeader.CONNECTION, "close");
}

@Override
public HttpFields.Mutable getHeaders()
{
return httpFields;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package examples;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URI;
import java.nio.charset.StandardCharsets;

import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.component.LifeCycle;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;

public class LimitedRequestsExampleTest
{
private Server server;

@BeforeEach
public void startServer() throws Exception
{
server = LimitedRequestsExample.newServer(0);
server.start();
}

@AfterEach
public void stopServer()
{
LifeCycle.stop(server);
}

@Test
public void testLimitedRequests() throws IOException
{
URI serverURI = server.getURI();

String rawRequest = "GET / HTTP/1.1\r\n" +
"Host: " + serverURI.getRawAuthority() + "\r\n" +
"\r\n";

try (Socket client = new Socket(serverURI.getHost(), serverURI.getPort());
OutputStream out = client.getOutputStream();
InputStream in = client.getInputStream();)
{
// Per configuration of setMaxRequests in LimitedRequestsExample this will allow
// only 5 requests before sending a Connection: close
for (int i = 1; i < 5; i++)
{
out.write(rawRequest.getBytes(StandardCharsets.UTF_8));
out.flush();

HttpTester.Response response = HttpTester.parseResponse(in);
assertThat(response.getStatus(), is(200));
assertThat(response.get(HttpHeader.CONNECTION), is(nullValue()));
}

// and one final one should trigger the closure
out.write(rawRequest.getBytes(StandardCharsets.UTF_8));
out.flush();

HttpTester.Response response = HttpTester.parseResponse(in);
assertThat(response.getStatus(), is(200));
assertThat(response.get(HttpHeader.CONNECTION), is("close"));
}
}
}
1 change: 1 addition & 0 deletions embedded/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<module>form-post</module>
<module>http-config</module>
<module>jndi</module>
<module>limited-requests</module>
<module>logging-java-util-logging</module>
<module>logging-mixed</module>
<module>logging-slf4j</module>
Expand Down

0 comments on commit 08b751b

Please sign in to comment.