Ultrakompakter HTTP Server
ulrich
10 days ago a1027d4499cfad752d6c449b407bb1f8dc4e16d2
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);
a1027d 61       String fBase = (String) exchange
e58690 62               .getHttpContext().getAttributes()
a1027d 63               .getOrDefault(ATTR_FILE_BASE, STR_EMPTY);
U 64       //File fileToDeliver = new File((String) exchange
65          //     .getHttpContext().getAttributes()
66            //   .getOrDefault(ATTR_FILE_BASE, STR_EMPTY), fName);
67       File fileToDeliver = new File(fBase, fName);
e58690 68       Headers headers = exchange.getRequestHeaders();
U 69       if (headers.containsKey(RANGE_HEADER)) {
70         new PartialFileServer().serveFileParts(exchange, fileToDeliver);
71       } else {
72         if (fName.length() < 1 || fName.endsWith(STR_SLASH)) {
73           File welcomeFile = tryWelcomeFiles(exchange, fName);
74           if(welcomeFile != null) {
75             fileToDeliver = welcomeFile;
76           }
77         }
78         new HttpResponder().serveFile(exchange, fileToDeliver);
79       }
19c3c5 80     } catch(IllegalArgumentException ex) {
U 81       new HttpResponder().sendNotFound(exchange, fName);
82     }
e58690 83   }
19c3c5 84   
e58690 85   public File tryWelcomeFiles(HttpExchange e, String fName) {
U 86     boolean notFound = true;
87     File file = null;
88     String fileBase = (String) e.getHttpContext().getAttributes()
89             .getOrDefault(ATTR_FILE_BASE, STR_EMPTY);
90     Object welcomeFiles = e.getHttpContext().getAttributes().get(ATTR_WELCOME_FILES);
91     if(welcomeFiles instanceof String) {
92       String[] fileNames = welcomeFiles.toString().split(STR_COMMA);
93       int i = -1;
94       while(notFound && ++i < fileNames.length) {
95         file = new File(fileBase, fName + fileNames[i]);
96         if(file.exists()) {
97           notFound = false;
98         }
99       }
100     }
101     if(notFound) {
102       file = new File(fileBase, fName + DEFAULT_INDEX_FILE);
103     }
104     return file;
105   }
106 }