Package org.w3c.jigsaw.frames

Source Code of org.w3c.jigsaw.frames.CGIHeaderHolderFactory

// CgiFrame.java
// $Id: CgiFrame.java,v 1.19 2003/04/30 20:08:23 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.frames ;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;

import org.w3c.tools.resources.Attribute;
import org.w3c.tools.resources.AttributeHolder;
import org.w3c.tools.resources.AttributeRegistry;
import org.w3c.tools.resources.BooleanAttribute;
import org.w3c.tools.resources.FileResource;
import org.w3c.tools.resources.FramedResource;
import org.w3c.tools.resources.InvalidParentException;
import org.w3c.tools.resources.LookupResult;
import org.w3c.tools.resources.LookupState;
import org.w3c.tools.resources.PropertiesAttribute;
import org.w3c.tools.resources.ProtocolException;
import org.w3c.tools.resources.Resource;
import org.w3c.tools.resources.ResourceException;
import org.w3c.tools.resources.ResourceFrame;
import org.w3c.tools.resources.ServerInterface;
import org.w3c.tools.resources.StringArrayAttribute;
import org.w3c.tools.resources.StringAttribute;

import org.w3c.tools.resources.ProtocolException;

import org.w3c.www.mime.MimeHeaderHolder;
import org.w3c.www.mime.MimeParser;
import org.w3c.www.mime.MimeParserException;
import org.w3c.www.mime.MimeParserFactory;
import org.w3c.www.mime.MimeType;

import org.w3c.jigsaw.http.Client;
import org.w3c.jigsaw.http.HTTPException;
import org.w3c.jigsaw.http.Reply;
import org.w3c.jigsaw.http.Request;
import org.w3c.jigsaw.http.httpd;

import org.w3c.www.http.HTTP;
import org.w3c.www.http.HeaderDescription;
import org.w3c.www.http.HttpEntityMessage;
import org.w3c.www.http.HttpEntityTag;
import org.w3c.www.http.HttpMessage;
import org.w3c.www.http.HttpReplyMessage;
import org.w3c.www.http.HttpRequestMessage;

import org.w3c.jigsaw.auth.AuthFilter;
import org.w3c.util.ArrayDictionary;

/**
* Parsing the CGI output - The CGIHeaderHolder, to hold CGI headers.
*/
class CGIHeaderHolder implements MimeHeaderHolder {
    // Status and Location deserve special treatments:
    String status   = null;
    String location = null;
    // Anyway, he is going to pay for using CGI
    Hashtable headers = null;
    // The MIME parse we are attached to:
    MimeParser parser = null;

    /**
     * The parsing is now about to start, take any appropriate action.
     * This hook can return a <strong>true</strong> boolean value to enforce
     * the MIME parser into transparent mode (eg the parser will <em>not</em>
     * try to parse any headers.
     * <p>This hack is primarily defined for HTTP/0.9 support, it might
     * also be usefull for other hacks.
     * @param parser The Mime parser.
     * @return A boolean <strong>true</strong> if the MimeParser shouldn't
     * continue the parsing, <strong>false</strong> otherwise.
     * @exception IOException if an IO error occurs.
     */

    public boolean notifyBeginParsing(MimeParser parser)
  throws IOException
    {
  return false;
    }

    /**
     * All the headers have been parsed, take any appropriate actions.
     * @param parser The Mime parser.
     * @exception IOException if an IO error occurs.
     */

    public void notifyEndParsing(MimeParser parser)
  throws IOException
    {
  return ;
    }

    /**
     * A new header has been emited by the script.
     * If the script is not an NPH, then it <strong>must</strong> at least
     * emit one header, so we are safe here, although people may not be safe
     * against the spec.
     * @param name The header name.
     * @param buf The header bytes.
     * @param off The begining of the value bytes  in above buffer.
     * @param len The length of the value bytes  in above buffer.
     * @exception MimeParserException if parsing failed.
     */

    public void notifyHeader(String name, byte buf[], int off, int len)
  throws MimeParserException
    {
  if ( name.equalsIgnoreCase("status") ) {
      status = new String(buf, 0, off, len);
  } else if ( name.equalsIgnoreCase("location") ) {
      location = new String(buf, 0, off, len);
  } else {
      String extraval =  new String(buf, 0, off, len);
      if ( headers == null ) {
    headers = new Hashtable(11);
      } else {
    String val = (String) headers.get(name.toLowerCase());
    if ( val != null )
        extraval = val + "," + extraval;
      }
      headers.put(name.toLowerCase(), extraval);
  }
    }

    /**
     * Get the status emited by the script.
     */

    public String getStatus() {
  return status;
    }

    /**
     * Get the location header value emited by the script.
     */

    public String getLocation() {
  return location;
    }

    /**
     * Get any header value (except status and location).
     * @param name The name of the header to fetch.
     * @return The string value of requested header, or <strong>null</strong>
     * if header was not defined.
     */

    public String getValue(String name) {
  return (headers == null) ? null : (String) headers.get(name);
    }

    /**
     * Enumerate the headers defined by the holder.
     * @return A enumeration of header names, or <strong>null</strong> if no
     * header is defined.
     */

    public Enumeration enumerateHeaders() {
  if ( headers == null )
      return null;
  return headers.keys();
    }

    /**
     * Get the remaining output of the stream.
     * This should be called only once header parsing is done.
     */

    public InputStream getInputStream() {
  return parser.getInputStream();
    }

    CGIHeaderHolder(MimeParser parser) {
  this.parser = parser;
    }

}

/**
* Parsing the CGI output - Always create a CGIHeaderHolder.
*/

class CGIHeaderHolderFactory implements MimeParserFactory {

    /**
     * Create a new header holder to hold the parser's result.
     * @param parser The parser that has something to parse.
     * @return A MimeParserHandler compliant object.
     */

    public MimeHeaderHolder createHeaderHolder(MimeParser parser) {
  return new CGIHeaderHolder(parser);
    }

    CGIHeaderHolderFactory() {
    }

}

/**
* A simple process feeder class.
*/

class ProcessFeeder extends Thread {
    Process      proc    = null ;
    OutputStream out     = null ;
    InputStream  in      = null ;
    int          count = -1 ;

    public void run () {
  try {
      byte buffer[] = new byte[4096] ;
      int  got      = -1 ;
     
      // Send the data to the target process:
      if ( count >= 0 ) {
    while ( (count > 0) && ((got = in.read(buffer)) > 0) ) {
        out.write (buffer, 0, got) ;
        count -= got ;
    }
      } else {
    while ( (got = in.read(buffer)) > 0 ) {
        out.write (buffer, 0, got) ;
    }
      }
  } catch (Exception e) {
      System.out.println ("ProcessFeeder: caught exception !") ;
      e.printStackTrace() ;
  } finally {
      // Clean up the process:
      try { out.flush() ; } catch (IOException ex) {}
      try { out.close() ; } catch (IOException ex) {}
      try { proc.waitFor() ; } catch (Exception ex) {}
  }
    }
 
    ProcessFeeder (Process proc, InputStream in) {
  this (proc, in, -1) ;
    }
 
    ProcessFeeder (Process proc, InputStream in, int count) {
  this.proc   = proc ;
  this.out    = proc.getOutputStream() ;
  this.in     = in ;
  this.count  = count ;
    }
}
/**
* Handle CGI error stream
*/
class ProcessErrorReader extends Thread {
    BufferedReader r = null;
   
    public void run() {
  String errline = null;
  try {
      errline = r.readLine();
      if (errline != null) {
    System.err.println("*** CgiError: " + errline);
      }
  } catch (Exception ex) {
  } finally {
      try { r.close(); } catch (IOException ioex) {}
  }
    }
   
    ProcessErrorReader(Process proc) {
  r = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
    }
}

/**
* Handle CGI scripts.
*/
public class CgiFrame extends HTTPFrame {

    private final static
  String STATE_EXTRA_PATH = "org.w3c.jigsaw.frames.CgiFrame.extraPath";

    /**
     * Attribute index - The interpreter to use, if any.
     */
    protected static int ATTR_INTERPRETER = -1;
    /**
     * Attribute index - The array of string that makes the command to run.
     */
    protected static int ATTR_COMMAND = -1 ;
    /**
     * Attribute index - Does the script takes care of its headers ?
     */
    protected static int ATTR_NOHEADER = -1 ;
    /**
     * Attribute index - Does the script generates the form on GET ?
     */
    protected static int ATTR_GENERATES_FORM = -1 ;
    /**
     * Attribute index - Do DNS, to fill in REMOTE_HOST env var.
     */
    protected static int ATTR_REMOTE_HOST = -1;
    /**
     * Attribute index - Turn the script in debug mode.
     */
    protected static int ATTR_CGI_DEBUG = -1;
    /**
     * Attribute index - Additional environment vars
     */
    protected static int ATTR_ENV = -1;

    static {
  Attribute a   = null ;
  Class     cls = null ;
  try {
      cls = Class.forName("org.w3c.jigsaw.frames.CgiFrame") ;
  } catch (Exception ex) {
      ex.printStackTrace() ;
      System.exit(1) ;
  }
  // The interpreter attribute:
  a = new StringAttribute("interpreter"
        , null
        , Attribute.EDITABLE);
  ATTR_INTERPRETER = AttributeRegistry.registerAttribute(cls, a);
  // The command attribute:
  a = new StringArrayAttribute("command"
             , null
             , Attribute.MANDATORY|Attribute.EDITABLE);
  ATTR_COMMAND = AttributeRegistry.registerAttribute(cls, a) ;
  // The noheader attribute:
  a = new BooleanAttribute("noheader"
         , Boolean.FALSE
         , Attribute.EDITABLE) ;
  ATTR_NOHEADER = AttributeRegistry.registerAttribute(cls, a) ;
  // The generates form attribute
  a = new BooleanAttribute("generates-form"
         , Boolean.TRUE
         , Attribute.EDITABLE) ;
  ATTR_GENERATES_FORM = AttributeRegistry.registerAttribute(cls, a);
  // Registerr the DODNS attribute.
  a = new BooleanAttribute("remote-host"
         , null
         , Attribute.EDITABLE);
  ATTR_REMOTE_HOST = AttributeRegistry.registerAttribute(cls, a);
  // Register the debug mode flag:
  a = new BooleanAttribute("cgi-debug"
         , Boolean.FALSE
         , Attribute.EDITABLE);
  ATTR_CGI_DEBUG = AttributeRegistry.registerAttribute(cls, a);
  // The env attribute:
  a = new PropertiesAttribute("environment"
            , null
            , Attribute.EDITABLE);
  ATTR_ENV = AttributeRegistry.registerAttribute(cls, a) ;
    }

    /**
     * Get the interpreter to use to execute the script.
     * This is most usefull for operating systems that don't have a
     * <code>!#</code> convention ala UNIX.
     * @return The interpreter to run the script.
     */

    public String getInterpreter() {
  return getString(ATTR_INTERPRETER, null);
    }

    /**
     * Get the command string array.
     */

    public String[] getCommand() {
  return (String[]) getValue(ATTR_COMMAND, null) ;
    }

    public ArrayDictionary getUserEnv() {
  return (ArrayDictionary) getValue(ATTR_ENV, null);
    }

    /**
     * Get the noheader flag.
     * @return The boolean value of the noheader flag.
     */

    public boolean checkNoheaderFlag() {
  return getBoolean(ATTR_NOHEADER, false) ;
    }

    /**
     * Get the generates form flag.
     * @return The boolean value of the generates form flag.
     */

    public boolean checkGeneratesFormFlag() {
  return getBoolean(ATTR_GENERATES_FORM, true) ;
    }

    /**
     * Get the remote host attribute value.
     * If turned on, this flag will enable the REMOTE_HOST env var computation.
     * @return A boolean.
     */

    public boolean checkRemoteHost() {
  return getBoolean(ATTR_REMOTE_HOST, false);
    }

    /**
     * Get the CGI debug flag.
     * @return The boolean value of the CGI debug flag.
     */

    public boolean checkCgiDebug() {
  return getBoolean(ATTR_CGI_DEBUG, false);
    }

    /**
     * Turn the given header name into it's env var canonical name.
     * This guy is crazy enough to run CGI scripts, he can pay for that
     * overhead.
     * @param name The header name.
     * @return A String giving the official env variable name for that header.
     */

    public String getEnvName(String name) {
  int          sl = name.length();
  StringBuffer sb = new StringBuffer(5+sl);
  sb.append("HTTP_");
  for (int i = 0 ; i < sl ; i++) {
      char ch = name.charAt(i);
      sb.append((ch == '-') ? '_' : Character.toUpperCase(ch));
  }
  return sb.toString();
    }

    /**
     * Get this resource Etag
     * @return an instance of HttpEntityTag, or <strong>null</strong> if not
     *    defined.
     */
    public HttpEntityTag getETag() {
  if (etag == null) {
      HttpEntityTag netag = super.getETag();
      if (netag != null) {
    etag.setWeak(true);
      }
  }
  return etag;
    }

    /**
     * Handle the CGI script output.
     * This methods handles the CGI script output. Depending on the
     * value of the <strong>noheader</strong> attribute it either:
     * <ul>
     * <li>Sends back the script output directly,</li>
     * <li>Parses the script output, looking for a status header or a
     * location header, or a content-length header, or any combination
     * of those three.
     * </ul>
     * @param process The underlying CGI process.
     * @param request The processed request.
     * @exception ProtocolException If an HTTP error
     * should be sent back to the client.
     */

    protected Reply handleCGIOutput (Process process, Request request)
  throws ProtocolException
    {
  // first, take care of error stream
  (new ProcessErrorReader(process)).start();
  // No header script don't deserve attention:
  if ( checkNoheaderFlag() ) {
      Reply reply = request.makeReply(HTTP.NOHEADER) ;
      reply.setStream (process.getInputStream()) ;
      return reply ;
  }
  // Check for debugging mode:
  if ( checkCgiDebug() ) {
      Reply reply = request.makeReply(HTTP.OK);
      reply.setContentType(MimeType.TEXT_PLAIN);
      reply.setStream(process.getInputStream());
      return reply;
  }
  // We MUST parse at least one header:
  MimeParser p = new MimeParser(process.getInputStream(),
              new CGIHeaderHolderFactory());
  Reply           reply  = null ;
  try {
      CGIHeaderHolder h = (CGIHeaderHolder) p.parse();
      // Check for a status code:
      String svalue   = h.getStatus();
      String location = h.getLocation();
      if ( svalue != null ) {
    int status = -1;
    try {
                    String _st = svalue.trim();
        int _space = _st.indexOf(' ');
                    if (_space != -1) {
      _st = _st.substring(0, _space);
        }
        status = Integer.parseInt(_st);
    } catch (Exception ex) {
        // This script has emited an invalid status line:
        String msg = ("Emited an invalid status line ["+
          svalue + "].");
        getServer().errlog(this, msg);
        // Throw an HTTPException:
        reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
        reply.setContent("CGI script emited invalid status.");
        throw new HTTPException(reply);
    }
    // we will use the default for this frame, but remove
    // the length calculated from the script size.
    reply = createDefaultReply(request, status);
    reply.setContentLength(-1);
      } else {
    // No status code available, any location header ?
    if (location != null) {
        reply = request.makeReply(HTTP.FOUND);
    } else {
        reply = createDefaultReply(request, HTTP.OK);
        reply.setContentLength(-1);
    }
      }
      // Set up the location header if needed:
      if ( location != null ) {
    try {
        reply.setLocation(new URL(getURL(request), location));
    } catch (MalformedURLException ex) {
        // This should really not happen:
        getServer().errlog(this, "unable to create location url "+
               location+
               " in base "+getURL(request));
    }
      }
      // And then, the remaining headers:
      Enumeration e = h.enumerateHeaders();
      if ( e != null ) {
    while ( e.hasMoreElements() ) {
        String hname = (String) e.nextElement();
        reply.setValue(hname, (String) h.getValue(hname));
    }
      }
      reply.setStream(p.getInputStream()) ;
  } catch (IOException ex) {
      ex.printStackTrace();
  } catch (MimeParserException ex) {
      // This script has generated invalid output:
      String msg = (getURL(request)
        +": emited invalid output ["+
        ex.getMessage() +"]");
      getServer().errlog(this, msg);
      // Throw an HTTPException:
      Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
      error.setContent("CGI error: unable to parse script headers.") ;
      throw new HTTPException (error) ;
  }
  if (reply != null) {
      reply.setDynamic(true);
  }
  return reply ;
    }

    /**
     * Add an enviornment binding to the given vector.
     * @param name The name of the enviornment variable.
     * @param val Its value.
     * @param into The vector to which accumulate bindings.
     */

    private void addEnv (String name, String val, Vector into) {
  into.addElement (name+"="+val) ;
    }

    /**
     * Prepare the command to run for this CGI script, and run it.
     * @param request The request to handle.
     * @return The running CGI process object.
     * @exception ProtocolException If we weren't able
     * to build the command or the environment.
     * @exception IOException if an IO erro occurs.
     */

    protected Process makeCgiCommand (Request request)
  throws ProtocolException, IOException
    {
  // Check the command attribute first:
  String      query     = null;
  String      command[] = getCommand() ;
  if ( command == null ) {
      Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
      error.setContent("CgiResource mis-configured: it doesn't have a "
           + " command attribute");
      throw new HTTPException(error);
  }
  // Ok:
  Vector      env       = new Vector(32) ;
  httpd       server    = request.getClient().getServer() ;
  InetAddress sadr      = server.getInetAddress() ;
  // Specified environment variables:
  // We do not handle the following variables:
  // - REMOTE_IDENT: would require usage of IDENT protocol.
  // Authentification type, if any:
  String svalue = (String) request.getState(AuthFilter.STATE_AUTHTYPE);
  if ( svalue != null )
      addEnv("AUTH_TYPE", svalue, env);
  // Content length, if available:
  svalue = request.getValue("content-length");
  if ( svalue != null )
      addEnv("CONTENT_LENGTH", svalue, env);
  // Content type, if available:
  svalue = request.getValue("content-type");
  if ( svalue != null )
      addEnv("CONTENT_TYPE", svalue, env);
  // The gateway interface, hopefully 1.1 !
  addEnv ("GATEWAY_INTERFACE", "CGI/1.1", env) ;
  // The PATH_INFO, which I am afraid I still don't understand:
  svalue = (String) request.getState(STATE_EXTRA_PATH);
  if ( svalue == null )
      addEnv ("PATH_INFO", "/", env) ;
  else
      addEnv ("PATH_INFO", svalue, env) ;
  // The query string:
  query = request.getQueryString();
  if ( query != null )
      addEnv("QUERY_STRING", query, env) ;
  // The remote client IP address:
  svalue = request.getClient().getInetAddress().toString();
  addEnv ("REMOTE_ADDR", svalue, env);
  // Authentified user:
  svalue = (String) request.getState(AuthFilter.STATE_AUTHUSER);
  if ( svalue != null )
      addEnv("REMOTE_USER", svalue, env);
  // Remote host name, if allowed:
  if ( checkRemoteHost() ) {
      String host = request.getClient().getInetAddress().getHostName();
      addEnv("REMOTE_HOST", host, env);
  }
  // The request method:
  addEnv ("REQUEST_METHOD", request.getMethod(), env) ;
  // The script name :
  addEnv("SCRIPT_NAME", getURLPath(), env);
  // Server name:
  addEnv ("SERVER_NAME", getServer().getHost(), env) ;
  // Server port:
  svalue = Integer.toString(getServer().getLocalPort());
  addEnv ("SERVER_PORT", svalue, env);
  // Server protocol:
  addEnv ("SERVER_PROTOCOL", request.getVersion(), env) ;
  // Server software:
  addEnv ("SERVER_SOFTWARE", server.getSoftware(), env) ;
  if (getFileResource()!= null) {
      addEnv("PATH_TRANSLATED",
       getFileResource().getFile().getAbsolutePath(), env);
  }

  //Add user env
  ArrayDictionary uenv = getUserEnv();
  if (uenv != null) {
      Enumeration names = uenv.keys();
      while (names.hasMoreElements()) {
    String var = (String)names.nextElement();
    addEnv(var, (String)uenv.get(var), env);
      }
  }
  // All other request fields, yeah, let's lose even more time:
  Enumeration e = request.enumerateHeaderDescriptions(false);
  while ( e.hasMoreElements() ) {
      HeaderDescription d = (HeaderDescription) e.nextElement();
      addEnv(getEnvName(d.getName())
       , request.getHeaderValue(d).toString()
       , env);
  }
  // Command line:
  if ( query != null ) {
      String querycmd[] = new String[command.length+1] ;
      System.arraycopy(command, 0, querycmd, 0, command.length) ;
      querycmd[command.length] = query ;
      command = querycmd ;
  }
  String aenv[] = new String[env.size()] ;
  env.copyInto (aenv) ;
  // Run the process:
  if ( getInterpreter() != null ) {
      String run[] = new String[command.length+1];
      run[0] = getInterpreter();
      System.arraycopy(command, 0, run, 1, command.length);
      return Runtime.getRuntime().exec (run, aenv) ;
  } else {
      return Runtime.getRuntime().exec (command, aenv) ;
  }
    }

    /**
     * Lookup sub-resources.
     * Accumulate the remaning path in some special state of the request.
     * <p>This allows us to implement the <code>PATH_INFO</code>
     * CGI variable properly.
     * @param ls Current lookup state.
     * @param lr Lookup result under construction.
     * @return A boolean <strong>true</strong> if lookup should continue,
     * <strong>false</strong> otherwise.
     * @exception ProtocolException (fixme doc)
     */

    public boolean lookup(LookupState ls, LookupResult lr)
  throws ProtocolException
    {
  // Get the extra path information:
  String extraPath = ls.getRemainingPath(true);
  if ((extraPath == null) || extraPath.equals(""))
      extraPath = "/";
  // Keep this path info into the request, if possible:
  Request request = (Request) ls.getRequest();
  if ( request != null )
      request.setState(STATE_EXTRA_PATH, extraPath);
  lr.setTarget(getResource().getResourceReference());
  return super.lookup(ls, lr);
    }

    /**
     * GET method implementation.
     * this method is splitted into two cases:
     * <p>If the resource is able to generates its form, than run the script
     * to emit the form. Otherwsie, use our super class (FileResource) ability
     * to send the file that contains the form.
     * <p>Note that there is no need to feed the underlying process with
     * data in the GET case.
     * @param request The request to handle.
     * @exception ProtocolException If processing the request failed.
     * @exception ResourceException If the resource got a fatal error.
     */
    public Reply get(Request request)
  throws ProtocolException, ResourceException
   {
       if ( ! checkGeneratesFormFlag() )
     return super.get (request) ;
       Process       process = null ;
       try {
     process = makeCgiCommand (request) ;
       } catch (IOException e) {
     e.printStackTrace();
     Reply error = request.makeReply(HTTP.NOT_FOUND) ;
     error.setContent("The resource's script wasn't found.") ;
     throw new HTTPException (error) ;
       }
       return handleCGIOutput (process, request) ;
   }

    /**
     * Handle the POST method according to CGI/1.1 specification.
     * The request body is sent back to the launched CGI script, as is, and
     * the script output is handled by the handleCGIOutput method.
     * @param request The request to process.
     * @exception ProtocolException If the processing failed.
     * @exception ResourceException If the resource got a fatal error.
     */
    public Reply post(Request request)
  throws ProtocolException, ResourceException
    {
  Process       process = null ;
  // Launch the CGI process:
  try {
      process = makeCgiCommand(request) ;
  } catch (IOException ex) {
      // The process wasn't executable, emit a errlog message:
      String msg = ("The process "+
        getCommand()[0] +" couldn't be executed ["+
        ex.getMessage() + "]");
      getServer().errlog(this, msg);
      // Throw an internal server error:
      Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
      error.setContent("CGI script is misconfigured.");
      throw new HTTPException (error) ;
  }
  // Now feed the process:
  try {
      // Send the 100 status code:
      Client client = request.getClient();
      if ( client != null )
    client.sendContinue();
      InputStream in = request.getInputStream();
      if ( in == null ) {
    // There was no input to that CCI, close process stream
    process.getOutputStream().close();
      } else {
    // Some input to feed the process with:
    (new ProcessFeeder(process, in)).start();
      }
  } catch (IOException ex) {
      // This is most probably a bad request:
      Reply error = request.makeReply(HTTP.BAD_REQUEST);
      error.setContent("The request didn't have a valid input.");
      throw new HTTPException(error);
  }
  return handleCGIOutput(process, request);
    }

    /**
     * At register time, if no command, use a suitable default.
     * THis method will set the command to the identifier, if it is not
     * provided.
     * @param values Default attribute values.
     */

    public void registerResource(FramedResource resource) {
  super.registerResource(resource);
  //if no command is specified look for a file resource attached
  //and get its File absolute path if available.
  if (getCommand() == null) {
      if (getFileResource() != null) {
    try {
        if (getFileResource().getFile() != null) {
      String cmd[] = new String[1];
      cmd[0] = getFileResource().getFile().getAbsolutePath();
      setValue(ATTR_COMMAND, cmd);
        }
    } catch (InvalidParentException ex) {
        //nothing to do
        //probably an indexer operation
    }
      }
  }
    }
}
TOP

Related Classes of org.w3c.jigsaw.frames.CGIHeaderHolderFactory

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.