/*
|
neon - Embeddable HTTP Server based on jdk.httpserver
|
Copyright (C) 2024 Ulrich Hilger
|
|
This program is free software: you can redistribute it and/or modify
|
it under the terms of the GNU Affero General Public License as
|
published by the Free Software Foundation, either version 3 of the
|
License, or (at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU Affero General Public License for more details.
|
|
You should have received a copy of the GNU Affero General Public License
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
*/
|
package de.uhilger.neon;
|
|
import com.sun.net.httpserver.Headers;
|
import com.sun.net.httpserver.HttpExchange;
|
import java.io.File;
|
import java.io.IOException;
|
|
/**
|
* Objekte der Klasse FileServer liefern Dateien ueber HTTP aus
|
*
|
* Im Attribut FileServer.ATTR_FILE_BASE in
|
* HttpExchange.getContext().getAttributes() wird das
|
* Verzeichnis erwartet, aus dem Dateien ausgeliefert
|
* werden sollen.
|
*
|
* Im Attribut FileServer.ATTR_WELCOME_FILES in
|
* HttpExchange.getContext().getAttributes() kann eine
|
* mit Komma getrennte Liste mit Dateinamen uebergeben
|
* werden, die ausgeliefert werden sollen, wenn ein
|
* Verzeichnis anstelle einer Datei angefragt ist.
|
*
|
* @author Ulrich Hilger
|
*/
|
public class FileServer {
|
|
public static final String RANGE_HEADER = "Range";
|
|
public static final String ATTR_FILE_BASE = "fileBase";
|
public static final String ATTR_WELCOME_FILES = "welcomeFiles";
|
|
public static final String DEFAULT_INDEX_FILE = "index.html";
|
|
public static final String STR_SLASH = "/";
|
public static final String STR_BLANK = " ";
|
public static final String STR_DASH = "-";
|
public static final String STR_COMMA = ",";
|
public static final String STR_DOT = ".";
|
public static final String STR_EMPTY = "";
|
|
public void serveFile(HttpExchange exchange) throws IOException {
|
String fName = exchange.getRequestURI().getPath();
|
try {
|
fName = new HttpHelper().getFileName(exchange);
|
File fileToDeliver = new File((String) exchange
|
.getHttpContext().getAttributes()
|
.getOrDefault(ATTR_FILE_BASE, STR_EMPTY), fName);
|
Headers headers = exchange.getRequestHeaders();
|
if (headers.containsKey(RANGE_HEADER)) {
|
new PartialFileServer().serveFileParts(exchange, fileToDeliver);
|
} else {
|
if (fName.length() < 1 || fName.endsWith(STR_SLASH)) {
|
File welcomeFile = tryWelcomeFiles(exchange, fName);
|
if(welcomeFile != null) {
|
fileToDeliver = welcomeFile;
|
}
|
}
|
new HttpResponder().serveFile(exchange, fileToDeliver);
|
}
|
} catch(IllegalArgumentException ex) {
|
new HttpResponder().sendNotFound(exchange, fName);
|
}
|
}
|
|
public File tryWelcomeFiles(HttpExchange e, String fName) {
|
boolean notFound = true;
|
File file = null;
|
String fileBase = (String) e.getHttpContext().getAttributes()
|
.getOrDefault(ATTR_FILE_BASE, STR_EMPTY);
|
Object welcomeFiles = e.getHttpContext().getAttributes().get(ATTR_WELCOME_FILES);
|
if(welcomeFiles instanceof String) {
|
String[] fileNames = welcomeFiles.toString().split(STR_COMMA);
|
int i = -1;
|
while(notFound && ++i < fileNames.length) {
|
file = new File(fileBase, fName + fileNames[i]);
|
if(file.exists()) {
|
notFound = false;
|
}
|
}
|
}
|
if(notFound) {
|
file = new File(fileBase, fName + DEFAULT_INDEX_FILE);
|
}
|
return file;
|
}
|
}
|