FileHandler.java :  » Web-Server » pygmy-httpd » pygmy » handlers » Java Open Source

Java Open Source » Web Server » pygmy httpd 
pygmy httpd » pygmy » handlers » FileHandler.java
package pygmy.handlers;

import pygmy.core.*;

import java.io.*;
import java.util.logging.Logger;
import java.text.ParseException;
import java.net.HttpURLConnection;

/**
 * <p>
 * This is the most basic Handler of a web server.  It serves up files from a specified directory.  For all urls
 * matching the url-prefix parameter, it translates those into files on the root files system starting at the root
 * parameter.  It does pay attention to the Range http header parameter, and will send a range of bytes from a
 * request file.  It also sets the <i>file-path</i> request property to the translate local system path of the file.
 * Other handlers could use this so that they don't have to translate the URL into a path.  This handler ignores
 * directory requests, but will serve up default files ( like index.html, if the config parameter is set ).  It does
 * not provide a directory listing see {@link DirectoryHandler} for that functionality.
 * </p>
 *
 * <table class="inner">
 * <tr class="header"><td>Parameter Name</td><td>Explanation</td><td>Default Value</td><td>Required</td></tr>
 * <tr class="row"><td>url-prefix</td><td>The prefix to filter request urls.</td><td>None</td><td>Yes</td></tr>
 * <tr class="altrow"><td>root</td><td>A local system path to the root of the folder to share.</td><td>None</td><td>Yes</td></tr>
 * <tr class="row"><td>default-file</td><td>The name of the default file that should be used if no file is specified in the URL.</td><td>index.html</td><td>No</td></tr>
 * </table>
 */
public class FileHandler extends AbstractHandler implements Handler {
    public static final Logger log = Logger.getLogger( FileHandler.class.getName() );

    public static final ConfigOption ROOT_OPTION = new ConfigOption("root", true, "The path to the directory share files." );
    public static final ConfigOption DEFAULT_FILE_OPTION = new ConfigOption("default-file", "index.html", "The default file to send if no file is specified.");

    public static final String IF_MODIFIED = "If-Modified-Since";
    public static final String LAST_MODIFIED_KEY = "Last-Modified";
    public static final String RANGE_HEADER_KEY = "Range";

    private String root;
    private String defaultFile;

    public boolean initialize(String handlerName, Server server) {
        super.initialize(handlerName, server);
        root = ROOT_OPTION.getProperty( server, handlerName );
        defaultFile = DEFAULT_FILE_OPTION.getProperty( server, handlerName );
        return true;
    }

    protected boolean handleBody( HttpRequest request, HttpResponse response ) throws IOException {
        File file = Http.translatePath( root, request.getUrl().substring( getUrlPrefix().length() ) );
        if( !Http.isSecure( root, file ) ) {
            log.warning( "Access denied to " + file.getAbsolutePath() );
            return false;
        }
        request.putProperty( "file-path", file.getAbsolutePath() );
        if ( file.isDirectory() ) {
            file = new File( file, defaultFile );
        }
        if (file.exists() == false) {
            log.warning( "File " + file.getAbsolutePath() + " was not found." );
            return false;
        }
        String type = getMimeType( file.getName() );
        if( type != null ) {
            sendFile( request, response, file, type );
            return true;
        } else {
            log.warning( "Mime type for file " + file.getAbsolutePath() + " was not found." );
            return false;
        }
    }

    static public void sendFile( HttpRequest request, HttpResponse response, File file, String type ) throws IOException {
        if (file.isFile() == false) {
            response.sendError(HttpURLConnection.HTTP_NOT_FOUND, " not a normal file");
            return;
        }
        if (file.canRead() == false) {
            response.sendError(HttpURLConnection.HTTP_FORBIDDEN, " Permission Denied");
            return;
        }

        if( request.getRequestHeader(IF_MODIFIED) != null ) {
            try {
                long modified = Http.parseTime( request.getRequestHeader(IF_MODIFIED) );
                if( file.lastModified() <= modified ) {
                    response.setStatusCode( HttpURLConnection.HTTP_NOT_MODIFIED );
                    return;
                }
            } catch( ParseException ignore ) {
                // ignore the date.
            }
        }
        InputStream in = new BufferedInputStream( new FileInputStream(file) );
        response.addHeader(LAST_MODIFIED_KEY, Http.formatTime(file.lastModified()) );
        long[] range = getRange( request, file );
        response.setMimeType( type );
        response.sendResponse( in, range[0], range[1] );
    }

    private static long[] getRange( HttpRequest request, File file ) {
        long range[] = new long[2];
        range[0] = 0;
        range[1] = file.length();
        String rangeStr = request.getRequestHeader( RANGE_HEADER_KEY, "bytes=0-" );
        int equalSplit = rangeStr.indexOf("=") + 1;
        int split = rangeStr.indexOf("-");
        if( split < -1 ) {
            try {
                range[0] = Integer.parseInt( rangeStr.substring( equalSplit ) );
            } catch( NumberFormatException e ) {
            }
        } else {
            range[0] = Integer.parseInt( rangeStr.substring( equalSplit, split ) );
            if( split + 1 < rangeStr.length() ) {
                try {
                    range[1] = Integer.parseInt( rangeStr.substring( split + 1, rangeStr.length() ) );
                } catch( NumberFormatException e ) {
                }
            }
        }
        return range;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.