Ultrakompakter HTTP Server
ulrich
6 days ago 19c3c55e8120312c41fd008da799a7e47f53a5bb
commit | author | age
e58690 1 /*
U 2   neon - Embeddable HTTP Server based on jdk.httpserver
3   Copyright (C) 2024  Ulrich Hilger
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package de.uhilger.neon;
19
20 import com.sun.net.httpserver.Headers;
21 import com.sun.net.httpserver.HttpExchange;
22 import java.io.File;
23 import java.io.IOException;
24
25 /**
26  * Objekte der Klasse FileServer liefern Dateien ueber HTTP aus
27  * 
28  * Im Attribut FileServer.ATTR_FILE_BASE in 
29  * HttpExchange.getContext().getAttributes() wird das 
30  * Verzeichnis erwartet, aus dem Dateien ausgeliefert 
31  * werden sollen. 
32  * 
33  * Im Attribut FileServer.ATTR_WELCOME_FILES in 
34  * HttpExchange.getContext().getAttributes() kann eine 
35  * mit Komma getrennte Liste mit Dateinamen uebergeben 
36  * werden, die ausgeliefert werden sollen, wenn ein 
37  * Verzeichnis anstelle einer Datei angefragt ist. 
38  * 
39  * @author Ulrich Hilger
40  */
41 public class FileServer {
42   
43   public static final String RANGE_HEADER = "Range";
44   
45   public static final String ATTR_FILE_BASE = "fileBase";
46   public static final String ATTR_WELCOME_FILES = "welcomeFiles";
47
48   public static final String DEFAULT_INDEX_FILE = "index.html";
49   
50   public static final String STR_SLASH = "/";
51   public static final String STR_BLANK = " ";
52   public static final String STR_DASH = "-";
53   public static final String STR_COMMA = ",";
54   public static final String STR_DOT = ".";
55   public static final String STR_EMPTY = "";
56   
57   public void serveFile(HttpExchange exchange) throws IOException {
19c3c5 58     String fName = exchange.getRequestURI().getPath();
U 59     try {
60       fName = new HttpHelper().getFileName(exchange);
e58690 61       File fileToDeliver = new File((String) exchange
U 62               .getHttpContext().getAttributes()
63               .getOrDefault(ATTR_FILE_BASE, STR_EMPTY), fName);
64       Headers headers = exchange.getRequestHeaders();
65       if (headers.containsKey(RANGE_HEADER)) {
66         new PartialFileServer().serveFileParts(exchange, fileToDeliver);
67       } else {
68         if (fName.length() < 1 || fName.endsWith(STR_SLASH)) {
69           File welcomeFile = tryWelcomeFiles(exchange, fName);
70           if(welcomeFile != null) {
71             fileToDeliver = welcomeFile;
72           }
73         }
74         new HttpResponder().serveFile(exchange, fileToDeliver);
75       }
19c3c5 76     } catch(IllegalArgumentException ex) {
U 77       new HttpResponder().sendNotFound(exchange, fName);
78     }
e58690 79   }
19c3c5 80   
e58690 81   public File tryWelcomeFiles(HttpExchange e, String fName) {
U 82     boolean notFound = true;
83     File file = null;
84     String fileBase = (String) e.getHttpContext().getAttributes()
85             .getOrDefault(ATTR_FILE_BASE, STR_EMPTY);
86     Object welcomeFiles = e.getHttpContext().getAttributes().get(ATTR_WELCOME_FILES);
87     if(welcomeFiles instanceof String) {
88       String[] fileNames = welcomeFiles.toString().split(STR_COMMA);
89       int i = -1;
90       while(notFound && ++i < fileNames.length) {
91         file = new File(fileBase, fName + fileNames[i]);
92         if(file.exists()) {
93           notFound = false;
94         }
95       }
96     }
97     if(notFound) {
98       file = new File(fileBase, fName + DEFAULT_INDEX_FILE);
99     }
100     return file;
101   }
102 }