Package org.pasif.server.http

Source Code of org.pasif.server.http.PasAysHttpFileServer$HttpFileHandler

package org.pasif.server.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;

import javax.swing.JTextArea;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
import org.apache.http.nio.ContentDecoder;
import org.apache.http.nio.ContentDecoderChannel;
import org.apache.http.nio.FileContentDecoder;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.NHttpConnection;
import org.apache.http.nio.entity.ConsumingNHttpEntity;
import org.apache.http.nio.entity.ConsumingNHttpEntityTemplate;
import org.apache.http.nio.entity.ContentListener;
import org.apache.http.nio.entity.NFileEntity;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.nio.protocol.AsyncNHttpServiceHandler;
import org.apache.http.nio.protocol.EventListener;
import org.apache.http.nio.protocol.NHttpRequestHandler;
import org.apache.http.nio.protocol.NHttpRequestHandlerResolver;
import org.apache.http.nio.protocol.SimpleNHttpRequestHandler;
import org.apache.http.nio.reactor.IOEventDispatch;
import org.apache.http.nio.reactor.ListeningIOReactor;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.pas.utils.Utils;

public class PasAysHttpFileServer {

    private JTextArea output;
    private int port;
    private String folder;

    public PasAysHttpFileServer(JTextArea output, int port, String folder) {
        this.output = output;
        this.port = port;
        this.folder = folder;
    }

    public void start() {
        HttpParams params = new BasicHttpParams();
        params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE,
                8 * 1024).setBooleanParameter(
                CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true).setParameter(CoreProtocolPNames.ORIGIN_SERVER,
                "HttpComponents/1.1");

        BasicHttpProcessor httpproc = new BasicHttpProcessor();
        httpproc.addInterceptor(new ResponseDate());
        httpproc.addInterceptor(new ResponseServer());
        httpproc.addInterceptor(new ResponseContent());
        httpproc.addInterceptor(new ResponseConnControl());

        AsyncNHttpServiceHandler handler = new AsyncNHttpServiceHandler(
                httpproc, new DefaultHttpResponseFactory(),
                new DefaultConnectionReuseStrategy(), params);

        final HttpFileHandler filehandler = new HttpFileHandler(folder, true);

        NHttpRequestHandlerResolver resolver = new NHttpRequestHandlerResolver() {

            public NHttpRequestHandler lookup(String requestURI) {
                return filehandler;
            }
        };

        handler.setHandlerResolver(resolver);

        // Provide an event logger
        handler.setEventListener(new EventLogger());

        IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(
                handler, params);

        try {
            output.append(Utils.getCurrentTimeToString() + ":开启服务器,端口:9999\n");
            output.setCaretPosition(output.getText().length());
            ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2, params);
            ioReactor.listen(new InetSocketAddress(port));
            ioReactor.execute(ioEventDispatch);
        } catch (InterruptedIOException ex) {
            System.err.println("Interrupted");
        } catch (IOException e) {
            System.err.println("I/O error: " + e.getMessage());
        }
        output.append(Utils.getCurrentTimeToString() + "服务器关闭。\n");
        output.setCaretPosition(output.getText().length());
    }

    class HttpFileHandler extends SimpleNHttpRequestHandler {

        private final String docRoot;
        private final boolean useFileChannels;

        public HttpFileHandler(final String docRoot, boolean useFileChannels) {
            this.docRoot = docRoot;
            this.useFileChannels = useFileChannels;
        }

        public ConsumingNHttpEntity entityRequest(
                final HttpEntityEnclosingRequest request,
                final HttpContext context) throws HttpException, IOException {
            return new ConsumingNHttpEntityTemplate(request.getEntity(),
                    new FileWriteListener(useFileChannels));
        }

        @Override
        public void handle(final HttpRequest request,
                final HttpResponse response, final HttpContext context)
                throws HttpException, IOException {
            String target = request.getRequestLine().getUri();
            final File file = new File(this.docRoot, URLDecoder.decode(target,
                    "UTF-8"));
            if (!file.exists()) {
                response.setStatusCode(HttpStatus.SC_NOT_FOUND);
                NStringEntity entity = new NStringEntity("<html><body><h1>File" + file.getPath() + " not found</h1></body></html>",
                        "UTF-8");
                entity.setContentType("text/html; charset=UTF-8");
                response.setEntity(entity);
            } else if (!file.canRead() || file.isDirectory()) {
                response.setStatusCode(HttpStatus.SC_FORBIDDEN);
                NStringEntity entity = new NStringEntity(
                        "<html><body><h1>Access denied</h1></body></html>",
                        "UTF-8");
                entity.setContentType("text/html; charset=UTF-8");
                response.setEntity(entity);
            } else {
                response.setStatusCode(HttpStatus.SC_OK);
                NFileEntity entity = new NFileEntity(file,
                        "text/html;charset=UTF-8", useFileChannels);
                response.setEntity(entity);
            }
        }
    }

    class FileWriteListener implements ContentListener {

        private final File file;
        private final FileInputStream inputFile;
        private final FileChannel fileChannel;
        private final boolean useFileChannels;
        private long idx = 0;

        public FileWriteListener(boolean useFileChannels) throws IOException {
            this.file = File.createTempFile("tmp", ".tmp", null);
            this.inputFile = new FileInputStream(file);
            this.fileChannel = inputFile.getChannel();
            this.useFileChannels = useFileChannels;
        }

        public void contentAvailable(ContentDecoder decoder, IOControl ioctrl)
                throws IOException {
            long transferred;
            if (useFileChannels && decoder instanceof FileContentDecoder) {
                transferred = ((FileContentDecoder) decoder).transfer(
                        fileChannel, idx, Long.MAX_VALUE);
            } else {
                transferred = fileChannel.transferFrom(new ContentDecoderChannel(decoder), idx,
                        Long.MAX_VALUE);
            }

            if (transferred > 0) {
                idx += transferred;
            }
        }

        public void finished() {
            try {
                inputFile.close();
            } catch (IOException ignored) {
                output.append(Utils.getCurrentTimeToString() + ignored.getMessage());
                output.setCaretPosition(output.getText().length());
            }
            try {
                fileChannel.close();
            } catch (IOException ignored) {
                output.append(Utils.getCurrentTimeToString() + ignored.getMessage());
                output.setCaretPosition(output.getText().length());
            }
        }
    }

    class EventLogger implements EventListener {

        public void connectionOpen(final NHttpConnection conn) {
            output.append(Utils.getCurrentTimeToString() + conn + ":连接到服务器。\n");
            output.setCaretPosition(output.getText().length());
        }

        public void connectionTimeout(final NHttpConnection conn) {
            output.append(Utils.getCurrentTimeToString() + conn + ":连接超时。\n");
            output.setCaretPosition(output.getText().length());
        }

        public void connectionClosed(final NHttpConnection conn) {
            output.append(Utils.getCurrentTimeToString() + conn + ":远程关闭连接。\n");
            output.setCaretPosition(output.getText().length());
        }

        public void fatalIOException(final IOException ex,
                final NHttpConnection conn) {
            System.err.println("I/O error: " + ex.getMessage());
        }

        public void fatalProtocolException(final HttpException ex,
                final NHttpConnection conn) {
            System.err.println("HTTP error: " + ex.getMessage());
        }

        public void fatalProtocolException(org.apache.http.HttpException ex, NHttpConnection conn) {
            System.err.println("HTTP error: " + ex.getMessage());
        }
    }
}
TOP

Related Classes of org.pasif.server.http.PasAysHttpFileServer$HttpFileHandler

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.