/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copyright (c) Non, Inc. 1997 -- All Rights Reserved PROJECT: Servlet Library MODULE: Servlets FILE: PosterServlet.java AUTHOR: John D. Mitchell, Oct 5, 1997 REVISION HISTORY: Name Date Description ---- ---- ----------- JDM 97.10.05 Initial version. JDM 97.10.11 Added temp. directory clearing. DESCRIPTION: This servlet helps to deal with the problem that applets can't do a showDocument() call on a POST request. However, we can work around this by accepting the POST with the servlet, generating a temporary file containing the desired web page output, returning a magic string to the applet for encoding in the URL of a showDocument() call (which is a GET request), accepting the showDocument()'s request, decoding the magic string, and returning the previously generated content/file. Note that all of the calls to log() are commented out since JWS v1.1a seems to crash if log() is used inside of catch blocks. INSTALLATION: Compile this code and put it into the $JSERV_HOME/servlets/net/non/servlets/ directory. Add it to the known servlets list using the adminstration tool. Add a servlet alias for it of "/poster". %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ package net.non.servlets; // Standard Java core packages: import java.io.*; import java.util.*; // Java Servlet packages: import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.http.HttpUtils.*; public class PosterServlet extends HttpServlet { // The file/path name parts for the temporary files. protected String posterTempDir = "posters"; protected String posterTempExt = ".pst"; // Default value for limit of GET & POST information that we'll accept // so as to protect ourselves from a DOS attack. protected int postContentLimit = 100*1024; // 100KB limit. protected int getContentLimit = 1*1024; // 1KB limit. // Random number generator (helps generate temporary filenames. protected Random randomizer = null; // Override getServletInfo(). public String getServletInfo() { return ( "Copyright Non, Inc. 1997 -- " + "John D. Mitchell (john@non.net)\n\n" + "POST HTTP servlet." ); } public void init (ServletConfig sc) { // Create the randomizer. randomizer = new Random (); // Delete all of the (abandoned) generated files. clearTempDir(); } protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Process the incoming information, generate page output, generate // response output. // Set the response type. response.setContentType ("text/plain"); // Check to limit Denial of Service attack. // Limit POST information to a reasonable size. if (postContentLimit < request.getContentLength()) { sendPostFailure (response, "Exceeded POST data length limit. Go away punk!"); /* // Log the error for the SysAdmin. log ("PosterServlet: POST content exceeded limit!"); */ return; } // Build the ouput filename. String fileName = (new Long (randomizer.nextLong())).toString(); File file = null; try { file = new File (posterTempDir + File.separator + fileName + posterTempExt); } catch (Exception e) { // Sigh. Something is really wrong since this is only supposed // to throw up if the path doesn't exist. sendPostFailure (response, "Unable to build output file path!"); /* // Log the error for the SysAdmin. log ("PosterServlet: Not allowed to access :" + file.getAbsolutePath() + ": Please check the permissions."); */ return; } // Open the output file. PrintWriter output = null; try { output = new PrintWriter ( new BufferedWriter ( new FileWriter (file))); } catch (IOException e) { // Hmm... Couldn't open the file. sendPostFailure (response, "Unable to open output file!"); /* // Log the error for the SysAdmin. log ("PosterServlet: Unable to open :" + file.getAbsolutePath() + ": for writing. Please check the permissions."); */ return; } // Spew out the appropriate header shme. output.println (""); output.print ("Poster Servlet Generated Output"); output.println (""); output.println (""); // Now, loop through the request headers and spew them to the file. String headerName = null; Enumeration headers = request.getHeaderNames(); if (headers.hasMoreElements()) { output.println ("

CGI headers:


"); output.println ("

"); } // Deal with the POST contents. if (0 < request.getContentLength()) { String line = null; // Translate all of those incoming bytes to characters. BufferedReader in = new BufferedReader ( new InputStreamReader (request.getInputStream())); output.println ("

POST contents:


"); output.println ("

");


	    // Read each line of input and spew it to the output file.
	    HttpUtils httpUtils = new HttpUtils();
	    try
		{
		while (null != (line = in.readLine()))
		    {
		    try
			{
			Hashtable data = httpUtils.parseQueryString (line);

			// Rip through the list of entries and write out
			// each pair to a single line of the output file.
			String keyName = null;
			Enumeration keys = data.keys();

			// Should really also URLDecode the data but it's
			// not provided as part of the standard Java
			// classes and I don't want to add yet more code to
			// this example.
			while (keys.hasMoreElements())
			    {
			    String[] values = null;

			    keyName = (String) keys.nextElement();
			    output.print (keyName);

			    values = (String[]) data.get (keyName);

			    output.print (" =");
			    if (1 < values.length)
				output.println ("");
			    for (int i = 0; i < values.length; i++)
				{
				output.print ("\t");
				output.println (values[i]);
				}
			    }
			output.println();
			}
		    catch (IllegalArgumentException e)
			{
			// Couldn't seem to parse the query string.
			// Just dump the raw input string to the output.
			output.print (line);
			}
		    }
		}
	    catch (IOException e)
		{
		// Must have been some sort of input error.
		// Just note it and continue.
		output.println ("\n

"); output.println ("Unable to read entire POST contents!"); output.println ("


\n");
		}

	    output.println ("


"); } // Tidy up the output file. output.println (""); output.flush(); output.close(); // Build the POST response. ServletOutputStream out = response.getOutputStream(); out.println (fileName); out.println ("That is the magic value to return as a URL " + "parameter in a showDocument() call to\n" + "get the data generated by this POST call."); } // End of doPost(). protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get magic information, get previously generated output page, // and then generate response. // Set the content type. response.setContentType ("text/html"); // Check to limit Denial of Service attack. // Limit GET information to a reasonable size. if (getContentLimit < request.getContentLength()) { sendGetFailure (response, "Exceeded GET data length limit. Go away punk!"); /* // Log the error for the SysAdmin. log ("PosterServlet: GET content exceeded limit!"); */ return; } // Get the identifier the doPost() method gave the caller, if any. String fileName = request.getQueryString(); if ((null == fileName) || fileName.equals ("")) { // No file name. Tell the caller to use the POST first. sendGetFailure (response, "Invalid or missing output file key!
" + "You must first POST to this servlet " + "to get generate a response file & key"); return; } // Build the input filename. File file = null; try { file = new File (posterTempDir + File.separator + fileName + posterTempExt); } catch (Exception e) { // Sigh. Something is really wrong since this is only supposed // to throw up if the path doesn't exist. sendGetFailure (response, "Unable to get data file. Please start over!"); /* // Log the error for the SysAdmin. log ("PosterServlet: Not allowed to get input file :" + file.getAbsolutePath() + ": Please check the permissions."); */ return; } // Open the file. BufferedReader input = null; try { input = new BufferedReader ( new FileReader (file)); } catch (FileNotFoundException e) { // Non-existent file. Bummer. sendGetFailure (response, "Unable to find data file. Please start over!"); return; } // Read in the data file and spew it out. ServletOutputStream out = response.getOutputStream(); String line = null; try { while (null != (line = input.readLine())) { out.println (line); } } catch (IOException e) { // Must have been some sort of input error. // Just note it and continue. out.println ("\n

"); out.println ("Unable to read entire data file contents!"); out.println ("


\n"); } // Close and delete the input file. input.close(); try { if (!file.delete()) { /* // Log the error for the SysAdmin to deal with. log ("PosterServlet: Unable to delete :" + file.getAbsolutePath() + ":"); */ } } catch (SecurityException e) { /* // Log the error for the SysAdmin to deal with. log ("PosterServlet: Not allowd to delete :" + file.getAbsolutePath() + ": Please check the permissions."); */ } } // End of doGet(). private void sendPostFailure (HttpServletResponse response, String reason) throws IOException { ServletOutputStream out = response.getOutputStream(); out.println ("nil"); out.println (reason); } // End of sendPostFailure(). private void sendGetFailure (HttpServletResponse response, String reason) throws IOException { ServletOutputStream out = response.getOutputStream(); out.println (""); out.print ("Poster Servlet Output Error"); out.println ("

"); out.println (reason); out.println ("


"); } // End of sendGetFailure(). private void clearTempDir() { // Get access to the temporary file directory. File tempDir = null; try { tempDir = new File (posterTempDir); } catch (Exception e) { // Path doesn't exist. /* // Log the error for the SysAdmin. log ("PosterServlet: Unable to access temp directory :" + posterTempDir + ": Please check the permissions."); */ return; } // Make sure that it's a directory. if (!tempDir.isDirectory()) { /* // Not a directory. Note it and bail. log ("PosterServlet: The temp directory :" + posterTempDir + ": is *not* a directory!"); */ return; } // Get list of all of the files in the temporary directory. String[] fileNameList = null; try { fileNameList = tempDir.list(); } catch (SecurityException se) { // Not allowed to muck with the directory. se.printStackTrace(); /* // Log the error for the SysAdmin. log ("PosterServlet: Unable to list temp directory :" + posterTempDir + ": Please check the permissions."); */ return; } // Nuke each of the files in the temporary directory. File curFile = null; String path = tempDir.getPath(); for (int i = 0; i < fileNameList.length; i++) { curFile = new File (path, fileNameList[i]); try { if (!curFile.delete()) { /* // Note the error and continue. log ("PosterServlet: Unable to delete :" + file.getAbsolutePath() + ":"); */ } } catch (SecurityException e) { /* // Just note the error and continue. log ("PosterServlet: Not allowd to delete :" + file.getAbsolutePath() + ": Please check the permissions."); */ } } } // End of clearTempDir(). } // End of PosterServlet.