package http.content;
import static http.config.Config.getConfig;
import static http.global.HttpGlobal.CRLF;
import http.content.header.HttpHeader;
import http.log.Log;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
import java.util.Vector;
/**
* Gets content from a file and returns it as a {@link String} in {@link #get()}
* . It also handles errors, such as not found(error #404).
*
* @author Dennis Hedegaard
*
*/
public class HttpContent {
private Socket socket;
private String get;
public String getIp() {
return socket.getInetAddress().getHostAddress();
}
/**
* Constructs a new {@link HttpContent} object, which has the purpose of
* returning a {@link String} with the content of a file, or return an error
* page or similar on eventual errors.
*
* @param socket
* The {@link Socket} that made the request.
* @param get
* The {@link String} that contains the GET tag from the
* {@link Socket} client.
*/
public HttpContent(Socket socket, String get) {
this.socket = socket;
this.get = get;
this.get = this.get.replace("GET ", "").replace(" HTTP/1.1", "").trim();
if (this.get.charAt(this.get.length() - 1) == '/')
this.get += getConfig().getIndex();
}
/**
* A file is read to a {@link Vector} of bytes, this byte {@link Vector} is
* then converted to an array and returned.
*
* @return A byte array, containing the output from the file.
*/
public void write(OutputStream socketOut) {
File f = new File(String.format("%s%s", getConfig().getHtmldir(), get));
InputStream in = null;
/**
* Attempts to open a FileInputStream on the file, this is used for
* reading it's content.
*/
HttpHeader header = new HttpHeader(socket, f.getPath());
try {
in = new BufferedInputStream(new FileInputStream(f));
Log.fine("200: %s", f.getPath());
} catch (FileNotFoundException e) {
Log.fine("404: %s", get);
try {
socketOut.write(header.get404());
} catch (IOException e1) {
Log.fine("Unable to write 404 to output stream.");
}
return;
}
try {
socketOut.write(header.get200());
} catch (IOException e1) {
Log.info("Unable to write header to output stream for: %s", getIp());
}
try {
socketOut.write(header.getContentLength(in.available()));
socketOut.write(CRLF.getBytes());
} catch (IOException e1) {
Log.info("Unable to write content length to the header for: %s",
getIp());
e1.printStackTrace();
}
/**
* Remember a newline.
*/
int read = -2;
try {
while ((read = in.read()) != -1)
socketOut.write(read);
socketOut.flush();
} catch (IOException e) {
if (read == -2)
Log.warning("Unable to read file input stream: %s for: %s",
f.getPath(), getIp());
}
return;
}
/**
* Converts a {@link Vector} of bytes to a byte[].
*
* @param v
* The {@link Vector} to convert.
* @return The byte[] with the bytes from the {@link Vector}.
*/
public static byte[] vectorToArray(final List<Byte> v) {
byte[] result = new byte[v.size()];
int c = 0;
for (Byte b : v)
result[c++] = b;
return result;
}
/**
* Converts a byte[] to a {@link Vector} of bytes.
*
* @param b
* The byte array to convert.
* @return The {@link Vector} with the bytes from the array.
*/
public static List<Byte> arrayToVector(final byte[] b) {
List<Byte> result = new Vector<Byte>();
for (Byte _b : b)
result.add(_b);
return result;
}
}