Skip to content

Commit a3e113d

Browse files
committed
Server Driver completed
1 parent 190afe1 commit a3e113d

File tree

9 files changed

+123
-75
lines changed

9 files changed

+123
-75
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
# HTTP Client/Server for Java
22

33
由Java Socket API实现的简单HTTP Client与Http Server
4+
5+
## 1. 概览
6+
7+

src/main/java/client/ClientDriver.java

Lines changed: 8 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package client;
22

3+
import exception.InvalidCommandException;
34
import message.consts.WebMethods;
5+
import util.ArgIterator;
46

57
import java.net.URI;
68
import java.util.ArrayList;
@@ -21,7 +23,7 @@ public class ClientDriver {
2123
The default value of the port number is 80.
2224
Only support HTTP protocol (not HTTPS).
2325
24-
OPTIONS
26+
OPTIONS
2527
-m <METHOD> Send with the specified web method.
2628
Only supports GET and POST.
2729
The default value is GET.
@@ -35,55 +37,9 @@ Only support HTTP protocol (not HTTPS).
3537
e.g.: User-Agent:AbaAba/0.1
3638
""";
3739

38-
private static class InvalidCommandException extends Exception {
39-
public InvalidCommandException(String message) {
40-
super(message);
41-
}
42-
}
43-
44-
private static class ArgIterator {
45-
private final
46-
String[] args;
47-
private
48-
int idx;
49-
50-
public ArgIterator(String[] args) {
51-
this.args = args;
52-
this.idx = 0;
53-
for (String first; (first = peek()) != null && !first.startsWith("http://"); )
54-
next();
55-
56-
}
57-
58-
public boolean hasNext() {
59-
return idx < args.length;
60-
}
61-
62-
public String peek() {
63-
if (hasNext())
64-
return args[idx];
65-
else
66-
return null;
67-
}
68-
69-
public String next() {
70-
if (hasNext())
71-
return args[idx++];
72-
else
73-
return null;
74-
}
75-
76-
public String[] nextValues() {
77-
ArrayList<String> as = new ArrayList<>();
78-
for (String token; (token = peek()) != null && !token.startsWith("-"); next())
79-
as.add(token);
80-
return as.toArray(new String[0]);
81-
}
82-
}
83-
8440
public static void main(String[] args) {
8541
try {
86-
ArgIterator ai = new ArgIterator(args);
42+
ArgIterator ai = new ArgIterator(args, "http://");
8743

8844
String raw = ai.next();
8945
if (raw == null || raw.startsWith("-"))
@@ -92,12 +48,8 @@ public static void main(String[] args) {
9248
URI u = new URI(raw);
9349

9450
String hostName = u.getHost();
95-
String query = u.getQuery();
9651
int port = u.getPort();
97-
String path = u.getPath();
98-
9952
if (port == -1) port = 80;
100-
if (path == null || path.length() == 0) path = "/";
10153

10254
String method = WebMethods.GET;
10355
boolean keepAlive = false;
@@ -116,21 +68,13 @@ public static void main(String[] args) {
11668
|| WebMethods.POST.equals(method);
11769
}
11870

119-
case "--keep-alive" -> {
120-
keepAlive = true;
121-
}
71+
case "--keep-alive" -> keepAlive = true;
12272

123-
case "-b" -> {
124-
body = ai.next();
125-
}
73+
case "-b" -> body = ai.next();
12674

127-
case "-h" -> {
128-
headers = ai.nextValues();
129-
}
75+
case "-h" -> headers = ai.nextValues();
13076

131-
default -> {
132-
throw new InvalidCommandException("Invalid token at \"%s\"".formatted(opt));
133-
}
77+
default -> throw new InvalidCommandException("Invalid token at \"%s\"".formatted(opt));
13478
}
13579
}
13680

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package exception;
2+
3+
public class InvalidCommandException extends Exception {
4+
public InvalidCommandException(String message) {
5+
super(message);
6+
}
7+
}

src/main/java/message/HttpMessage.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public void setBodyAsPlainText(String body) {
201201
setBodyWithType(body, "%s; %s".formatted(TEXT_PLAIN, CHARSET_UTF8));
202202
}
203203

204-
private void setBodyAsFile(String path, String time, long fileSize, InputStream stream) {
204+
private void setBodyAsFile(String path, long fileSize, InputStream stream) {
205205
String[] a = path.split("\\.");
206206
String suffix = a[a.length - 1];
207207
MediaType mediaType = suffixToMime.getOrDefault(suffix, suffixToMime.get("default"));
@@ -223,7 +223,9 @@ private void setBodyAsFile(String path, String time, long fileSize, InputStream
223223
size = "%.2fKB".formatted((double) fileSize / (1 << 10));
224224
}
225225

226-
Log.logPrompt("File packed: ", "[%s][%s][Last modified: %s]".formatted(path, size, time));
226+
String pathS = path.replace(Config.USER_DIR, ".");
227+
228+
Log.logPrompt("File packed", "[%s][%s]".formatted(pathS, size));
227229

228230
setBodyType(type);
229231
setBody(stream, fileSize);
@@ -235,7 +237,7 @@ public void setBodyAsFileWithAbsPath(Path path) {
235237
long fileSize = Config.getSizeOfResource(path);
236238
InputStream stream = Files.newInputStream(path);
237239

238-
setBodyAsFile(path.toString(), time, fileSize, stream);
240+
setBodyAsFile(path.toString(), fileSize, stream);
239241
} catch (IOException e) {
240242
e.printStackTrace();
241243
Log.debug("Setting failed!");

src/main/java/server/HttpServer.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
import static message.consts.Headers.KEEP_ALIVE;
2828

2929
public class HttpServer {
30-
private final static boolean DEFAULT_KEEP_ALIVE = false;
31-
private final static int DEFAULT_TIMEOUT = 10000;
3230

3331
private final AsynchronousServerSocketChannel aServerSocket;
3432
private final TargetHandler handler;
@@ -66,7 +64,7 @@ public HttpServer() throws IOException {
6664
* @param timeOut timeout for long connection
6765
*/
6866
public void launch(boolean keepAlive, int timeOut) {
69-
Log.logServer("The server is starting up....");
67+
Log.logServer("The server is now running");
7068

7169
try {
7270
while (true) {
@@ -97,7 +95,7 @@ public void failed(Throwable exc, Object attachment) {
9795
* Long connection is disabled by default
9896
*/
9997
public void launch() {
100-
launch(DEFAULT_KEEP_ALIVE, DEFAULT_TIMEOUT);
98+
launch(Config.DEFAULT_KEEP_ALIVE, Config.DEFAULT_TIMEOUT);
10199
}
102100

103101
/**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,54 @@
11
package server;
22

3+
import exception.InvalidCommandException;
4+
import util.ArgIterator;
5+
import util.Config;
6+
7+
import java.io.IOException;
8+
39
public class ServerDriver {
10+
public static final String HELP = """
11+
SYNOPSIS
12+
~ [-p <PORT>] [--keep-alive]
13+
[-t <TIMEOUT>]
14+
15+
OPTIONS
16+
-p <PORT> Set up the server with the specified port number.
17+
The default value is 8080
18+
19+
--keep-alive Enable keep-alive.
20+
21+
-t <TIMEOUT> Socket timeout.
22+
The default value is 10000
23+
""";
24+
425
public static void main(String[] args) {
26+
try {
27+
ArgIterator ai = new ArgIterator(args, "-");
28+
29+
int port = 8080;
30+
boolean keepAlive = Config.DEFAULT_KEEP_ALIVE;
31+
int timeout = Config.DEFAULT_TIMEOUT;
32+
33+
while (ai.hasNext()) {
34+
String opt = ai.next();
35+
switch (opt) {
36+
case "-p" -> port = Integer.parseInt(ai.next());
37+
case "--keep-alive" -> keepAlive = true;
38+
case "-t" -> timeout = Integer.parseInt(ai.next());
39+
default -> throw new InvalidCommandException("Invalid token at \"%s\"".formatted(opt));
40+
}
41+
}
42+
43+
HttpServer server = new HttpServer("127.0.0.1", port);
44+
server.launch(keepAlive, timeout);
545

46+
} catch (InvalidCommandException e) {
47+
System.err.println("Error: " + e.getMessage());
48+
} catch (Exception e) {
49+
e.printStackTrace();
50+
} finally {
51+
System.err.println(HELP);
52+
}
653
}
754
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package util;
2+
3+
import java.util.ArrayList;
4+
5+
public class ArgIterator {
6+
private final
7+
String[] args;
8+
private
9+
int idx;
10+
11+
public ArgIterator(String[] args, String prefix) {
12+
this.args = args;
13+
this.idx = 0;
14+
for (String first; (first = peek()) != null && !first.startsWith(prefix); )
15+
next();
16+
17+
}
18+
19+
public boolean hasNext() {
20+
return idx < args.length;
21+
}
22+
23+
public String peek() {
24+
if (hasNext())
25+
return args[idx];
26+
else
27+
return null;
28+
}
29+
30+
public String next() {
31+
if (hasNext())
32+
return args[idx++];
33+
else
34+
return null;
35+
}
36+
37+
public String[] nextValues() {
38+
ArrayList<String> as = new ArrayList<>();
39+
for (String token; (token = peek()) != null && !token.startsWith("-"); next())
40+
as.add(token);
41+
return as.toArray(new String[0]);
42+
}
43+
}

src/main/java/util/Config.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ public class Config {
2323
public final static String TARGET_PATH = "target_path.json";
2424
public final static String MIME = "mime.json";
2525

26-
public static final String DATA_DIR;
26+
public static final String USER_DIR;
2727
static {
28-
DATA_DIR = System.getProperty("user.dir") + "/Data";
28+
USER_DIR = System.getProperty("user.dir");
2929
}
30+
public static final String DATA_DIR = USER_DIR + "/Data";
3031
public static final String CLIENT_PATH = DATA_DIR + "/Client";
3132
public static final String SERVER_PATH = DATA_DIR + "/Server";
3233
public static final String TEST_PATH = DATA_DIR + "/Test";
@@ -42,7 +43,9 @@ public class Config {
4243

4344
public final static String[] TRANSFER_ENCODINGS = { CHUNKED };
4445

45-
public final static int SOCKET_BUFFER_SIZE = 1 << 10;
46+
public final static int DEFAULT_TIMEOUT = 10000;
47+
public final static boolean DEFAULT_KEEP_ALIVE = false;
48+
public final static int SOCKET_BUFFER_SIZE = 1 << 10;
4649

4750
private static Path getPath(String resource) {
4851
URL url = ClassLoader.getSystemClassLoader().getResource(resource);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Manifest-Version: 1.0
2-
Main-Class: client.ClientDriver
2+
Main-Class: server.ServerDriver
33

0 commit comments

Comments
 (0)