Skip to content

Commit 2f187ad

Browse files
committed
304 supported
1 parent ef6abe4 commit 2f187ad

File tree

16 files changed

+271
-1967
lines changed

16 files changed

+271
-1967
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ src/main/resources/test_cache/*
4242
css
4343
*.dmg
4444
/src/main/resources/static/M3_files/
45+
46+
/Data/Server/*
47+
/Data/Client/*
48+
/Data/Test/*

src/main/java/client/HttpClient.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import exception.InvalidMessageException;
44
import lombok.Getter;
55
import server.HttpResponseMessage;
6+
import util.Config;
7+
import util.HttpMessage;
68
import util.Log;
9+
import util.consts.Headers;
710
import util.consts.WebMethods;
811
import util.packer.MessagePacker;
912
import util.parser.MessageParser;
@@ -13,6 +16,7 @@
1316
import java.net.URLEncoder;
1417
import java.nio.channels.AsynchronousSocketChannel;
1518
import java.nio.charset.StandardCharsets;
19+
import java.nio.file.Path;
1620
import java.util.concurrent.ExecutionException;
1721
import java.util.concurrent.Future;
1822
import java.util.concurrent.TimeoutException;
@@ -44,6 +48,8 @@ public class HttpClient {
4448
@Getter private
4549
String[] headers;
4650

51+
@Getter private
52+
String rawTarget;
4753

4854
public HttpClient(String hostName, int hostPort, boolean longConnection) throws IOException {
4955
this.hostName = hostName;
@@ -105,6 +111,7 @@ HttpResponseMessage request(String method, String target, String param, String b
105111

106112
/* Memorized for status handler */
107113
this.method = method;
114+
this.rawTarget = target;
108115
this.param = param;
109116
this.body = body;
110117
this.headers = headers;
@@ -142,6 +149,8 @@ private HttpResponseMessage request(HttpRequestMessage request) throws IOExcepti
142149

143150
request.addHeader("Host", hostName);
144151

152+
checkCache(request);
153+
145154
MessagePacker packer = new MessagePacker(request, null);
146155
packer.send(aSocket);
147156

@@ -154,6 +163,13 @@ private HttpResponseMessage request(HttpRequestMessage request) throws IOExcepti
154163

155164
Log.logClient("Request complete");
156165

166+
String content_type = hrm.getHeaderVal(Headers.CONTENT_TYPE);
167+
if ( hrm.getStatusCode() != 304
168+
&& content_type != null
169+
&& !content_type.contains(Headers.TEXT_PLAIN)) {
170+
hrm.storeBodyInCache(Config.CLIENT_CACHE, getHostName() + getRawTarget(), content_type);
171+
}
172+
157173
return hrm;
158174
} catch (InvalidMessageException e) {
159175
e.printMsg(aSocket);
@@ -170,4 +186,13 @@ private HttpResponseMessage request(HttpRequestMessage request) throws IOExcepti
170186

171187
return null;
172188
}
189+
190+
private void checkCache(HttpRequestMessage hrm) {
191+
Path path = HttpMessage.getCache(Config.CLIENT_CACHE, getHostName() + getRawTarget());
192+
if (path != null) {
193+
String time = Config.getResourceLastModifiedTime(path);
194+
Log.debug("Cache last modified: ", time);
195+
hrm.addHeader(Headers.IF_MODIFIED_SINCE, time);
196+
}
197+
}
173198
}

src/main/java/client/StatusHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import exception.InvalidMessageException;
44
import server.HttpResponseMessage;
5+
import util.Config;
56
import util.Log;
67
import util.consts.Headers;
78

@@ -89,7 +90,7 @@ private HttpResponseMessage handle302(HttpClient client, HttpResponseMessage msg
8990
* 304 Not Modified
9091
*/
9192
private HttpResponseMessage handle304(HttpClient client, HttpResponseMessage msg) {
92-
// TODO: cached content
93+
msg.loadBodyFromCache(Config.CLIENT_CACHE, client.getHostName() + client.getRawTarget());
9394
return msg;
9495
}
9596
}

src/main/java/server/TargetHandler.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import java.lang.reflect.Field;
44
import java.lang.reflect.InvocationTargetException;
55
import java.lang.reflect.Method;
6+
import java.nio.file.Files;
7+
import java.nio.file.Path;
68
import java.util.Arrays;
9+
import java.util.Date;
710
import java.util.HashMap;
811
import java.util.HashSet;
912
import java.util.Locale;
@@ -15,6 +18,9 @@
1518
import util.Config;
1619
import util.HttpMessage;
1720
import util.Log;
21+
import util.MessageHelper;
22+
import util.consts.Headers;
23+
import util.consts.WebMethods;
1824

1925
/**
2026
* A singleton handler
@@ -105,26 +111,57 @@ public HttpResponseMessage handle(HttpRequestMessage msg) {
105111
target = target.toLowerCase(Locale.ROOT);
106112

107113
if (!targetToMethod.containsKey(target)) {
108-
String path = Config.STATIC_DIR + target;
109-
if (ClassLoader.getSystemClassLoader().getResource(path) == null)
114+
// -------------------- 1. Static Resource -------------------- //
115+
Path path = getResourcePath(target);
116+
117+
Log.debug("Search resource in path: ", path);
118+
119+
if (WebMethods.GET.equals(msg.getMethod())
120+
&& Files.exists(path)
121+
) {
122+
return loadStaticResource(path, msg);
123+
} else {
110124
target = "Missing";
111-
else {
112-
HttpResponseMessage hrm = factory.produce(200);
113-
hrm.setBodyAsFile(path);
114-
return hrm;
115125
}
116126
}
117127

118-
Method method = targetToMethod.get(target);
128+
// -------------------- 2. Matched Target -------------------- //
119129

130+
/* Check method validity */
131+
Method method = targetToMethod.get(target);
120132
if (Arrays.binarySearch(method.getDeclaredAnnotation(Mapping.class).method(), msg.getMethod()) < 0)
121133
return factory.produce(405);
122134

135+
123136
return (HttpResponseMessage) targetToMethod.get(target).invoke(null, msg);
124137

125138
} catch (IllegalAccessException | InvocationTargetException e) {
126139
e.printStackTrace();
127140
return factory.produce(500);
128141
}
129142
}
143+
144+
private Path getResourcePath(String target) {
145+
if (target.endsWith("/"))
146+
target += "index.html";
147+
return Path.of(Config.STATIC_DIR, target);
148+
}
149+
150+
private HttpResponseMessage loadStaticResource(Path path, HttpRequestMessage request) {
151+
Log.debug("Resource found");
152+
153+
if (request.containsHeader(Headers.IF_MODIFIED_SINCE)) {
154+
String time = request.getHeaderVal(Headers.IF_MODIFIED_SINCE);
155+
Date date = MessageHelper.parseTime(time);
156+
assert date != null;
157+
Date myDate = Config.getResourceLastModifiedTimeAsDate(path);
158+
if (myDate.compareTo(date) < 0) {
159+
return factory.produce(304);
160+
}
161+
}
162+
163+
HttpResponseMessage hrm = factory.produce(200);
164+
hrm.setBodyAsFileWithAbsPath(path);
165+
return hrm;
166+
}
130167
}

src/main/java/server/target/Html.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
import util.Config;
77

88
public class Html extends TargetSet {
9-
@Mapping("/lab-m3")
10-
public static HttpResponseMessage labM3(HttpRequestMessage msg) {
11-
HttpResponseMessage hrm = factory.produce(200);
12-
hrm.setBodyAsFile("static_html/M3_ 系统调用 Profiler (sperf).html");
13-
return hrm;
14-
}
15-
16-
@Mapping("/jyy-os")
17-
public static HttpResponseMessage jyyOs(HttpRequestMessage msg) {
18-
HttpResponseMessage hrm = factory.produce(200);
19-
hrm.setBodyAsFile("static_html/test_page_1.html");
20-
return hrm;
21-
}
9+
// @Mapping("/lab-m3")
10+
// public static HttpResponseMessage labM3(HttpRequestMessage msg) {
11+
// HttpResponseMessage hrm = factory.produce(200);
12+
// hrm.setBodyAsFile("M3_ 系统调用 Profiler (sperf).html");
13+
// return hrm;
14+
// }
15+
//
16+
// @Mapping("/jyy-os")
17+
// public static HttpResponseMessage jyyOs(HttpRequestMessage msg) {
18+
// HttpResponseMessage hrm = factory.produce(200);
19+
// hrm.setBodyAsFile("test_page_1.html");
20+
// return hrm;
21+
// }
2222
}

src/main/java/util/Config.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ public class Config {
2222
public final static String TARGET_PATH = "target_path.json";
2323
public final static String MIME = "mime.json";
2424

25-
public static final String STATIC_DIR = "static";
26-
public final static String CLIENT_CACHE = "client_cache";
27-
public final static String SERVER_CACHE = "server_cache";
28-
public final static String TEST_CACHE = "test_cache";
25+
public static final String DATA_DIR;
26+
static {
27+
DATA_DIR = System.getProperty("user.dir") + "/Data";
28+
}
29+
public static final String CLIENT_PATH = DATA_DIR + "/Client";
30+
public static final String SERVER_PATH = DATA_DIR + "/Server";
31+
public static final String TEST_PATH = DATA_DIR + "/Test";
32+
33+
public final static String STATIC_DIR = SERVER_PATH + "/Static";
34+
public final static String CLIENT_CACHE = CLIENT_PATH + "/Cache";
35+
public final static String SERVER_CACHE = SERVER_PATH + "/Cache";
36+
public final static String TEST_CACHE = TEST_PATH + "/Cache";
2937

3038
public final static int GZIP_THRESHOLD = (1 << 20); // 1MB
3139

@@ -47,6 +55,11 @@ private static Path getPath(String resource) {
4755

4856
public static long getSizeOfResource(String resource) {
4957
Path path = getPath(resource);
58+
assert path != null;
59+
return getSizeOfResource(path);
60+
}
61+
62+
public static long getSizeOfResource(Path path) {
5063
assert path != null;
5164
try {
5265
return Files.size(path);
@@ -100,6 +113,10 @@ public static JSONObject getConfigAsJsonObj(String config) {
100113
);
101114
}
102115

116+
public static Path getClientCacheDir() {
117+
return getPath(Config.CLIENT_CACHE);
118+
}
119+
103120
public static String getResourceLastModifiedTime(String resource) {
104121
FileTime ft = Config.getResourceFileTime(resource);
105122
if (ft != null)
@@ -108,9 +125,25 @@ public static String getResourceLastModifiedTime(String resource) {
108125
return "Error";
109126
}
110127

128+
public static Date getResourceLastModifiedTimeAsDate(Path path) {
129+
FileTime ft = Config.getResourceFileTime(path);
130+
assert ft != null;
131+
return new Date(ft.toMillis());
132+
}
133+
134+
public static String getResourceLastModifiedTime(Path path) {
135+
return MessageHelper.getTime(
136+
getResourceLastModifiedTimeAsDate(path)
137+
);
138+
}
139+
111140
public static FileTime getResourceFileTime(String resource) {
112141
Path path = getPath(resource);
113142
assert path != null;
143+
return getResourceFileTime(path);
144+
}
145+
146+
public static FileTime getResourceFileTime(Path path) {
114147
try {
115148
return Files.getLastModifiedTime(path);
116149
} catch (IOException e) {

0 commit comments

Comments
 (0)