Basisklassen zum Modul jdk.httpserver
ulrich
2021-06-24 bf550a92498fc5f253ffa0daefa03022d0a39724
commit | author | age
069fd4 1 /*
90f2d3 2   http-base - Extensions to jdk.httpserver
069fd4 3   Copyright (C) 2021  Ulrich Hilger
U 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.httpserver.base.handler;
19
786e8c 20 import de.uhilger.httpserver.base.HttpResponder;
069fd4 21 import com.sun.net.httpserver.Headers;
U 22 import com.sun.net.httpserver.HttpExchange;
23 import com.sun.net.httpserver.HttpHandler;
786e8c 24 import de.uhilger.httpserver.base.actor.FileActor;
069fd4 25 import java.io.File;
U 26 import java.io.IOException;
27 import java.util.logging.Logger;
28
29 /**
30  * Die Klasse FileHandler dient zur Auslieferung von Dateiinhalten &uuml;ber
31  * HTTP.
32  *
33  * F&uuml;r das Streaming &uuml;ber HTTP wird die Auslieferung von Teilinhalten
34  * mit dem Accept-Ranges-Header angeboten und via Range-Header unterst&uuml;tzt.
35  * (vgl. https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests)
36  *
37  * @author Ulrich Hilger
90f2d3 38  * @version 1, 03.06.2021, (seit 25. M&auml;rz 2021)
069fd4 39  */
U 40 public class FileHandler implements HttpHandler {
41
42   /* Der Logger fuer diesen FileHandler */
43   private static final Logger logger = Logger.getLogger(FileHandler.class.getName());
44
45   /* Headernamen */
46   public static final String RANGE_HEADER = "Range";
47   public static final String CONTENT_RANGE_HEADER = "Content-Range";
48   //public static final String ACCEPT_RANGES_HEADER = "Accept-Ranges";
49   //public static final String LAST_MODIFIED_DATE_HEADER = "Last-Modified";
50   public static final String CONTENT_TYPE = "Content-Type";
51   public static final String CONTENT_LENGTH = "Content-Length";
52
53   /* Statuscodes */
54   public static final int SC_OK = 200;
55   public static final int SC_PARTIAL_CONTENT = 206;
e88b7b 56   public static final int SC_FORBIDDEN = 403;
069fd4 57   public static final int SC_NOT_FOUND = 404;
U 58   public static final int SC_METHOD_NOT_ALLOWED = 405;
59   public static final int SC_UNPROCESSABLE_ENTITY = 422;
60
61   /* String Konstanten */
62   //public static final String STR_BYTES = "bytes";
63   public static final String STR_SLASH = "/";
64   public static final String STR_BLANK = " ";
65   public static final String STR_DASH = "-";
66   public static final String STR_COMMA = ",";
67   public static final String STR_DOT = ".";
68   //public static final String STR_NOT_FOUND = " not found.";
69   //public static final String LM_PATTERN = "EEE, dd MMM yyyy HH:mm:ss zzz";
70   public static final String RANGE_PATTERN = "[^\\d-,]";
71   public static final String WELCOME_FILE = "index.html";
72
73   /* Ablageort fuer Webinhalte */
74   protected final String fileBase;
75
76   /**
77    * Ein neues Objekt der Klasse FileHandler erzeugen
78    *
79    * @param absoluteDirectoryPathAndName der absolute Pfad und Name des 
80    * Ordners im Dateisystem, der die Inhalte enthaelt, die von diesem 
81    * Handler ausgeliefert werden sollen
82    */
83   public FileHandler(String absoluteDirectoryPathAndName) {
84     this.fileBase = absoluteDirectoryPathAndName;
85   }
86
87   /**
88    * Die Datei ermitteln, die sich aus dem angefragten URL ergibt, pr&uuml;fen,
89    * ob die Datei existiert und den Inhalt der Datei abh&auml;ngig davon, ob ein
90    * Range-Header vorhanden ist, ganz oder teilweise ausliefern.
91    *
92    * @param e das Objekt mit Methoden zur Untersuchung der Anfrage sowie zum
93    * Anfertigen und Senden der Antwort
94    * @throws IOException falls etwas schief geht entsteht dieser Fehler
95    */
96   @Override
97   public void handle(HttpExchange e) throws IOException {
98     String fName = getFileName(e);
99     if (fName.startsWith(STR_DOT)) {
100       HttpResponder fs = new HttpResponder();
101       fs.sendNotFound(e, fName);
102     } else {
103       Headers headers = e.getRequestHeaders();
104       if (headers.containsKey(RANGE_HEADER)) {
786e8c 105         FileActor fa = new FileActor();
U 106         fa.serveFileParts(e, new File(fileBase, fName));
069fd4 107       } else {
U 108         if (fName.length() < 1 || fName.endsWith(STR_SLASH)) {
109           fName += WELCOME_FILE;
110         }
111         HttpResponder fs = new HttpResponder();
112         fs.serveFile(e, new File(fileBase, fName));
113       }
114     }
115   }
116
117   /**
118    * Den Namen der gew&uuml;nschten Datei aus der HTTP-Anfrage ermitteln
119    * 
120    * @param e das Objekt mit Methoden zur Untersuchung der Anfrage sowie zum
121    * Anfertigen und Senden der Antwort
122    * @return Name der gew&uuml;nschten Datei
123    */
9efb60 124   public String getFileName(HttpExchange e) {
069fd4 125     String ctxPath = e.getHttpContext().getPath();
U 126     String uriPath = e.getRequestURI().getPath();
127     logger.info(uriPath);
128     return uriPath.substring(ctxPath.length());
129   }
130   
bf550a 131   public String getFileBase() {
U 132     return this.fileBase;
133   }
134   
069fd4 135 }