-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileSystemHandler.java
More file actions
122 lines (100 loc) · 3.55 KB
/
FileSystemHandler.java
File metadata and controls
122 lines (100 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package handlers;
import core.Handler;
import core.Request;
import core.Response;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static core.HttpStatusCode.NOT_FOUND;
import static core.HttpStatusCode.OK;
import static util.Helper.combinePaths;
import static util.Helper.getServerTime;
public class FileSystemHandler extends Handler {
private String documentRoot;
public FileSystemHandler(String documentRoot) {
this.documentRoot = documentRoot;
}
@Override
public void handle(Request request, Response response) {
if (response.responseStatusCode != null)
return;
switch (request.requestMethod) {
case "GET":
case "HEAD":
try {
response.setBody(browsePath(request.requestURI, response.bodyCharset));
response.responseStatusCode = OK;
} catch (IOException e) {
response.setBody("<div style=\"text-align: center;\"><h1 style=\"color: red;\">404 Error</h1><br>File not found</div>");
response.responseStatusCode = NOT_FOUND;
}
response.setHeader("Content-Type", "text/html; charset=" + response.bodyCharset);
response.setHeader("Last-modified", getServerTime());
break;
default:
break;
}
}
public String browsePath(URI requestURI, Charset charset) throws IOException {
File localFile = covertRequestURIToLocalFile(requestURI);
if (localFile.isDirectory())
return generateDirectoryListingHTML(requestURI);
else
return new String(Files.readAllBytes(localFile.toPath()), charset);
}
public String generateDirectoryListingHTML(URI requestURI) {
String body = "<h1>Index of " + requestURI.getPath() + "</h1>";
body += "<ul>";
body += generateDirectoryListing(requestURI)
.stream()
.map(line -> "<li>" + line + "</li>")
.collect(Collectors.joining("\r\n"));
body += "</ul>";
return body;
}
public File covertRequestURIToLocalFile(URI requestURI) {
return new File(combinePaths(getDocumentRoot(), requestURI.getPath()));
}
public String getDocumentRoot() {
return documentRoot;
}
public List<String> generateDirectoryListing(URI requestURI) {
File localFile = covertRequestURIToLocalFile(requestURI);
List<String> links = Arrays.stream(localFile.listFiles())
.filter(file -> !file.getName().endsWith("~"))
.map(this::generateLinkToPath)
.collect(Collectors.toList());
if (!requestURI.getPath().equals("/"))
links.add(0, generateLinkToParent(localFile));
return links;
}
public String generateLink(String name, String relativePath) {
return "<a href=\"" + encodeURL(relativePath) + "\">" + name + "</a>";
}
public String generateLinkToPath(File file) {
String name = file.getName();
String absPath = makeAbsPath(file);
return generateLink(name, absPath);
}
public String makeAbsPath(File filePath) {
return "/" + new File(getDocumentRoot()).toURI().relativize(filePath.toURI()).getPath();
}
public String generateLinkToParent(File file) {
String name = "..";
String absPath = makeAbsPath(file.getParentFile());
return generateLink(name, absPath);
}
public String encodeURL(String relativePath) {
try {
return new URI(null, null, relativePath, null).toASCIIString();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}