1 /*
   2  * Copyright (c) 2016, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.InputStream;
  25 import java.io.OutputStream;
  26 import java.io.IOException;
  27 import java.net.URI;
  28 import java.net.InetSocketAddress;
  29 import javax.net.ssl.SSLSession;
  30 import jdk.incubator.http.internal.common.HttpHeadersImpl;
  31 import jdk.incubator.http.internal.frame.HeaderFrame;
  32 import jdk.incubator.http.internal.frame.HeadersFrame;
  33 
  34 public class Http2TestExchange {
  35 
  36     final HttpHeadersImpl reqheaders;
  37     final HttpHeadersImpl rspheaders;
  38     final URI uri;
  39     final String method;
  40     final InputStream is;
  41     final BodyOutputStream os;
  42     final SSLSession sslSession;
  43     final int streamid;
  44     final boolean pushAllowed;
  45     final Http2TestServerConnection conn;
  46     final Http2TestServer server;
  47 
  48     int responseCode = -1;
  49     long responseLength;
  50 
  51     Http2TestExchange(int streamid,
  52                       String method,
  53                       HttpHeadersImpl reqheaders,
  54                       HttpHeadersImpl rspheaders,
  55                       URI uri,
  56                       InputStream is,
  57                       SSLSession sslSession,
  58                       BodyOutputStream os,
  59                       Http2TestServerConnection conn,
  60                       boolean pushAllowed) {
  61         this.reqheaders = reqheaders;
  62         this.rspheaders = rspheaders;
  63         this.uri = uri;
  64         this.method = method;
  65         this.is = is;
  66         this.streamid = streamid;
  67         this.os = os;
  68         this.sslSession = sslSession;
  69         this.pushAllowed = pushAllowed;
  70         this.conn = conn;
  71         this.server = conn.server;
  72     }
  73 
  74     public HttpHeadersImpl getRequestHeaders() {
  75         return reqheaders;
  76     }
  77 
  78     public HttpHeadersImpl getResponseHeaders() {
  79         return rspheaders;
  80     }
  81 
  82     public URI getRequestURI() {
  83         return uri;
  84     }
  85 
  86     public String getRequestMethod() {
  87         return method;
  88     }
  89 
  90     public SSLSession getSSLSession() {
  91         return sslSession;
  92     }
  93 
  94     public void close() {
  95         try {
  96             is.close();
  97             os.close();
  98         } catch (IOException e) {
  99             System.err.println("TestServer: HttpExchange.close exception: " + e);
 100             e.printStackTrace();
 101         }
 102     }
 103 
 104     public InputStream getRequestBody() {
 105         return is;
 106     }
 107 
 108     public OutputStream getResponseBody() {
 109         return os;
 110     }
 111 
 112     public void sendResponseHeaders(int rCode, long responseLength) throws IOException {
 113         this.responseLength = responseLength;
 114         if (responseLength > 0 || responseLength < 0) {
 115                 long clen = responseLength > 0 ? responseLength : 0;
 116             rspheaders.setHeader("Content-length", Long.toString(clen));
 117         }
 118 
 119         rspheaders.setHeader(":status", Integer.toString(rCode));
 120 
 121         Http2TestServerConnection.ResponseHeaders response
 122                 = new Http2TestServerConnection.ResponseHeaders(rspheaders);
 123         response.streamid(streamid);
 124         response.setFlag(HeaderFrame.END_HEADERS);
 125         if (responseLength < 0) {
 126             response.setFlag(HeadersFrame.END_STREAM);
 127             os.closeInternal();
 128         }
 129         conn.outputQ.put(response);
 130         os.goodToGo();
 131         System.err.println("Sent response headers " + rCode);
 132     }
 133 
 134     public InetSocketAddress getRemoteAddress() {
 135         return (InetSocketAddress) conn.socket.getRemoteSocketAddress();
 136     }
 137 
 138     public int getResponseCode() {
 139         return responseCode;
 140     }
 141 
 142     public InetSocketAddress getLocalAddress() {
 143         return server.getAddress();
 144     }
 145 
 146     public String getProtocol() {
 147         return "HTTP/2";
 148     }
 149 
 150     public boolean serverPushAllowed() {
 151         return pushAllowed;
 152     }
 153 
 154     public void serverPush(URI uri, HttpHeadersImpl headers, InputStream content) {
 155         OutgoingPushPromise pp = new OutgoingPushPromise(
 156                 streamid, uri, headers, content);
 157         headers.setHeader(":method", "GET");
 158         headers.setHeader(":scheme", uri.getScheme());
 159         headers.setHeader(":authority", uri.getAuthority());
 160         headers.setHeader(":path", uri.getPath());
 161         try {
 162             conn.outputQ.put(pp);
 163             // writeLoop will spin up thread to read the InputStream
 164         } catch (IOException ex) {
 165             System.err.println("TestServer: pushPromise exception: " + ex);
 166         }
 167     }
 168 }