Giter VIP home page Giter VIP logo

java-express's Introduction

Logo

Simple and fast HTTP-Framework with the touch of expressjs

License MIT Support me

State of this project

I created this years ago and I'm no longer actively working with java. If anyone is interested maintaining this (and has experience with java), feel free to leave a comment here. It merely was a proof-of-concept of how we could do things more the "funcional" oriented way and less like big java-frameworks and library use to be (as seen on simple but extremely popular libraries such as expressjs).

Getting Started

Express app = new Express();

app.get("/", (req, res) -> {
   res.send("Hello World");
}).listen(); // Will listen on port 80 which is set as default

Installation

Add the following dependency coordinate from JCenter on your favorite build system:

Download

io.vacco.java-express:java-express:<VERSION>

Routing

DynExpress

Express allows the attaching of request-handler to instance methods via the DynExpress annotation:

// Your main class
import express.Express;
public class Main {
    public static void main(String[] args) {
        Express app = new Express();
        app.bind(new Bindings()); // See class below
        app.listen();
    }
}

// Your class with request handlers
import express.DynExpress;
import express.http.RequestMethod;
import express.http.request.Request;
import express.http.response.Response;
public class Bindings {

    @DynExpress() // Default is context="/" and method=RequestMethod.GET
    public void getIndex(Request req, Response res) {
        res.send("Hello World!");
    }

    @DynExpress(context = "/about") // Only context is defined, method=RequestMethod.GET is used as method
    public void getAbout(Request req, Response res) {
        res.send("About page");
    }

    @DynExpress(context = "/impressum", method = RequestMethod.PATCH) // Both defined
    public void getImpressum(Request req, Response res) {
        res.send("Impressum page was patched");
    }

    @DynExpress(method = RequestMethod.POST) // Only the method is defined, "/" is used as context
    public void postIndex(Request req, Response res) {
        res.send("POST to index");
    }
}

Direct

You can add routes (And middlewares) directly to the Express object to handle requests:

Express app = new Express();

// Sample for home routes
app.get("/", (req, res) -> res.send("Hello index!"));
app.get("/home", (req, res) -> res.send("Homepage"));
app.get("/about", (req, res) -> res.send("About"));

// Sample for user
app.get("/user/login", (req, res) -> res.send("Please login!"));
app.get("/user/register", (req, res) -> res.send("Join now!"));

app.listen();

Directly it also supports methods like POST PATCH DELETE and PUT, others need to be created manually:

Express app = new Express();

// Basic methods
app.get("/user", (req, res) -> res.send("Get an user!"));
app.patch("/user", (req, res) -> res.send("Modify an user!"));
app.delete("/user", (req, res) -> res.send("Delete an user!"));
app.put("/user", (req, res) -> res.send("Add an user!"));

// Example fot the CONNECT method
app.on("/user", "CONNECT", (req, res) -> res.send("Connect!"));

app.listen();

With Router

But it's better to split your code, right? With the ExpressRouter you can create routes and add it later to the Express object:

Express app = new Express() {{

  // Define root greeting
  get("/", (req, res) -> res.send("Hello World!"));

  // Define home routes
  use("/home", new ExpressRouter(){{
    get("/about", (req, res) -> res.send("About page"));
    get("/impressum", (req, res) -> res.send("Impressum page"));
    get("/sponsors", (req, res) -> res.send("Sponsors page"));
  }});

  // Define root routes
  use("/", new ExpressRouter(){{
    get("/login", (req, res) -> res.send("Login page"));
    get("/register", (req, res) -> res.send("Register page"));
    get("/contact", (req, res) -> res.send("Contact page"));
  }});

  // Start server
  listen();
}};

URL Basics

Over the express object you can create handler for all request-methods and contexts. Some examples:

app.get("/home", (req, res) -> {
	// Will match every request which uses the 'GET' method and matches the '/home' path
});

app.post("/login", (req, res) -> {
	// Will match every request which uses the 'POST' method and matches the /login' path
});

URL Parameter

Sometimes you want to create dynamic URL where some parts of the URL's are not static. With the : operator you can create variables in the URL which will be saved later in a HashMap.

Example request: GET /posts/john/all:

app.get("/posts/:user/:description", (req, res) -> {
   String user = req.getParam("user"); // Contains 'john'
   String description = req.getParam("description"); // Contains 'all'
   res.send("User: " + user + ", description: " + description); // Send: "User: john, description: all"
});

URL Parameter Listener

You can also add an event listener when the user called an route which contains an certain parameter.

app.get("/posts/:user/:id", (req, res) -> {
  // Code
});

For example, if we want to check every id before the associated get post etc. handler will be fired, we can use the app.onParam([PARAM]) function:

app.onParam("id", (req, res) -> {
  // Do something with the id parameter, eg. check if it's valid.
});

Now, this function will be called every time when an context is requested which contains the id parameter placeholder.

URL Querys

If you make an request which contains querys, you can access the querys over req.getQuery(NAME).

Example request: GET /posts?page=12&from=john:

app.get("/posts", (req, res) -> {
   String page = req.getQuery("page"); // Contains '12'
   String from = req.getQuery("from"); // Contains 'John'
   res.send("Page: " + page + ", from: " + from); // Send: "Page: 12, from: John"
});

Cookies

With req.getCookie(NAME) you can get an cookie by his name, and with res.setCookie(NAME, VALUE) you can easily set an cookie.

Example request: GET /setcookie:

app.get("/setcookie", (req, res) -> {
   Cookie cookie = new Cookie("username", "john");
   res.setCookie(cookie);
   res.send("Cookie has been set!");
});

Example request: GET /showcookie:

app.get("/showcookie", (req, res) -> {
   Cookie cookie = req.getCookie("username");
   String username = cookie.getValue();
   res.send("The username is: " + username); // Prints "The username is: john"
});

Form data

Over req.getFormQuery(NAME) you receive the values from the input elements of an HTML-Form. Example HTML-Form:

<form action="http://localhost/register" method="post">
   <input description="text" name="email" placeholder="Your E-Mail">
   <input description="text" name="username" placeholder="Your username">
   <input description="submit">
</form>

Attention: Currently, File-inputs don't work, if there is an File-input the data won't get parsed! Now description, for the example below, john in username and [email protected] in the email field. Java code to handle the post request and access the form elements:

app.post("/register", (req, res) -> {
  String email = req.getFormQuery("email");
  String username = req.getFormQuery("username");
  // Process data

  // Prints "E-Mail: [email protected], Username: john"
  res.send("E-Mail: " + email + ", Username: " + username);
});

HTTP Relevant classes

Express

This class represents the entire HTTP-Server, the available methods are:

app.get(String context, HttpRequest handler);                   // Add an GET request handler
app.post(String context, HttpRequest handler);                  // Add an POST request handler
app.patch(String context, HttpRequest handler);                 // Add an PATCH request handler
app.put(String context, HttpRequest handler);                   // Add an PUT request handler
app.delete(String context, HttpRequest handler);                // Add an DELETE request handler
app.all(HttpRequest handler);                                   // Add an handler for all methods and contexts
app.all(String context, HttpRequest handler);                   // Add an handler for all methods but for an specific context
app.all(String context, String method, HttpRequest handler);    // Add an handler for an specific method and context
app.use(String context, String method, HttpRequest handler);    // Add an middleware for an specific method and context
app.use(HttpRequest handler);                                   // Add an middleware for all methods but for an specific context
app.use(String context, HttpRequest handler);                   // Add an middleware for all methods and contexts
app.use(String context, ExpressRouter router);                  // Add an router for an specific root context
app.use(ExpressRouter router);                                  // Add an router for the root context (/)
app.onParam(String name, HttpRequest handler);                  // Add an listener for an specific url parameter
app.getParameterListener();                                     // Returns all parameterlistener
app.get(String key);                                            // Get an environment variable
app.set(String key, String val);                                // Set an environment variable
app.isSecure();                                                 // Check if the server uses HTTPS
app.setExecutor(Executor executor);                             // Set an executor service for the request
app.listen();                                                   // Start the async server on port 80
app.listen(ExpressListener onstart);                            // Start the async server on port 80, call the listener after starting
app.listen(int port);                                           // Start the async server on an specific port
app.listen(ExpressListener onstart, int port);                  // Start the async server on an specific port call the listener after starting
app.stop();                                                     // Stop the server and all middleware worker

Response Object

Over the response object, you have serveral possibility like setting cookies, send an file and more. Below is an short explanation what methods exists: (We assume that res is the Response object)

res.getContentType();                  // Returns the current content type
res.setContentType(MediaType type);    // Set the content type with enum help
res.setContentType(String type);       // Set the content type
res.isClosed();                        // Check if the response is already closed
res.getHeader(String key);             // Get the value from an header field via key
res.setHeader(String key, String val); // Add an specific response header
res.sendAttachment(Path file)          // Sends a file as attachment
res.send(String str);                  // Send a string as response
res.send(Path path);                   // Send a file as response
res.send(byte[] bytes)                 // Send bytes as response
res.send();                            // Send empty response
res.redirect(String location);         // Redirect the request to another url
res.setCookie(Cookie cookie);          // Add an cookie to the response
res.sendStatus(Status status);         // Set the response status and send an empty response
res.getStatus();                       // Returns the current status
res.setStatus(Status status);          // Set the repose status
res.streamFrom(long contentLength, InputStream is, MediaType mediaType) // Send a inputstream with known length and type

The response object calls are comments because you can only call the .send(xy) once each request!

Request Object

Over the Request Object you have access to serveral request stuff (We assume that req is the Request object):

req.getAddress();                 // Returns the INET-Adress from the client
req.getMethod();                  // Returns the request method
req.getPath();                    // Returns the request path
req.getContext();                 // Returns the corresponding context
req.getQuery(String name);        // Returns the query value by name
req.getHost();                    // Returns the request host
req.getContentLength();           // Returns the content length
req.getContentType();             // Returns the content type
req.getMiddlewareContent(String name); // Returns the content from an middleware by name
req.getFormQuerys();              // Returns all form querys
req.getParams();                  // Returns all params
req.getQuerys();                  // Returns all querys
req.getFormQuery(String name);    // Returns the form value by name
req.getHeader(String key);        // Returns the value from an header field by name
req.getParam(String key);         // Returns the url parameter by name
req.getApp();                     // Returns the related express app
req.getCookie(String name);       // Returns an cookie by his name
req.getCookies();                 // Returns all cookies
req.getIp();                      // Returns the client IP-Address
req.getUserAgent();               // Returns the client user agent
req.getURI();                     // Returns the request URI
req.isFresh();                    // Returns true if the connection is fresh, false otherwise (see code inline-doc)
req.isStale();                    // Returns the opposite of req.fresh;
req.isSecure();                   // Returns true when the connection is over HTTPS, false otherwise
req.isXHR();                      // Returns true if the 'X-Requested-With' header field is 'XMLHttpRequest'
req.getProtocol();                // Returns the connection protocol
req.getAuthorization();           // Returns the request authorization
req.hasAuthorization();           // Check if the request has an authorization
req.pipe(OutputStream stream, int buffersize); // Pipe the request body to an outputstream
req.pipe(Path path, int buffersize);           // Pipe the request body to an file
req.getBody();                    // Returns the request inputstream

Middleware

Middleware are one of the most important features of JavaExpress, with middleware you can handle a request before it reaches any other request handler. To create an own middleware you have serveral interfaces:

  • HttpRequest - Is required to handle an request.
  • ExpressFilter - Is required to put data on the request listener.
  • ExpressFilterTask - Can be used for middleware which needs an background thread.

Middlewares work, for you, exact same as request handler. For example an middleware for all request-methods and contexts:

// Global context, matches every request.
app.use((req, res) -> {
  // Handle data
});

You can also filter by request-methods and contexts:

// Global context, you can also pass an context if you want
app.use("/home", "POST", (req, res) -> {
  // Handle request by context '/home' and method 'POST'
});

In addition to that yo can use * which stands for every context or request-method:

// Global context, you can also pass an context if you want
app.use("/home", "*", (req, res) -> {
  // Handle request which matches the context '/home' and all methods.
});

Create own middleware

Now we take a look how we can create own middlewares. Here we create an simple PortParser which parse / extract the port-number for us. We only used HttpRequest and ExpressFilter because we don't need any background thread.

public class PortMiddleware implements HttpRequest, ExpressFilter {

   /**
    * From interface HttpRequest, to handle the request.
    */
   @Override
   public void handle(Request req, Response res) {
      
      // Get the port
      int port = req.getURI().getPort();
      
      // Add the port to the request middleware map
      req.addMiddlewareContent(this, port);

      /**
       * After that you can use this middleware by call:
       *   app.use(new PortMiddleware());
       *   
       * Than you can get the port with:
       *   int port = (Integer) app.getMiddlewareContent("PortParser");
       */
   }

   /**
    * Defines the middleware.
    *
    * @return The middleware name.
    */
   @Override
   public String getName() {
      return "PortParser";
   }
}

Now we can, as we learned above, include it with:

// Global context, you can also pass an context if you want
app.use(new PortMiddleware());

And use it:

app.get("/port-test", (req, res) -> {
  
  // Get the content from the PortParser which we create above
  int port = (Integer) req.getMiddlewareContent("PortParser");
   
  // Return it to the client:
  res.send("Port: " + port);
});

Existing Middlewares

There are already some basic middlewares included, you can access these via static methods provided from Middleware.

CORS

To realize a cors api yu can use the cors middleware.

app.use(Middleware.cors());

You can use CorsOptions to specify origin, methods and more:

CorsOptions corsOptions = new CorsOptions();
corsOptions.setOrigin("https://mypage.com");
corsOptions.setAllowCredentials(true);
corsOptions.setHeaders(new String[]{"GET", "POST"});
corsOptions.setFilter(req -> // Custom validation if cors should be applied);
        
app.use(Middleware.cors());

Provide static Files

If you want to allocate some files, like librarys, css, images etc. you can use the static middleware. But you can also provide other files like mp4 etc.

Example:

 app.use(Middleware.statics("examplepath\\myfiles"));

Now you can access every files in the test_statics over the root adress \. I'ts also possible to set an configuration for the FileProvider:

FileProviderOptionsoptions = new FileProviderOptions();
options.setExtensions("html", "css", "js"); // By default, all are allowed.

/*
 * Activate the fallbacksearch.
 * E.g. if an request to <code>/js/code.js</code> was made but the
 * requested ressource cannot be found. It will be looked for an file called <code>code</code>
 * and return it.
 *
 *  Default is false
 */
options.setFallBackSearching(true);
options.setHandler((req, res) -> {...});    // Can be used to handle the request before the file will be returned.
options.setLastModified(true);              // Send the Last-Modified header, by default true.
options.setMaxAge(10000);                   // Send the Cache-Control header, by default 0.
options.setDotFiles(DotFiles.DENY);         // Deny access to dot-files. Default is IGNORE.
app.use(Middleware.statics("examplepath\\myfiles", new FileProviderOptions())); // Using with StaticOptions

Cookie Session

There is also an simple cookie-session implementation:

// You should use an meaningless cookie name for serveral security reasons, here f3v4.
// Also you can specify the maximum age of the cookie from the creation date and the file types wich are actually allowed.
app.use(Middleware.cookieSession("f3v4", 9000));

To use a session cookie we need to get the data from the middleware which is actually an SessionCookie:

 // Cookie session example
app.get("/session", (req, res) -> {

   /**
   * CookieSession named his data "Session Cookie" which is
   * an SessionCookie so we can Cast it.
   */
   SessionCookie sessionCookie = (SessionCookie) req.getMiddlewareContent("sessioncookie");
   int count;
   
Check if the data is null, we want to implement an simple counter
   if (sessionCookie.getData() == null) {
   
      // Set the default data to 1 (first request with this session cookie)
      count = (Integer) sessionCookie.setData(1);
   
   } else {
      // Now we know that the cookie has an integer as data property, increase it
      count = (Integer) sessionCookie.setData((Integer) sessionCookie.getData() + 1);
   }

Send an info message
   res.send("You take use of your session cookie " + count + " times.");
});

Global Variables

Java-express also supports to save and read global variables over the Express instance.

app.set("my-data", "Hello World");
app.get("my-data"); // Returns "Hello World"

Examples

Very simple static-website

// Create instance
new Express() {{
  
  // Define middleware-route for static site
  use("/", Middleware.statics("my-website-folder/"));
}};

File download

// Your file
Path downloadFile = Paths.get("my-big-file");

// Create instance
new Express() {{

  // Create get-route where the file can be downloaded
  get("/download-me", (req, res) -> res.sendAttachment(downloadFile));
}};

Send cookies

new Express() {{

  // Define route
  get("/give-me-cookies", (req, res) -> {
  
    // Set an cookie (you can call setCookie how often you want)
    res.setCookie(new Cookie("my-cookie", "Hello World!"));
    
    // Send text
    res.send("Your cookie has been set!");
  });
}};

License

This project is licensed under the MIT License - see the LICENSE file for details.

java-express's People

Contributors

cocomana avatar jjzazuet avatar michalwa avatar simonwep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-express's Issues

There is no way to specify the charset of a response

Using latest version: 0.2.1

Do you want to request a feature or report a bug?
This should really be a bug, but may be thought of as a feature.
What is the current behavior?
response.send(String s) always uses the default charset s.getBytes()
If the current behavior is a bug, please provide the steps to reproduce.
Specify response.setContentType("text/plain; charset=UTF-8");
What is the expected behavior?
That the String is sent using UTF-8 encoding, but the string is sent using the default charset of the javaVM
Please mention your java and java-express version.
0.2.1

Ideally there should be a method on the response for setting the charset and that charset then be used by send. Additionally calling response.contentType(String) should check whether a charset is specified and set it accordingly.

Static files not load and get timeout

I'm trying to access index.html through the static folder at http://localhost: 8080/index.html, but I did not succeed.

try {
    app.use(Middleware.statics(getPublicPath()));
} catch (IOException | URISyntaxException e) {
    e.printStackTrace();
}

My method getPublicPath:

private static String getPublicPath() throws URISyntaxException {
    return new File(WebServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath() + "/public";
}

My config public folder:

.
โ”œโ”€โ”€ Main.class
โ”œโ”€โ”€ animation
โ”‚ย ย  โ”œโ”€โ”€ AnimationImagens$OnAnimationListener.class
โ”‚ย ย  โ””โ”€โ”€ AnimationImagens.class
โ”œโ”€โ”€ controller
โ”‚ย ย  โ””โ”€โ”€ Controller.class
โ”œโ”€โ”€ public
โ”‚ย ย  โ”œโ”€โ”€ css
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ index.css
โ”‚ย ย  โ”œโ”€โ”€ index.html
โ”‚ย ย  โ”œโ”€โ”€ js
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ lib
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ axios.min.js
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ jquery-3.3.1.min.js
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ jquery.inputmask.bundle.min.js
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ primus.io.js
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ simplepeer.min.js
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ socket.io.js
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ primus.io.js
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ webRtc.js
โ”‚ย ย  โ””โ”€โ”€ webRtc.html
โ””โ”€โ”€ web
    โ””โ”€โ”€ WebServer.class

I get timeout in all requests, but i when use:

app.get("/", (req, res) -> {
    try {
        res.send(Paths.get(getPublicPath() + "/index.html"));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
});

I get success and load only html, not js, css

My HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Captive portal</title>
</head>
<body>
    <div class="login-page">
        <div class="form">
            <div id="form">
                <input id="name" type="text" placeholder="nome" />
                <input id="phone" type="text" placeholder="telefone" />
                <button id="login">login</button>
            </div>
            <div id="finish" style="display: none;">
                Aguarde 3 segundos
            </div>
        </div>
    </div>

    <!-- <script src="/js/index.js"></script> -->
</body>
</html>

Websocket support

Hi, this looks like a nice alternative to a lot of bloated Java web frameworks, which is awesome.

I'm browsing through the source code, and it looks like the core implementation relies on the JDK's built-in http server code base com.sun.net.httpserver. Is it possible to either configure Websocket support via java-express? Or can that be achieved by talking to the HttpServer jdk implementation directly?

Thanks!

SessionCookies should be maintained as long as the user returns within MaxAge seconds

Do you want to request a feature or report a bug?
bug
What is the current behavior?
The data of the SessionCookie is lost after MaxAge milliseconds
If the current behavior is a bug, please provide the steps to reproduce.
Set the session cookie middletier with an specific MaxAge. No matter how frequent the page is visited the cookie will change (reset after maxAge milliseconds).
What is the expected behavior?
The cookie should stay the same as long as you comeback within MaxAge seconds.
Please mention your java and java-express version.
version 0.2.1

โœ‹ Looking for maintainer

Last time I actively worked on it is almost a full year ago. I'm not longer working with java and I'm looking for someone new to maintain this project / addressing existing issues which I, considering my limited experience with Java, cannot fix / implement anymore (the last version I worked with was Java 8 which is quite ancient I guess).

Please write a comment below if you're interested.

Nice Framework. Why not post it to Maven central?

If you make this available on maven central, people will be able to include it into their maven builds easily.

As it is, in my maven builds, I must declare a local repo and store the java-express jar file there. This works but it sure would be nice to be able to get the latest version from an externally-hosted maven repo.

Thanks for the framework.

multiplart/form-data handle

I am sending file form client like

<form method="post" enctype="multipart/form-data">
  <input type="file" name="file">
</form>

I have tried with these but not received file.

app.post("/", (req, res) -> {
   req.getFormQuery("file");
});

How do I receive multipart form data for file upload handle?

testability - synchronous version of Express.listen()

Express.listen() spawns a separate thread to instantiate and start underlying HttpServer.
This introduces a race condition if an automated test is trying to execute an http call to the express app right after call to listen().

Workaround:

public void start(int port) {
        System.out.println("Application starting...");
        CountDownLatch latch = new CountDownLatch(1);

        express = new Express();
        //configuration of routes omitted

        express.listen(latch::countDown, port);
        latch.await();
        System.out.println("Application started @ http://localhost:" + getPort()); 
}

I'd prefer not to have to use CountDownLatch.

req.body JSON example

Can you show an example where you would do the Java equivalent of JSON.parse(req.body) in JavaScript?

Async support

How well does this handle async? If there's even any async support

testability - expose access to InetSocketAddress of HttpServer

When running tests on CI/CD, I need to start the application under test on random port with Express.listen(0).
Then I'd like to obtain the actual port number to hand it over to RestAssured (or whatever other rest client)

Proposed addition to express.Express class:

public InetSocketAddress getAddress() {
    return httpServer.getAddress(); 
}

MaxAge for SessionCookies should be treated in seconds

Do you want to request a feature or report a bug?
bug

What is the current behavior?
The value of maxAge for the cookie of the session-cookie is set as is (which will be treated as seconds). But the code treats this value as milli-seconds when cleaning the SessionCookie cache.

If the current behavior is a bug, please provide the steps to reproduce.
Set maxAge to a number of seconds. You will see the browser keep sending the cookie for that amount of time, But the cookie will be lost and a new one created after that amount of milliseconds.

What is the expected behavior?
The middletier should keep the SessionCookie for maxAge*1000

Please mention your java and java-express version.
version 0.2.1

Imeplement maximum request size validation

Overview

We need some sort of measure to prevent attacks based on huge HTTP request payloads.

@simonwep , would you suggest any particular configuration class to implement this feature?

We could probably implement this as a Middleware extension.

HTML5 History API

I were told to ask if java-express supports the HTML5 history API? If not, would it be possible to add it?

Bintray deprecation broke this package

Since 1st May 2021, the bintray website was deprecated. This means this code is not compilable anymore, as it requires a Gradle plugin that was stored at https://dl.bintray.com/vaccovecrana/vacco-oss, which is not working anymore. Besides that, the jcenter() repository was also deprecated, which means it will very soon stop working, too (it is still working, but who knows when it will cease action?). I tried to use jitpack.io instead jcenter(), but it is not working also, because the code is not compiling anymore, and jitpack needs to be able to compile the code in the background to do its magic, and make the package available. Is the code of io.vacco.common-build plugin available elsewhere ? Or should we move to a more standard java-library Gradle plugin ? What is this io.vacco.common-build plugin doing more than java-library ? I was able to compile the package by locally downloading it and changing from the io.vacco.common-build plugin to the more standard java-library. But I don't know if I am losing something in the process ...

Any way to know if a client connection was dropped/closed?

Hi guys

Nice library. Thanks for this. I am wondering if someone can help me with the following this issue.

I am trying to know when a client connection was dropped. But I can't find any way to do it with this java-express. It is based on what's done in Expressjs. So to help you better understand what I'm trying to achieve, please check the following code that can be used as a GET event handler in Expressjs ... I borrowed it from https://alligator.io/nodejs/server-sent-events-build-realtime-app/#sse-express-backend

function eventsHandler(req, res, next) {
  // Mandatory headers and http status to keep connection open
  const headers = {
    'Content-Type': 'text/event-stream',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache'
  };
  res.writeHead(200, headers);

  // After client opens connection send all nests as string
  const data = `data: ${JSON.stringify(nests)}\n\n`;
  res.write(data);

  // Generate an id based on timestamp and save res
  // object of client connection on clients list
  // Later we'll iterate it and send updates to each client
  const clientId = Date.now();
  const newClient = {
    id: clientId,
    res
  };
  clients.push(newClient);

  // When client closes connection we update the clients list
  // avoiding the disconnected one
  req.on('close', () => {
    console.log(`${clientId} Connection closed`);
    clients = clients.filter(c => c.id !== clientId);
  });
}

In this code, please notice the part where we have req.on('close', () => {...}) near the end of the snippet.

This allows listening to events on the request object. It could be a close event, an error event, etc.

I know that the .on() fonction is a Javascript specific function and is probably inherited by the reqobject. But I am hoping that someone could help me achieve the same thing with java-express .

Essentially, I am trying to keep track of each request until they are disconnected. And in the meantime, when I receive a POST request (in my Java code) that will have a channel property in the submitted data, I will send that to all the GET requests that were made with that same channel. I know that clients will stay connected because they are supposed to be using an EventSource() connection to connect to the server, which will in turn a response with a text/event-stream content type.

Thank you

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.