SourceForge: dvbcentral/dvbcentral: changeset 309:988b94996181
Attempt to create more bulletproof server
authorJaroslav Tulach <jtulach@netbeans.org>
Sun Jun 21 17:29:12 2009 +0200 (6 months ago)
changeset 309988b94996181
parent 308 512beacf08ec
child 310 a6db9693b244
Attempt to create more bulletproof server
httpserver/src/net/sf/dvbcentral/http/HttpServer.java
nbproject/project.properties
     1.1 --- a/httpserver/src/net/sf/dvbcentral/http/HttpServer.java	Tue May 19 19:35:21 2009 +0200
     1.2 +++ b/httpserver/src/net/sf/dvbcentral/http/HttpServer.java	Sun Jun 21 17:29:12 2009 +0200
     1.3 @@ -24,6 +24,7 @@
     1.4  import java.net.InetSocketAddress;
     1.5  import java.nio.ByteBuffer;
     1.6  import java.nio.channels.Channels;
     1.7 +import java.nio.channels.ClosedByInterruptException;
     1.8  import java.nio.channels.ReadableByteChannel;
     1.9  import java.nio.channels.SelectableChannel;
    1.10  import java.nio.channels.SelectionKey;
    1.11 @@ -69,6 +70,7 @@
    1.12   * @author Jaroslav Tulach
    1.13   */
    1.14  public final class HttpServer extends Object implements Runnable {
    1.15 +    private final int port;
    1.16      private ServerSocketChannel server;
    1.17      private Selector connection;
    1.18      private Thread processor;
    1.19 @@ -79,6 +81,7 @@
    1.20      private static final Pattern PATTERN_GET = Pattern.compile("(HEAD|GET) */([^ \\?]*)(\\?[^ ]*)?");
    1.21      private static final Pattern PATTERN_LANGS = Pattern.compile(".*^Accept-Language:(.*)$", Pattern.MULTILINE);
    1.22      static final Logger LOG = Logger.getLogger(HttpServer.class.getName());
    1.23 +
    1.24      @SuppressWarnings("deprecation")
    1.25      private void initHtml() {
    1.26          FileUtil.setMIMEType("html", "text/html");
    1.27 @@ -88,18 +91,11 @@
    1.28      }
    1.29      
    1.30      public HttpServer(int port, FileObject pages) throws IOException {
    1.31 +        this.port = port;
    1.32          connection = Selector.open();
    1.33          this.pages = pages;
    1.34          
    1.35 -        server = ServerSocketChannel.open();
    1.36 -        server.configureBlocking(false);
    1.37 -        
    1.38 -        InetSocketAddress address = new InetSocketAddress(port);
    1.39 -        server.socket().bind(address);
    1.40 -        
    1.41 -        server.register(this.connection, SelectionKey.OP_ACCEPT);
    1.42 -        
    1.43 -        LOG.log(Level.INFO, "Listening for HTTP connections on port {0}", address.getPort());
    1.44 +        LOG.log(Level.INFO, "Listening for HTTP connections on port {0}", getServer().socket().getLocalPort());
    1.45          
    1.46          processor = new Thread(this, "HTTP server");
    1.47          processor.start();
    1.48 @@ -108,7 +104,11 @@
    1.49      /** @return the port to listen to
    1.50       */
    1.51      public int getPort() {
    1.52 -        return server.socket().getLocalPort();
    1.53 +        try {
    1.54 +            return getServer().socket().getLocalPort();
    1.55 +        } catch (IOException ex) {
    1.56 +            return port;
    1.57 +        }
    1.58      }
    1.59  
    1.60      public void run() {
    1.61 @@ -119,17 +119,16 @@
    1.62              ServerSocketChannel localServer;
    1.63              Selector localConnection;
    1.64              
    1.65 +            SocketChannel toClose = null;
    1.66 +            try {
    1.67 +                synchronized (this) {
    1.68 +                    localServer = this.getServer();
    1.69 +                    localConnection = this.connection;
    1.70 +                }
    1.71 +
    1.72 +                LOG.log(Level.FINE, "Before select {0}", localConnection.isOpen());
    1.73 +                LOG.log(Level.FINE, "Server {0}", localServer.isOpen());
    1.74              
    1.75 -            synchronized (this) {
    1.76 -                localServer = this.server;
    1.77 -                localConnection = this.connection;
    1.78 -            }
    1.79 -            
    1.80 -            LOG.log(Level.FINE, "Before select {0}", localConnection.isOpen());
    1.81 -            LOG.log(Level.FINE, "Server {0}", localServer.isOpen());
    1.82 -            SocketChannel toClose = null;
    1.83 -            
    1.84 -            try {
    1.85                  int amount = localConnection.select();
    1.86  
    1.87                  LOG.log(Level.FINE, "After select: {0}", amount);
    1.88 @@ -153,11 +152,18 @@
    1.89                      it.remove();
    1.90  
    1.91                      if (key.isAcceptable()) {
    1.92 -                        SocketChannel channel = localServer.accept();
    1.93 -                        channel.configureBlocking(false);
    1.94 -                        SelectionKey another = channel.register(
    1.95 -                            localConnection, SelectionKey.OP_READ
    1.96 -                        );
    1.97 +                        try {
    1.98 +                            SocketChannel channel = localServer.accept();
    1.99 +                            channel.configureBlocking(false);
   1.100 +                            SelectionKey another = channel.register(
   1.101 +                                localConnection, SelectionKey.OP_READ
   1.102 +                            );
   1.103 +                        } catch (ClosedByInterruptException ex) {
   1.104 +                            LOG.log(Level.WARNING, "Interrupted while accepting", ex);
   1.105 +                            server.close();
   1.106 +                            server = null;
   1.107 +                            LOG.log(Level.INFO, "Accept server reset");
   1.108 +                        }
   1.109                          continue PROCESS;
   1.110                      }
   1.111                          
   1.112 @@ -215,7 +221,7 @@
   1.113              LOG.fine("Closing connection");
   1.114              this.connection.close();
   1.115              LOG.fine("Closing server");
   1.116 -            this.server.close();
   1.117 +            this.getServer().close();
   1.118          } catch (IOException ex) {
   1.119              LOG.log(Level.WARNING, null, ex);
   1.120          }
   1.121 @@ -335,6 +341,22 @@
   1.122              return new byte[0];
   1.123          }
   1.124  }
   1.125 +
   1.126 +    /**
   1.127 +     * @return the server
   1.128 +     */
   1.129 +    public ServerSocketChannel getServer() throws IOException {
   1.130 +        if (server == null) {
   1.131 +            server = ServerSocketChannel.open();
   1.132 +            server.configureBlocking(false);
   1.133 +
   1.134 +            InetSocketAddress address = new InetSocketAddress(port);
   1.135 +            server.socket().bind(address);
   1.136 +
   1.137 +            server.register(this.connection, SelectionKey.OP_ACCEPT);
   1.138 +        }
   1.139 +        return server;
   1.140 +    }
   1.141      
   1.142      private static interface Request {
   1.143          public void handle(SelectionKey key, SocketChannel channel) throws IOException;
     2.1 --- a/nbproject/project.properties	Tue May 19 19:35:21 2009 +0200
     2.2 +++ b/nbproject/project.properties	Sun Jun 21 17:29:12 2009 +0200
     2.3 @@ -14,7 +14,7 @@
     2.4  
     2.5  app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
     2.6  app.name=dvbcentral
     2.7 -app.version=0.70
     2.8 +app.version=0.71
     2.9  app.title=DVB Central
    2.10  #branding.token=${app.name}
    2.11