Skip to content
This repository was archived by the owner on Jul 31, 2022. It is now read-only.

Added Throttled Handler #39

Merged
merged 9 commits into from
May 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public synchronized String assignSessionID(final HttpExchange exchange){
* Returns the session of the client or assigns one if it does not yet have one Session will only be saved client side if the exchange headers are sent using {@link HttpExchange#sendResponseHeaders(int, long)}.
*
* @param exchange http exchange
* @return session associated with the exchange
*
* @since 03.03.00
* @author Ktt Development
Expand Down Expand Up @@ -136,6 +137,7 @@ public final String toString(){
.setHttpOnly(true)
.build();
exchange.getResponseHeaders().add("Set-Cookie",out.toCookieHeaderString());
sessions.put(sessionId,session);
}else{
session = sessions.get(sessionId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,17 @@ public final String toCookieHeaderString(){
final StringBuilder OUT = new StringBuilder();
OUT.append(name).append("=").append(value);
if(expires != null)
OUT.append("; Expires=").append(new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss").format(expires)).append(" GMT");
OUT.append("; Expires=").append(sdf.format(expires)).append(" GMT");
if(maxAge != null)
OUT.append("; Max-Age=").append(maxAge);
if(domain != null)
OUT.append("; Domain=").append(domain);
if(path != null)
OUT.append("; Path=").append(path);
if(secure != null && secure)
OUT.append("; Secure=").append(secure);
OUT.append("; Secure=").append(true);
if(httpOnly != null && httpOnly)
OUT.append("; HttpOnly=").append(httpOnly);
OUT.append("; HttpOnly=").append(true);
if(sameSite != null)
OUT.append("; SameSite=").append(sameSite);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.kttdevelopment.simplehttpserver.handler;

import com.sun.net.httpserver.HttpExchange;

/**
* Determines how connections are handled by the {@link ThrottledHandler}.
*
* @see ServerThrottler
* @see SessionThrottler
* @since 03.03.00
* @version 03.03.00
* @author Ktt Development
*/
abstract class ConnectionThrottler {

/**
* Adds a connection to the pool.
*
* @param exchange exchange to process
* @return if exchange was able to be added
*
* @see #deleteConnection(HttpExchange)
* @since 03.03.00
* @author Ktt Development
*/
abstract boolean addConnection(final HttpExchange exchange);

/**
* Removes a connection from the pool.
*
* @param exchange exchange to process
*
* @see #addConnection(HttpExchange)
* @since 03.03.00
* @author Ktt Development
*/
abstract void deleteConnection(final HttpExchange exchange);

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
* @version 02.00.00
* @author Ktt Development
*/
@SuppressWarnings("SpellCheckingInspection")
class DirectoryEntry {

private final boolean isWalkthrough;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public final void handle(final SimpleHttpExchange exchange) throws IOException{

//


@SuppressWarnings("StringBufferReplaceableByString")
@Override
public String toString(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* A SSE handler allows server to client events by using an <code>text/event-stream</code>. Events are sent using {@link #push(String)} or {@link #push(String, int, String)}.
*
* @see SimpleHttpHandler
* @since 03.01.00
* @version 03.03.00
* @author Ktt Development
*/
public class SSEHandler implements SimpleHttpHandler {

private final List<OutputStream> listeners = new ArrayList<>();
Expand Down Expand Up @@ -48,10 +56,30 @@ public final void handle(final SimpleHttpExchange exchange) throws IOException{
listeners.add(exchange.getOutputStream());
}

/**
* Pushes an event to the stream.
*
* @param data data to send
*
* @see #push(String, int, String)
* @since 03.01.00
* @author Ktt Development
*/
public synchronized final void push(final String data){
push(data,0,"");
}

/**
* Pushes an event to the stream.
*
* @param data data to send
* @param retry how long to retry for
* @param event event type
*
* @see #push(String)
* @since 03.01.00
* @author Ktt Development
*/
public synchronized final void push(final String data, final int retry, final String event){
eventId.addAndGet(1);
final EventStreamRecord record = new EventStreamRecord(retry,event,data);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package com.kttdevelopment.simplehttpserver.handler;

import com.sun.net.httpserver.HttpExchange;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

/**
* Limits connections for the server.
*
* @see ThrottledHandler
* @see SessionThrottler
* @since 03.03.00
* @version 03.03.00
* @author Ktt Development
*/
public class ServerThrottler extends ConnectionThrottler {

private final Predicate<HttpExchange> countsTowardsLimit;
private final AtomicInteger connections = new AtomicInteger(0);

private final AtomicInteger maxConnections = new AtomicInteger(0);

/**
* Creates a throttler that allows no connections.
*
* @since 03.03.00
* @author Ktt Development
*/
public ServerThrottler(){
countsTowardsLimit = exchange -> true;
}

/**
* Creates a throttler that allows a certain amount of simultaneous connections.
*
* @param maxConnections maximum simultaneous connections
*
* @since 03.03.00
* @author Ktt Development
*/
public ServerThrottler(final int maxConnections){
countsTowardsLimit = exchange -> true;
this.maxConnections.set(maxConnections);
}

/**
* Creates a throttler that allows a certain amount of simultaneous connections and exempt connections.
*
* @param countsTowardsLimit determines which exchanges count towards the connection limit
*
* @since 03.03.00
* @author Ktt Development
*/
public ServerThrottler(final Predicate<HttpExchange> countsTowardsLimit){
this.countsTowardsLimit = countsTowardsLimit;
}

/**
* Creates a throttler that allows a certain amount of simultaneous connections and exempt connections.
*
* @param countsTowardsLimit determines which exchanges count towards the connection limit
* @param maxConnections maximum simultaneous connections
*
* @since 03.03.00
* @author Ktt Development
*/
public ServerThrottler(final Predicate<HttpExchange> countsTowardsLimit, final int maxConnections){
this.countsTowardsLimit = countsTowardsLimit;
this.maxConnections.set(maxConnections);
}

/**
* Returns the maximum allowed connections.
*
* @return maximum allowed connections
*
* @see #setMaxConnections(int)
* @since 03.03.00
* @author Ktt Development
*/
public final int getMaxConnections(){
return maxConnections.get();
}

/**
* Sets the maximum allowed connections. Must be a positive number.
*
* @param maxConnections maximum allowed connections
*
* @see #getMaxConnections()
* @since 03.03.00
* @author Ktt Development
*/
public synchronized final void setMaxConnections(final int maxConnections){
if(maxConnections >= 0)
this.maxConnections.set(maxConnections);
}

final boolean addConnection(final HttpExchange exchange){
if(!countsTowardsLimit.test(exchange)){
return true;
}else{
synchronized(this){
if(connections.get() + 1 <= maxConnections.get()){
connections.incrementAndGet();
return true;
}
}
}
return false;
}

final void deleteConnection(final HttpExchange exchange){
if(countsTowardsLimit.test(exchange))
synchronized(this){
connections.decrementAndGet();
}
}

//

@SuppressWarnings("StringBufferReplaceableByString")
@Override
public String toString(){
final StringBuilder OUT = new StringBuilder();

OUT.append("ConnectionThrottler") .append('{');
OUT.append("condition") .append('=') .append(countsTowardsLimit) .append(", ");
OUT.append("connections") .append('=') .append(connections.get()) .append(", ");
OUT.append("maxConnections") .append('=') .append(maxConnections.get());
OUT.append('}');

return OUT.toString();
}

}
Loading