Request.java

package fr.umlv.ji.tcp.server.http;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.prefs.Preferences;
import java.util.regex.*;
public class Request extends BufferedInputStream {
  // Table des en-têtes
  protected Map headers = new HashMap();
  // Expression régulière de la ligne de requête HTTP
  private static final Pattern pattern =
    Pattern.compile("^([A-Z]+) (\\p{Graph}+) ?((HTTP/[0-9\\.]+)?)$");
  // Divers attributs de la classe
  protected String method;
  protected URI uri;
  protected String protocol;
  protected Object content;
  protected HTTPService service;
  protected int maxLineLen;
  protected int maxHeaderNb;
  protected static ContentHandler ch = null;
  /** Initialisation de l'objet Requête. */
  public Request(InputStream in, HTTPService s) {
    super(in, s.getPreferences().getInt("bufferSize", 2048));
    maxLineLen = s.getPreferences().getInt("maxLineLen", 1024);
    maxHeaderNb = s.getPreferences().getInt("maxHeaderNb", 1024);
    service = s;
  }
  /** Méthode de lecture des en-têtes HTTP. */
  public void readHeaders() throws IOException, URISyntaxException {
    StringBuffer sb = new StringBuffer();
    headers.clear();
    boolean closed = readLine(sb);
    if (closed)
      throw new IOException("Connection reset by peer");
    setRequestLine(sb);
    for (int i=0; ; i++) {
      sb.setLength(0); // Réinitialise sb
      closed = readLine(sb);
      if (closed)
    throw new IOException("Connection reset by peer");
      if (sb.length() == 0) return;
      addHeader(sb);
      if (i==maxHeaderNb)
    throw new IOException("Too many Headers !");
    }
  }
  /** Méthode de lecture du corps de la requête. */
  public void readContent() throws IOException {
    // Récupération du gestionnaire de contenu
    ContentHandler handler = getContentHandler(getContentType());
    // Stockage du contenu de la requête
    content = handler.getContent(getContentLength(), this);
  }
  /** Méthode récupérant le gestionnaire de contenu par défaut.
      Méthode à redéfinir pour étendre le serveur. */
  protected ContentHandler getContentHandler(String s) {
    if (ch == null) ch = new ContentHandler.Default();
    return ch;
  }
  /** Méthode de décomposition de la ligne de requête.  */
  public void setRequestLine(StringBuffer stringbuffer)
    throws IOException, URISyntaxException {
    Matcher matcher = pattern.matcher(stringbuffer);
    if (!matcher.find()) {
      throw new IOException("Malformed header line: " + stringbuffer);
    } else {
      method = matcher.group(1);
      uri = new URI(matcher.group(2));
      protocol = matcher.group(3);
    }
  }
  /** Méthode de lecture de lignes terminées par \r\n. */
  private boolean readLine(StringBuffer buffer)
    throws IOException {
    boolean carriageReturnBefore = false;
    for (int j=0; j!=maxLineLen; j++) {
      int c = read();
      if (c == -1) {
    if (carriageReturnBefore)
      buffer.setLength(buffer.length() - 1);
    return true;
      }
      if (c == '\n') {
    if (carriageReturnBefore)
      buffer.setLength(buffer.length() - 1);
    return false;
      }
      buffer.append((char)c);
      carriageReturnBefore = (c == '\r');
    }
    throw new IOException("Input line too long !");
  }
  // Méthodes utilitaires
  public boolean isKeepAlive() {
    String s = (String)headers.get("connection");
    return (protocol.equals("HTTP/1.1") &&
        (s==null || !s.equalsIgnoreCase("close")));
  }
  public void addHeader(StringBuffer stringbuffer) {
    String as[] = Pattern.compile(" *: *").split(stringbuffer);
    if (as.length != 2) return;
    headers.put(as[0].toLowerCase(), as[1]);
  }
  public long getContentLength() {
    String s = (String)headers.get("content-length");
    if (s != null) return Long.parseLong(s);
    return -1;
  }
  public String getContentType() {
    return (String) headers.get("content-type");
  }
  public String getHeader(String s) {
    return (String) headers.get(s);
  }
  public String getMethod() { return method; }
  public URI getURI() { return uri; }
  public String getProtocol() { return protocol; }}