Response.java

package fr.umlv.ji.tcp.server.http;
import java.io.*;
import java.util.*;
import java.util.Iterator;
/** Classe des objets réponses à des requêtes HTTP. */
public class Response extends BufferedOutputStream {
  // Table des en-têtes
  protected Collection headers = new ArrayList();
  // Type d'erreur ou -1
  protected int error;
  // Type de la réponse ou null
  protected String contentType;
  // Taille de la réponse ou -1
  protected long contentLength;
  // Flot contenant la réponse
  protected InputStream in;
  // Connection fermée après la réponse
  protected boolean close;
  // Requête de type HEAD
  protected boolean headRequest;
  // Divers champs et constantes
  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) {}
  }
  /** Initialisation de la réponse. */
  public Response(OutputStream outputstream) {
    super(outputstream);
    reset();
    buffer = new byte[2048];
  }
  /** Réinitialisation des différents champs de la réponse. */
  public void reset() {
    close = false;
    error = -1;
    contentType = null;
    contentLength = -1L;
    in = null;
    headRequest = false;
    headers.clear();
  }
  /** Méthode d'envoi de la réponse. */
  public void send() throws IOException {
    if (error!=-1) {
      writeError();
    } else {
      writeReply();
    }
  }
  /** Méthode d'envoi d'erreur. */
  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;
  }
  /** Méthode d'envoi de réponse standard. */
  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();
  }
  // Méthodes utilitaires
  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; }
}