Skip to content
This repository was archived by the owner on May 10, 2024. It is now read-only.

Commit 9b900bd

Browse files
committed
server and handlers
1 parent 8e00b8e commit 9b900bd

34 files changed

+2990
-2
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<br>
2424

2525
> **Warning**
26-
>
2726
> simplehttpserver5 is not compatible with any previous version of [simplehttpserver](https://github.com/Ktt-Development/simplehttpserver)
2827
2928
🚧 WIP
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
import java.util.regex.Pattern;
22+
23+
abstract class ContextUtility {
24+
25+
// replace consecutive slashes and back slashes with a single forward slash
26+
@SuppressWarnings("RegExpRedundantEscape")
27+
private static final Pattern forwardSlash = Pattern.compile("\\/{2,}|\\\\+");
28+
// trim start and end slashes as well as whitespace
29+
@SuppressWarnings("RegExpRedundantEscape")
30+
private static final Pattern trimSlash = Pattern.compile("^\\s*\\/*|\\/*\\s*$");
31+
32+
static String getContext(final String context, final boolean leading, final boolean trailing){
33+
final String linSlash = forwardSlash.matcher(context).replaceAll("/");
34+
final String strippedSlash = trimSlash.matcher(linSlash).replaceAll("");
35+
return strippedSlash.length() == 0
36+
? leading || trailing ? "/" : ""
37+
: (leading ? "/" : "") + strippedSlash + (trailing ? "/" : "");
38+
}
39+
40+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
import java.nio.charset.StandardCharsets;
22+
import java.util.*;
23+
24+
public class FileRecord extends Record {
25+
26+
final String fileName, contentType;
27+
private final byte[] bytes;
28+
29+
FileRecord(final Map.Entry<String,Map<String,?>> entry){
30+
super(entry);
31+
32+
fileName = Objects.requireNonNull(Objects.requireNonNull(getHeader("Content-Disposition").getParameter("filename")));
33+
contentType = Objects.requireNonNull(Objects.requireNonNull(getHeader("Content-Type")).getValue());
34+
bytes = getValue().getBytes(StandardCharsets.UTF_8);
35+
}
36+
37+
public final String getFileName(){
38+
return fileName;
39+
}
40+
41+
public final String getContentType(){
42+
return contentType;
43+
}
44+
45+
public final byte[] getBytes(){
46+
return Arrays.copyOf(bytes, bytes.length);
47+
}
48+
49+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
import com.sun.net.httpserver.*;
22+
23+
import java.io.IOException;
24+
import java.net.InetSocketAddress;
25+
import java.util.Map;
26+
27+
interface HttpServerExtensions {
28+
29+
InetSocketAddress bind(final int port) throws IOException;
30+
31+
InetSocketAddress bind(final int port, final int backlog) throws IOException;
32+
33+
//
34+
35+
void setSessionHandler(final HttpSessionHandler sessionHandler);
36+
37+
HttpSessionHandler getSessionHandler();
38+
39+
HttpSession getSession(final HttpExchange exchange);
40+
41+
//
42+
43+
HttpHandler getContextHandler(final String context);
44+
45+
HttpHandler getContextHandler(final HttpContext context);
46+
47+
Map<HttpContext,HttpHandler> getContexts();
48+
49+
String getRandomContext();
50+
51+
String getRandomContext(final String context);
52+
53+
//
54+
55+
void stop();
56+
57+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
public abstract class HttpSession {
22+
23+
HttpSession(){ }
24+
25+
public abstract String getSessionID();
26+
27+
public abstract long getCreationTime();
28+
29+
public abstract long getLastAccessed();
30+
31+
public abstract void update();
32+
33+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
import com.sun.net.httpserver.Headers;
22+
import com.sun.net.httpserver.HttpExchange;
23+
24+
import java.net.HttpCookie;
25+
import java.util.*;
26+
27+
public class HttpSessionHandler {
28+
29+
private final Map<String,HttpSession> sessions = Collections.synchronizedMap(new HashMap<>());
30+
31+
private final String cookie;
32+
33+
public HttpSessionHandler(){
34+
this("__session-id");
35+
}
36+
37+
public HttpSessionHandler(final String cookie){
38+
this.cookie = cookie;
39+
}
40+
41+
public synchronized String assignSessionID(final HttpExchange exchange){
42+
String id;
43+
do id = UUID.randomUUID().toString();
44+
while(sessions.containsKey(id));
45+
return id;
46+
}
47+
48+
private String getSetSession(final Headers headers){
49+
if(headers.containsKey("Set-Cookie"))
50+
for(final String value : headers.get("Set-Cookie"))
51+
if(value.startsWith(cookie + "="))
52+
return value.substring(cookie.length() + 1, value.indexOf(";"));
53+
return null;
54+
}
55+
56+
public final HttpSession getSession(final HttpExchange exchange){
57+
final String sessionId;
58+
final HttpSession session;
59+
60+
@SuppressWarnings("SpellCheckingInspection")
61+
final String rcookies = exchange.getRequestHeaders().getFirst("Cookie");
62+
final Map<String,String> cookies = new HashMap<>();
63+
64+
if(rcookies != null && !rcookies.isEmpty()){
65+
final String[] pairs = rcookies.split("; ");
66+
for(final String pair : pairs){
67+
final String[] value = pair.split("=");
68+
cookies.put(value[0], value[1]);
69+
}
70+
}
71+
72+
final String setSession = getSetSession(exchange.getResponseHeaders());
73+
sessionId = setSession != null ? setSession : cookies.get(cookie);
74+
75+
synchronized(this){
76+
if(!sessions.containsKey(sessionId)){
77+
session = new HttpSession() {
78+
private final String sessionID;
79+
private final long creationTime;
80+
private long lastAccessTime;
81+
82+
{
83+
sessionID = assignSessionID(exchange);
84+
creationTime = System.currentTimeMillis();
85+
lastAccessTime = creationTime;
86+
sessions.put(sessionID, this);
87+
}
88+
89+
@Override
90+
public final String getSessionID(){
91+
return sessionID;
92+
}
93+
94+
//
95+
96+
@Override
97+
public final long getCreationTime(){
98+
return creationTime;
99+
}
100+
101+
@Override
102+
public final long getLastAccessed(){
103+
return lastAccessTime;
104+
}
105+
106+
@Override
107+
public synchronized final void update(){
108+
lastAccessTime = System.currentTimeMillis();
109+
}
110+
111+
};
112+
113+
final HttpCookie OUT = new HttpCookie(cookie, session.getSessionID());
114+
OUT.setPath("/");
115+
OUT.setHttpOnly(true);
116+
117+
exchange.getResponseHeaders().add("Set-Cookie", OUT.toString());
118+
sessions.put(session.getSessionID(), session);
119+
}else{
120+
session = sessions.get(sessionId);
121+
}
122+
}
123+
return session;
124+
}
125+
126+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2022 Katsute <https://github.com/Katsute>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*/
18+
19+
package dev.katsute.simplehttpserver;
20+
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
public class MultipartFormData {
25+
26+
private final Map<String,Record> data;
27+
28+
MultipartFormData(final Map<String,Record> data){
29+
this.data = new HashMap<>(data);
30+
}
31+
32+
public final Record getEntry(final String name){
33+
return data.get(name);
34+
}
35+
36+
public final Map<String,Record> getEntries(){
37+
return new HashMap<>(data);
38+
}
39+
40+
}

0 commit comments

Comments
 (0)