⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgiframe.java

📁 很棒的web服务器源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /**     * 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		}	    }	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -