Package org.w3c.jigsaw.http

Source Code of org.w3c.jigsaw.http.Reply

// Reply.java
// $Id: Reply.java,v 1.38 2003/02/25 17:52:01 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.http ;

import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import org.w3c.www.mime.MimeType;

import org.w3c.www.http.HTTP;
import org.w3c.www.http.HeaderValue;
import org.w3c.www.http.HttpEntityMessage;
import org.w3c.www.http.HttpFactory;
import org.w3c.www.http.HttpMessage;
import org.w3c.www.http.HttpMimeType;
import org.w3c.www.http.HttpReplyMessage;
import org.w3c.www.http.HttpRequestMessage;
import org.w3c.www.http.HttpTokenList;

import org.w3c.tools.resources.ReplyInterface;
import org.w3c.tools.resources.RequestInterface;
import org.w3c.tools.resources.ResourceFilter;

public class Reply extends HttpReplyMessage implements ReplyInterface {
    protected static HttpMimeType  DEFAULT_TYPE = null;
    protected static HttpTokenList CONNECTION   = null;
   
    private static String ka = "Keep-Alive";
    private static String pc = "Proxy-Connection";
    private static String cl = "close";

    static {
  String connection[] = { "Keep-Alive" };
  CONNECTION   = HttpFactory.makeStringList(connection);
  DEFAULT_TYPE = HttpFactory.makeMimeType(MimeType.TEXT_HTML);
    }

    InputStream is      = null;
    Client      client  = null;
    boolean     keep    = true;
    Request     request = null;
    private boolean sendBody = true;
    private boolean dynamic = false;

    /**
     * set the reply to be a reply for dynamic content
     * @param a boolean, true if the reply is generated by a dynamic
     */
    public void setDynamic(boolean dyn) {
  dynamic = dyn;
    }

    /**
     * is is dynamic or not?
     */
    public boolean isDynamic() {
  return dynamic;
    }
   
    public void setStatus(Integer status) {
  setStatus(status.intValue());
    }

    public boolean hasContentLength() {
  return hasHeader(H_CONTENT_LENGTH);
    }

    public boolean hasContentType() {
  return  ( hasHeader(H_CONTENT_TYPE) &&
      ( getHeaderValue(H_CONTENT_TYPE).getValue() != null));
    }

    public void setKeepAlive(String value) {
  setValue(ka, value);
    }

    public void setProxyConnection(String value) {
  setValue(pc, value);
    }

    public boolean keepProxyConnection() {
  throw new RuntimeException("keepProxyConnection: not implemented!");
    }

    /**
     * @deprecated
     */

    public FileDescriptor getInputFileDescriptor() {
  return null;
    }

    public void setKeepConnection(boolean onoff) {
  this.keep = onoff;
    }

    public boolean tryKeepConnection() {
  if ( ! keep ) {
      addConnection(cl);
      return false;
  } else if ( major >= 1 ) {
      if ( minor >= 1 )
    return true;
      if ( hasContentLength() || (is == null)) {
    if ( is_proxy )
        addProxyConnection(ka);
    else
        addConnection(ka);
    return true;
      }
  }
  return false;
    }

    /**
     * Is this reply a proxy reply.
     */
    protected boolean is_proxy = false;

    /**
     * Mark this reply as being a proxy reply.
     */

    public void setProxy (boolean onoff) {
  is_proxy = onoff;
    }

    /**
     * Sets the reply stream to the given HtmlGenerator stream.
     * @param g The HtmlGenerator whose output is to be used as the reply body.
     */

    public void setStream (org.w3c.jigsaw.html.HtmlGenerator g) {
  g.close() ;
  setContentLength (g.length()) ;
  setContentType (g.getMimeType()) ;
  if (sendBody)
      setStream (g.getInputStream(), true) ;
    }

    public boolean hasStream() {
  return is != null;
    }

    /**
     * Open this reply body stream.
     * This is used to send the reply body back to the client.
     * @return An InputStream containing the reply body, which is dumped
     *    back to the client.
     */

    public InputStream openStream () {
  return is ;
    }

    public void setStream(InputStream is) {
  setStream(is, false);
    }

    public synchronized void setStream(InputStream is, boolean closeOld) {
  if (sendBody) {
      if (closeOld && (this.is != null)) {
    try {
        this.is.close();
    } catch (IOException ioex) {};
      }
      this.is = is;
  }
    }

    protected ResourceFilter filters[] = null;
    protected int        infilters = -1;
    protected void setFilters(ResourceFilter filters[], int infilters) {
  this.filters   = filters;
  this.infilters = infilters;
    }

  
    protected OutputStream output = null;

    /**
     * Get the reply output stream.
     * @param doEmit Emit that reply before giving out the output stream.
     * @return An OutputStream instance.
     * @exception IOException If the output stream could not get opened.
     */

    public synchronized OutputStream getOutputStream(boolean doEmit)
  throws IOException
    {
  if ( output != null )
      return output;
  // Build the output stream:
  output = client.getOutputStream();
  // Call any filters:
  while ( --infilters >= 0 )
      output = filters[infilters].outputFilter(request, this, output);
  if ( doEmit ) {
      DataOutputStream dataOutput = new DataOutputStream(output);
      emit(dataOutput);
      dataOutput.flush();
      setStatus(HTTP.DONE);
  }
  // Disable keep-connection:
  keep = false;
  return output;
    }

    /**
     * Get that reply output stream.
     * The reply is first emitted to the stream, and the opened stream
     * is returned back to the caller.
     * @return An OutputStream instance.
     * @exception IOException If the output stream could not get opened.
     */

    public OutputStream getOutputStream()
  throws IOException
    {
  return getOutputStream(true);
    }

   /**
     * Should this reply be chunked ?
     * @return If so, the reply should prepare itself to send back the
     *     appropriate transfer encoding header, and return
     *     <strong>true</strong>, otherwise it should just return
     *     <strong>false</strong>.
     */

    protected Boolean chunkable = null ;
    // FIXME should be an HttpTokenList
    protected static String chunked = "chunked";

    public boolean canChunkTransfer() {
  // Have we already compute this ?
  if ( chunkable == null ) {
      // Compute wether we can chunk the reply:
      if ( hasContentLength() || (is == null)) {
    chunkable = Boolean.FALSE ;
      } else if ((major >= 1) && (minor >= 1)) {
//    String connections[] = getConnection();
    chunkable = Boolean.TRUE ;
//    if (connections != null) {
//        for (int i = 0; i< connections.length; i++) {
//      if (connections[i].equalsIgnoreCase("close")) {
//          chunkable = Boolean.FALSE;
//      }
//        }
//    }
//    if (chunkable == Boolean.TRUE)
        addTransferEncoding(chunked);
      } else {
    chunkable = Boolean.FALSE ;
      }
  }
  return (chunkable == Boolean.TRUE) ;
    }

    /**
     * Set this reply content.
     * This method allows to set the reply content to a simple String instance.
     * @param msg The reply content.
     * @param encoding, the encoding of the reply
     */
    public void setContent (String msg, String encoding) {
  if ( ! hasContentType() )
      setHeaderValue(H_CONTENT_TYPE, DEFAULT_TYPE) ;
  byte byteBuffer[];
  try {
      byteBuffer = msg.getBytes(encoding) ;
  } catch (UnsupportedEncodingException ex) {
      throw new RuntimeException (this.getClass().getName() +
          "[setContent] Unable to convert" +
          "properly char to bytes");
  }
  setContentLength (byteBuffer.length) ;
  if (sendBody) {
      ByteArrayInputStream bis = new ByteArrayInputStream (byteBuffer) ;
      setStream(bis, true);
  }
    }

    // FIXME the bug fix should be in HttpMessage.hasHeader, but it would
    // be more time consuming, as it would add checks for all headers
    // and only Content-Type seems to be problematic

    /**
     * @param out The output stream to emit the message to.
     * @param what (fixme doc)
     * @exception IOException If the message couldn't be emited to the
     * given stream, due to IO errors.
     */
    public void emit(OutputStream out, int what)
  throws IOException
    {
  int status = getStatus();
  if (!hasContentType() && ((status != HTTP.CONTINUE) ||
          (status != HTTP.SWITCHING)))  {
      setHeaderValue(H_CONTENT_TYPE, DEFAULT_TYPE) ;
  }
  super.emit(out, what);
    }
   
    public void dump(OutputStream out) {
  if (!hasContentType()) {
      setHeaderValue(H_CONTENT_TYPE, DEFAULT_TYPE) ;
  }
  super.dump(out);
  }  

    /**
     * Set this reply content.
     * This method allows to set the reply content to a simple String instance.
     * encoding will be by default "ISO8859_1"
     * @param msg The reply content.
     */
    public void setContent (String msg) {
  setContent(msg, "ISO-8859-1");
    }

    /**
     * Get the entity MIME type.
     * @return An HttpMimeType object describing the entity's type, or
     * <strong>null</strong> if udefined.
     */
    public MimeType getContentType() {
  MimeType mt = super.getContentType();
  if (mt == null) {
      return MimeType.APPLICATION_OCTET_STREAM;
  } else {
      return mt;
  }
    }

    /**
     * Create a new Reply instance for the given client.
     * @param client The client to who this reply  is directed.
     */

    public Reply (Client client) {
  this.client = client ;
    }

    /**
     * Create a new reply for the given client.
     * @param client The client ot who the reply is directed.
     * @reply status The reply status code.
     */
   
    public Reply(Client client, Request request, short major, short minor,
     int status) {
  this (client) ;
  this.request = request;
  this.major   = major;
  this.minor   = minor;
  this.keep    = true;
  this.setServer((client != null)
           ? client.getServer().getSoftware()
           : null);
  this.setStatus (status);
  if (request != null)
      if (request.getMethod().endsWith(HTTP.HEAD))
    sendBody = false;
    }
}
TOP

Related Classes of org.w3c.jigsaw.http.Reply

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.