Java Reference
In-Depth Information
String
encoding
=
"UTF-8"
;
if
(
args
.
length
>
2
)
encoding
=
args
[
2
];
try
{
Path
path
=
Paths
.
get
(
args
[
0
]);;
byte
[]
data
=
Files
.
readAllBytes
(
path
);
String
contentType
=
URLConnection
.
getFileNameMap
().
getContentTypeFor
(
args
[
0
]);
SingleFileHTTPServer
server
=
new
SingleFileHTTPServer
(
data
,
encoding
,
contentType
,
port
);
server
.
start
();
}
catch
(
ArrayIndexOutOfBoundsException
ex
)
{
System
.
out
.
println
(
"Usage: java SingleFileHTTPServer filename port encoding"
);
}
catch
(
IOException
ex
)
{
logger
.
severe
(
ex
.
getMessage
());
}
}
}
The constructors set up the data to be sent along with an HTTP header that includes
information about content length and content encoding. The header and the body of
the response are stored in
byte
arrays in the desired encoding so that they can be blasted
to clients very quickly.
The
SingleFileHTTPServer
class holds the content to send, the header to send, and the
port to bind to. The
start()
method creates a
ServerSocket
on the specified port, then
enters an infinite loop that continually accepts connections and processes them.
Each incoming socket is processed by a runnable
Handler
object that is submitted to a
thread pool. Thus, one slow client can't starve other clients. Each
Handler
gets an
InputStream
from it which it reads the client request. It looks at the first line to see
whether it contains the string
HTTP
. If it sees this string, the server assumes that the client
understands HTTP/1.0 or later and therefore sends a MIME header for the file; then it
sends the data. If the client request doesn't contain the string
HTTP
, the server omits the
header, sending the data by itself. Finally, the handler closes the connection.
The
main()
method just reads parameters from the command line. The name of the file
to be served is read from the first command-line argument. If no file is specified or the
file cannot be opened, an error message is printed and the program exits. Assuming the
file can be read, its contents are read into the
byte
array
data
using the
Path
and
Files
classes introduced in Java 7. The
URLConnection
class makes a reasonable guess about
the content type of the file, and that guess is stored in the
contentType
variable. Next,
the port number is read from the second command-line argument. If no port is specified
or if the second argument is not an integer from 1 to 65,535, port 80 is used. The encoding