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

Moved HttpSession to server; SimpleHttpHandler changed to interface. #37

Merged
merged 10 commits into from
May 5, 2020
15 changes: 0 additions & 15 deletions src/main/java/com/kttdevelopment/simplehttpserver/HttpSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,11 @@ public abstract class HttpSession {
/**
* Creates an empty {@link HttpSession}. Applications don't use this method.
*
* @see HttpSessionImpl#createHttpSession()
* @since 02.00.00
* @author Ktt Development
*/
HttpSession(){ }

//

/**
* Creates a {@link HttpSession}.
*
* @return a {@link HttpSession}
*
* @since 02.00.00
* @author Ktt Development
*/
synchronized static HttpSession create(){
return HttpSessionImpl.createHttpSession();
}

//

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

import com.sun.net.httpserver.HttpExchange;

import java.util.*;

/**
* This class assigns {@link HttpSession} to every client.
*
* @since 03.03.00
* @version 03.03.00
* @author Ktt Development
*/
public class HttpSessionHandler {

private final Map<String,HttpSession> sessions = new HashMap<>();

private final String cookie;

/**
* Creates a session handler using the cookie <code>__session-id</code>.
*
* @since 03.03.00
* @author Ktt Development
*/
public HttpSessionHandler(){
cookie = "__session-id";
}

/**
* Creates a session handler, storing the id at the specified cookie.
*
* @param cookie cookie to store session id
*
* @since 03.03.00
* @author Ktt Development
*/
public HttpSessionHandler(final String cookie){
this.cookie = cookie;
}

/**
* Assigns a session id to a client. It is important to make sure duplicate ids do not occur.
*
* @param exchange http exchange
* @return session id
*
* @since 03.03.00
* @author Ktt Development
*/
public synchronized String assignSessionID(final HttpExchange exchange){
String id;
do id = UUID.randomUUID().toString();
while(sessions.containsKey(id));
return id;
}

/**
* 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
*
* @since 03.03.00
* @author Ktt Development
*/
public final HttpSession getSession(final HttpExchange exchange){
final String sessionId;
final HttpSession session;

final String rcookies = exchange.getRequestHeaders().getFirst("Cookie");
final Map<String,String> cookies = new HashMap<>();

if(rcookies != null && !rcookies.isEmpty()){
final String[] pairs = rcookies.split("; ");
for(final String pair : pairs){
final String[] value = pair.split("=");
cookies.put(value[0],value[1]);
}
}

if((sessionId = cookies.get(cookie)) == null || !sessions.containsKey(sessionId)){
session = new HttpSession() {

private final String sessionID;
private final long creationTime;
private long lastAccessTime;

{
sessionID = assignSessionID(exchange);
creationTime = System.currentTimeMillis();
lastAccessTime = creationTime;
sessions.put(sessionID,this);
}

@Override
public final String getSessionID(){
return sessionID;
}

//

@Override
public final long getCreationTime(){
return creationTime;
}

@Override
public final long getLastAccessTime(){
return lastAccessTime;
}

@Override
public synchronized final void updateLastAccessTime(){
lastAccessTime = System.currentTimeMillis();
}

//

@SuppressWarnings("StringBufferReplaceableByString")
@Override
public final String toString(){
final StringBuilder OUT = new StringBuilder();
OUT.append("HttpSession") .append("{");
OUT.append("sessionID") .append("=") .append(sessionID) .append(", ");
OUT.append("creationTime") .append("=") .append(creationTime) .append(", ");
OUT.append("lastAccessTime").append("=") .append(lastAccessTime);
OUT.append("}");
return OUT.toString();
}

};

final SimpleHttpCookie out =
new SimpleHttpCookie.Builder(cookie,session.getSessionID())
.setPath("/")
.setHttpOnly(true)
.build();
exchange.getResponseHeaders().add("Set-Cookie",out.toCookieHeaderString());
}else{
session = sessions.get(sessionId);
}
return session;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -346,19 +346,6 @@ static SimpleHttpExchange create(final HttpExchange exchange){
*/
public abstract void setCookie(final SimpleHttpCookie cookie);

//

/**
* Returns the http session of the exchange if one exists; if one does not exist it will create one. <b>A new session will only persist if the exchange is sent.</b>
*
* @return http session
*
* @see HttpSession
* @since 02.00.00
* @author Ktt Development
*/
public abstract HttpSession getHttpSession();

//

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,32 +317,11 @@ public synchronized final void setCookie(final String key, final String value){
@Override
public synchronized final void setCookie(final SimpleHttpCookie cookie){
final String cstring = cookie.toCookieHeaderString();
if(cstring.startsWith("__session-id="))
throw new IllegalArgumentException("The cookie '__session-id' can not be set because it is reserved by the server");
getResponseHeaders().add("Set-Cookie",cstring);
}

//

@Override
public synchronized final HttpSession getHttpSession(){
final String sessionId;
final HttpSession session;

if((sessionId = cookies.get("__session-id")) == null || !HttpSession.sessions.containsKey(sessionId)){
session = HttpSession.create();
final SimpleHttpCookie cookie =
new SimpleHttpCookie.Builder("__session-id",session.getSessionID())
.setPath("/")
.setHttpOnly(true)
.build();
getResponseHeaders().add("Set-Cookie",cookie.toCookieHeaderString()); // bypass implementation
}else{
session = HttpSession.sessions.get(sessionId);
}
return session;
}


@Override
public final OutputStream getOutputStream(){
return outputStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,23 @@
* @version 03.03.00
* @author Ktt Development
*/
public interface SimpleHttpHandler {
/*

public interface SimpleHttpHandler extends HttpHandler {

/**
* Encapsulates the {@link #handle(SimpleHttpExchange)} for the authenticator. Applications do not use this.
* Encapsulates the {@link #handle(SimpleHttpExchange)} for the authenticator. This method is reserved by the server; <b>do not override this</b>, it will break the {@link #handle(SimpleHttpExchange)} method.
*
* @param exchange client information
* @throws IOException internal failure
*
* @since 02.00.00
* @author Ktt Development
/
*/
@Override
default final void handle(final HttpExchange exchange) throws IOException{
final SimpleHttpExchange sxe = SimpleHttpExchange.create(exchange);
if(authenticate(sxe))
handle(sxe);
else
sxe.close();
default void handle(final HttpExchange exchange) throws IOException{
handle(SimpleHttpExchange.create(exchange));
}
*/

/**
* Handlers the given request and generates a response <b>if no exceptions occur</b>.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ public static SimpleHttpServer create(final int port, final int backlog) throws
*/
public abstract Executor getExecutor();

//

public abstract void setHttpSessionHandler(final HttpSessionHandler sessionHandler);

public abstract HttpSessionHandler getHttpSessionHandler();

public abstract HttpSession getHttpSession(final HttpExchange exchange);

//

/**
Expand All @@ -221,7 +229,6 @@ public static SimpleHttpServer create(final int port, final int backlog) throws
*
* @see HttpContext
* @see #createContext(String, HttpHandler)
* @see #createContext(String, SimpleHttpHandler)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 02.00.00
Expand All @@ -241,34 +248,13 @@ public static SimpleHttpServer create(final int port, final int backlog) throws
* @see HttpContext
* @see HttpHandler
* @see #createContext(String)
* @see #createContext(String, SimpleHttpHandler)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 02.00.00
* @author Ktt Development
*/
public abstract HttpContext createContext(final String context, final HttpHandler handler);

/**
* Creates a context mapped to a specific {@link HttpHandler}.
*
* @param context the context
* @param handler the handler
* @return the http context associated with the context
* @throws IllegalArgumentException if the context is invalid or taken
* @throws NullPointerException if the context is null
*
* @see HttpContext
* @see SimpleHttpHandler
* @see #createContext(String)
* @see #createContext(String, HttpHandler)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 03.03.00
* @author Ktt Development
*/
public abstract HttpContext createContext(final String context, final SimpleHttpHandler handler);

//

/**
Expand All @@ -283,7 +269,6 @@ public static SimpleHttpServer create(final int port, final int backlog) throws
* @see HttpContext
* @see Authenticator
* @see #createContext(String, HttpHandler, Authenticator)
* @see #createContext(String, SimpleHttpHandler, Authenticator)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 03.03.00
Expand All @@ -305,36 +290,13 @@ public static SimpleHttpServer create(final int port, final int backlog) throws
* @see HttpHandler
* @see Authenticator
* @see #createContext(String, Authenticator)
* @see #createContext(String, SimpleHttpHandler, Authenticator)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 03.03.00
* @author Ktt Development
*/
public abstract HttpContext createContext(final String context, final HttpHandler handler, final Authenticator authenticator);

/**
* Creates a context mapped to a specific {@link HttpContext} with an {@link Authenticator}.
*
* @param context the context
* @param handler the handler
* @param authenticator authenticator
* @return the http context associated with the context
* @throws IllegalArgumentException if the context is invalid or taken
* @throws NullPointerException if the context is null
*
* @see HttpContext
* @see SimpleHttpHandler
* @see Authenticator
* @see #createContext(String, Authenticator)
* @see #createContext(String, HttpHandler, Authenticator)
* @see #removeContext(String)
* @see #removeContext(HttpContext)
* @since 03.03.00
* @author Ktt Development
*/
public abstract HttpContext createContext(final String context, final SimpleHttpHandler handler, final Authenticator authenticator);

//

/**
Expand Down
Loading