GithubHelp home page GithubHelp logo

jettyhelloworld's Introduction

Filter Example Using Jetty and Maven

This is a simple web service with a single resource (/hello) that illustrates using a rate-limiting filter and logging filter with embedded Jetty.

Rate limiting is done using Jetty's DoSFilter. Request logging is done using a filter class I wrote (its easy) that implements javax.servlet.Filter.

Both filters use Simple Logging for Java (slf4j), which is included in the Maven dependencies.

The resource itself is HellowResource.java in org.ske.resource, which uses standard JAX-RS annotations.

Below is a description of how to configure the DosFilter, how to run the project, and general method of adding a filter to an embedded Jetty project.

Adding Filters to an Embedded Jetty Project

The org.ske.JettyMain class shows how to configure filters and add them to a context. After you create a ContextHandler, you use the context.addFilter method (which is overloaded). An example is:

// ContextHandler for your web service or servlets:
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
// add servlets
// ...

// add filters
EnumSet<DispatcherType> SCOPE = EnumSet.of(DispatcherType.REQUEST);
// my request logging filter
context.addFilter( RequestLoggingFilter.class, "/*", SCOPE );
// Jetty DoSFilter, wrapped so we can set init parameters
FilterHolder holder = new FilterHolder( DoSFilter.class );
// see DoSFilter Javadoc for names and meanings of init parameters
holder.setInitParameter("maxRequestsPerSec", "1"); // "1" for testing
holder.setInitParameter("delayMs", "200"); // "-1" to reject excess request
holder.setInitParameter("remotePort", "false"); // "true" may be useful

context.addFilter( holder, "/*", SCOPE );
server.setHandler( context );

Build and Run this Project using Maven

The first time, Maven will download a lot of stuff.

>  mvn clean
>  mvn compile
>  mvn exec:java

[lots of messages]
Jetty Server started on port 8080...

you can also write the goals on one line: mvn clean compile exec:java.

Now send some requests to http://localhost:8080/hello. You should see a log message printed by the RequestLoggingFilter.

If you send requests faster than 1 per second (click "refresh" really fast), you should see some messages like this:

INFO RequestLoggingFilter - From 127.0.0.1:51830  GET /hello
WARN org.eclipse.jetty.servlets.DoSFilter - DOS ALERT: Request rejected ip=127.0.0.1,session=null,user=null

The "WARN" message shows you the DosFilter is working. As you can see below, I configured it to allow only 1 request per second per client, and to REJECT excess requests (the normal behavior is to queue extra requests and insert a delay). Realistically, you would allow more requests per second and not reject excess requests until the request queue is full.

When a request is rejected your browser should display:

HTTP ERROR: 503
Service Unavailable

Request Rate Limiting using DoSFilter

An application may need to limit the rate of requests to prevent a DoS attack or simply prevent one client from tying up the server at expense of others.

The Jetty DoSFilter does this, as documented at https://wiki.eclipse.org/Jetty/Reference/DoSFilter.

The DoSFilter uses a priority queue for requests. It gives priority to:

  • authenticated requests - use the extactUserId(ServletRequest) method to identify authenticated users
  • requests with an HttpSession
  • connections identified by IP address
  • (lowest priority) requests with no way to identify requester

To use this filter, your web application needs these two Jar files: jetty-util.jar and jetty-servlets.jar

For a Maven project, include these artifacts in your dependencies:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>${jetty.version}</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlets</artifactId>
    <version>${jetty.version}</version>
</dependency>

Parameters to Configure DoSFilter

The DoSFilter has many parameters to configure filter behavior and allowed request rates. They are all described in the DoSFilter Javadoc.

Some parameters I used are:

  • maxRequestsPerSec number of requests per connection per second
  • delayMs how long to delay requests over the rate limit. -1 means to reject.
  • trackSessions = false where to track sessions if a Session exists. Default is true.
  • remotePort = true track sender by IpAddr+port. Default is false.
  • ipWhitelist comma separated list of IP addresses not rate limited. Use 127.0.0.1 if another local app is using this service.

The Jetty documentation doesn't tell you how to set these parameters in an embedded application (they only describe settings in web.xml).

See the method JettyMain.startServer() for how I did using a FilterHolder. Creating an instance of DoSFilter and calling dosFilter.setXXX(yy) methods didn't work!

Example of how to write your own rate-limiting filter in Jetty:

If the DoSFilter doesn't do what you want, this example of writing a rate limiting filter may be helpful.

http://alvinalexander.com/java/jwarehouse/jetty-6.1.9/modules/util/src/main/java/org/mortbay/servlet/ThrottlingFilter.java.shtml

Logging Filter and Simple Logging for Java (slf4j)

This sample code also has a request logging filter. At first I used java.util.logging.Logger to output messages, but the log messages are ugly so I switched to Simple Logging for Java (slf4j). slf4j is a wrapper for other logging frameworks, such as Log4J.

To use slf4j in a Maven project requires dependencies for slf4j-api, an actual logger (e.g. Log4J), and an slf4j adapter for your logger (slf4j-log4j). For this project, I used the "simple logging" adapter that just prints messages on System.out.

jettyhelloworld's People

Contributors

jbrucker avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.