package fr.umlv.ji.tcp.server.http;
import java.io.*;
import java.util.*;
import java.util.Iterator;
public class Response extends BufferedOutputStream {
protected Collection headers = new ArrayList();
protected int error;
protected String contentType;
protected long contentLength;
protected InputStream in;
protected boolean close;
protected boolean headRequest;
private byte buffer[];
public static final int BAD_REQUEST = 1;
public static final int NOT_FOUND = 2;
public static final int MOVED_PERMANENTLY = 3;
public static byte messages[][][];
public static byte eol[];
public static byte defaultContentType[];
public static byte contentTypeHeader[];
public static byte contentLengthHeader[];
public static byte connexionHeader[];
static byte protocol[];
static {
try {
protocol = "HTTP/1.1".getBytes("ASCII");
messages = (new byte[][][] {
new byte[][] {
"200".getBytes("ASCII"), "Ok".getBytes("ASCII")
}, new byte[][] {
"400".getBytes("ASCII"), "Bad Request".getBytes("ASCII")
}, new byte[][] {
"404".getBytes("ASCII"), "Not Found".getBytes("ASCII")
}, new byte[][] {
"301".getBytes("ASCII"), "Moved Permanently".getBytes("ASCII")
}
});
eol = "\r\n".getBytes("ASCII");
defaultContentType = "application/octet-stream".getBytes("ASCII");
contentTypeHeader = "Content-Type: ".getBytes("ASCII");
contentLengthHeader = "Content-Length: ".getBytes("ASCII");
connexionHeader = "Connection: ".getBytes("ASCII");
} catch(UnsupportedEncodingException e) {}
}
public Response(OutputStream outputstream) {
super(outputstream);
reset();
buffer = new byte[2048];
}
public void reset() {
close = false;
error = -1;
contentType = null;
contentLength = -1L;
in = null;
headRequest = false;
headers.clear();
}
public void send() throws IOException {
if (error!=-1) {
writeError();
} else {
writeReply();
}
}
private void writeError() throws IOException {
print(protocol); print(' ');
print(messages[error][0]); print(' ');
println(messages[error][1]);
println(defaultContentType); println();
print(messages[error][0]); print(' ');
print(messages[error][1]); println();
flush();
close = true;
}
private void writeReply() throws IOException {
print(protocol); print(' ');
print(messages[0][0]); print(' ');
println(messages[0][1]); print(contentTypeHeader);
if (contentType == null)
println(defaultContentType);
else
println(contentType);
if (contentLength == -1L || close) {
close = true;
print(connexionHeader);
println("close");
} else {
print(contentLengthHeader);
println(Long.toString(contentLength));
}
Iterator it = headers.iterator();
while (it.hasNext()) {
String header = (String) it.next();
println(header);
}
println();
if (!headRequest && in!=null)
if (contentLength!=-1L)
writeFromTo(in, contentLength);
else
writeFromTo(in);
flush();
}
private void writeFromTo(InputStream in, long l) throws IOException {
for (int i;l>0L;l -= i) {
i = in.read(buffer);
if (i==-1) return;
write(buffer, 0, i);
}
}
private void writeFromTo(InputStream in) throws IOException {
for (;;) {
int i = in.read(buffer);
if (i==-1) return;
write(buffer, 0, i);
}
}
public void println(String s) throws IOException {
write(s.getBytes("ASCII")); write(eol);
}
public void print(String s) throws IOException {
write(s.getBytes("ASCII"));
}
public void println(byte[] tab) throws IOException {
write(tab); write(eol);
}
public void print(byte[] tab) throws IOException { write(tab); }
public void println() throws IOException { write(eol); }
public void print(char c) throws IOException { write(c); }
public boolean isClosed() { return close; }
public void close() { close = true; }
public void setError(int i) { error = i; }
public void setContentType(String s) { contentType = s; }
public void setContentLength(long l) { contentLength = l; }
public void setHeader(String h, String v) { headers.add(h+": "+v); }
public void setInputStream(InputStream input) { in = input; }
public void setHeadRequest(boolean flag) { headRequest = flag; }
public int getError() { return error; }
}