1 /*
   2  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.net.httpserver;
  27 
  28 import java.io.*;
  29 import javax.net.ssl.*;
  30 import java.nio.channels.*;
  31 import java.util.logging.Logger;
  32 import com.sun.net.httpserver.*;
  33 import com.sun.net.httpserver.spi.*;
  34 
  35 /**
  36  * encapsulates all the connection specific state for a HTTP/S connection
  37  * one of these is hung from the selector attachment and is used to locate
  38  * everything from that.
  39  */
  40 class HttpConnection {
  41 
  42     HttpContextImpl context;
  43     SSLEngine engine;
  44     SSLContext sslContext;
  45     SSLStreams sslStreams;
  46 
  47     /* high level streams returned to application */
  48     InputStream i;
  49 
  50     /* low level stream that sits directly over channel */
  51     InputStream raw;
  52     OutputStream rawout;
  53 
  54     SocketChannel chan;
  55     SelectionKey selectionKey;
  56     String protocol;
  57     long time;
  58     volatile long creationTime; // time this connection was created
  59     volatile long rspStartedTime; // time we started writing the response
  60     int remaining;
  61     boolean closed = false;
  62     Logger logger;
  63 
  64     public enum State {IDLE, REQUEST, RESPONSE};
  65     volatile State state;
  66 
  67     public String toString() {
  68         String s = null;
  69         if (chan != null) {
  70             s = chan.toString();
  71         }
  72         return s;
  73     }
  74 
  75     HttpConnection () {
  76     }
  77 
  78     void setChannel (SocketChannel c) {
  79         chan = c;
  80     }
  81 
  82     void setContext (HttpContextImpl ctx) {
  83         context = ctx;
  84     }
  85 
  86     State getState() {
  87         return state;
  88     }
  89 
  90     void setState (State s) {
  91         state = s;
  92     }
  93 
  94     void setParameters (
  95         InputStream in, OutputStream rawout, SocketChannel chan,
  96         SSLEngine engine, SSLStreams sslStreams, SSLContext sslContext, String protocol,
  97         HttpContextImpl context, InputStream raw
  98     )
  99     {
 100         this.context = context;
 101         this.i = in;
 102         this.rawout = rawout;
 103         this.raw = raw;
 104         this.protocol = protocol;
 105         this.engine = engine;
 106         this.chan = chan;
 107         this.sslContext = sslContext;
 108         this.sslStreams = sslStreams;
 109         this.logger = context.getLogger();
 110     }
 111 
 112     SocketChannel getChannel () {
 113         return chan;
 114     }
 115 
 116     synchronized void close () {
 117         if (closed) {
 118             return;
 119         }
 120         closed = true;
 121         if (logger != null && chan != null) {
 122             logger.finest ("Closing connection: " + chan.toString());
 123         }
 124 
 125         if (!chan.isOpen()) {
 126             ServerImpl.dprint ("Channel already closed");
 127             return;
 128         }
 129         try {
 130             /* need to ensure temporary selectors are closed */
 131             if (raw != null) {
 132                 raw.close();
 133             }
 134         } catch (IOException e) {
 135             ServerImpl.dprint (e);
 136         }
 137         try {
 138             if (rawout != null) {
 139                 rawout.close();
 140             }
 141         } catch (IOException e) {
 142             ServerImpl.dprint (e);
 143         }
 144         try {
 145             if (sslStreams != null) {
 146                 sslStreams.close();
 147             }
 148         } catch (IOException e) {
 149             ServerImpl.dprint (e);
 150         }
 151         try {
 152             chan.close();
 153         } catch (IOException e) {
 154             ServerImpl.dprint (e);
 155         }
 156     }
 157 
 158     /* remaining is the number of bytes left on the lowest level inputstream
 159      * after the exchange is finished
 160      */
 161     void setRemaining (int r) {
 162         remaining = r;
 163     }
 164 
 165     int getRemaining () {
 166         return remaining;
 167     }
 168 
 169     SelectionKey getSelectionKey () {
 170         return selectionKey;
 171     }
 172 
 173     InputStream getInputStream () {
 174             return i;
 175     }
 176 
 177     OutputStream getRawOutputStream () {
 178             return rawout;
 179     }
 180 
 181     String getProtocol () {
 182             return protocol;
 183     }
 184 
 185     SSLEngine getSSLEngine () {
 186             return engine;
 187     }
 188 
 189     SSLContext getSSLContext () {
 190             return sslContext;
 191     }
 192 
 193     HttpContextImpl getHttpContext () {
 194             return context;
 195     }
 196 }