1 /*
2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.util.*;
25 import java.util.concurrent.*;
26 import java.util.logging.*;
27 import java.io.*;
28 import java.net.*;
29 import java.security.*;
30 import javax.net.ssl.*;
31 import com.sun.net.httpserver.*;
32 
33 /**
34  * Implements a basic static content HTTP file server handler
35  * which understands text/html, text/plain content types
36  *
37  * Must be given an abs pathname to the document root.
38  * Directory listings together with text + html files
39  * can be served.
40  *
41  */
42 public class FileServerHandler implements HttpHandler {
43 
44     String docroot;
45 
FileServerHandler(String docroot)46     public FileServerHandler (String docroot) {
47         this.docroot = docroot;
48     }
49 
50     int invocation = 1;
handle(HttpExchange t)51     public void handle (HttpExchange t)
52         throws IOException
53     {
54         InputStream is = t.getRequestBody();
55         Headers map = t.getRequestHeaders();
56         Headers rmap = t.getResponseHeaders();
57         URI uri = t.getRequestURI();
58         String path = uri.getPath();
59 
60         int x = 0;
61         while (is.read () != -1) x++;
62         is.close();
63         File f = new File (docroot, path);
64         if (!f.exists()) {
65             notfound (t, path);
66             return;
67         }
68         String fixedrequest = map.getFirst ("XFixed");
69 
70         String method = t.getRequestMethod();
71         if (method.equals ("HEAD")) {
72             rmap.set ("Content-Length", Long.toString (f.length()));
73             t.sendResponseHeaders (200, -1);
74             t.close();
75         } else if (!method.equals("GET")) {
76             t.sendResponseHeaders (405, -1);
77             t.close();
78             return;
79         }
80 
81         if (path.endsWith (".html") || path.endsWith (".htm")) {
82             rmap.set ("Content-Type", "text/html");
83         } else {
84             rmap.set ("Content-Type", "text/plain");
85         }
86         if (f.isDirectory()) {
87             if (!path.endsWith ("/")) {
88                 moved (t);
89                 return;
90             }
91             rmap.set ("Content-Type", "text/html");
92             t.sendResponseHeaders (200, 0);
93             String[] list = f.list();
94             OutputStream os = t.getResponseBody();
95             PrintStream p = new PrintStream (os);
96             p.println ("<h2>Directory listing for: " + path+ "</h2>");
97             p.println ("<ul>");
98             for (int i=0; i<list.length; i++) {
99                 p.println ("<li><a href=\""+list[i]+"\">"+list[i]+"</a></li>");
100             }
101             p.println ("</ul><p><hr>");
102             p.flush();
103             p.close();
104         } else {
105             int clen;
106             if (fixedrequest != null) {
107                 clen = (int) f.length();
108             } else {
109                 clen = 0;
110             }
111             t.sendResponseHeaders (200, clen);
112             OutputStream os = t.getResponseBody();
113             FileInputStream fis = new FileInputStream (f);
114             int count = 0;
115             try {
116                 byte[] buf = new byte [16 * 1024];
117                 int len;
118                 while ((len=fis.read (buf)) != -1) {
119                     os.write (buf, 0, len);
120                     count += len;
121                 }
122             } catch (IOException e) {
123                 e.printStackTrace();
124             }
125             fis.close();
126             os.close();
127         }
128     }
129 
moved(HttpExchange t)130     void moved (HttpExchange t) throws IOException {
131         Headers req = t.getRequestHeaders();
132         Headers map = t.getResponseHeaders();
133         URI uri = t.getRequestURI();
134         String host = req.getFirst ("Host");
135         String location = "http://"+host+uri.getPath() + "/";
136         map.set ("Content-Type", "text/html");
137         map.set ("Location", location);
138         t.sendResponseHeaders (301, -1);
139         t.close();
140     }
141 
notfound(HttpExchange t, String p)142     void notfound (HttpExchange t, String p) throws IOException {
143         t.getResponseHeaders().set ("Content-Type", "text/html");
144         t.sendResponseHeaders (404, 0);
145         OutputStream os = t.getResponseBody();
146         String s = "<h2>File not found</h2>";
147         s = s + p + "<p>";
148         os.write (s.getBytes());
149         os.close();
150         t.close();
151     }
152 }
153