1 /* 2 * Copyright (c) 2015, 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. 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 jdk.incubator.http; 27 28 import java.io.IOException; 29 import java.net.URI; 30 import java.nio.ByteBuffer; 31 import java.util.concurrent.CompletableFuture; 32 import javax.net.ssl.SSLParameters; 33 import jdk.incubator.http.internal.common.Log; 34 import jdk.incubator.http.internal.websocket.RawChannel; 35 36 /** 37 * The implementation class for HttpResponse 38 */ 39 class HttpResponseImpl<T> extends HttpResponse<T> implements RawChannel.Provider { 40 41 final int responseCode; 42 final Exchange<T> exchange; 43 final HttpRequest initialRequest; 44 final HttpRequestImpl finalRequest; 45 final HttpHeaders headers; 46 //final HttpHeaders trailers; 47 final SSLParameters sslParameters; 48 final URI uri; 49 final HttpClient.Version version; 50 //final AccessControlContext acc; 51 RawChannel rawchan; 52 final HttpConnection connection; 53 final Stream<T> stream; 54 final T body; 55 56 public HttpResponseImpl(HttpRequest initialRequest, 57 Response response, 58 T body, Exchange<T> exch) { 59 this.responseCode = response.statusCode(); 60 this.exchange = exch; 61 this.initialRequest = initialRequest; 62 this.finalRequest = exchange.request(); 63 this.headers = response.headers(); 64 //this.trailers = trailers; 65 this.sslParameters = exch.client().sslParameters().orElse(null); 66 this.uri = finalRequest.uri(); 67 this.version = response.version(); 68 this.connection = exch.exchImpl.connection(); 69 this.stream = null; 70 this.body = body; 71 } 72 73 // A response to a PUSH_PROMISE 74 public HttpResponseImpl(Response response, 75 HttpRequestImpl pushRequest, 76 ImmutableHeaders headers, 77 Stream<T> stream, 78 SSLParameters sslParameters, 79 T body) { 80 this.responseCode = response.statusCode(); 81 this.exchange = null; 82 this.initialRequest = null; // ## fix this 83 this.finalRequest = pushRequest; 84 this.headers = headers; 85 //this.trailers = null; 86 this.sslParameters = sslParameters; 87 this.uri = finalRequest.uri(); // TODO: take from headers 88 this.version = HttpClient.Version.HTTP_2; 89 this.connection = stream.connection(); 90 this.stream = stream; 91 this.body = body; 92 } 93 94 private ExchangeImpl<?> exchangeImpl() { 95 return exchange != null ? exchange.exchImpl : stream; 96 } 97 98 @Override 99 public int statusCode() { 100 return responseCode; 101 } 102 103 @Override 104 public HttpRequest request() { 105 return initialRequest; 106 } 107 108 @Override 109 public HttpRequest finalRequest() { 110 return finalRequest; 111 } 112 113 @Override 114 public HttpHeaders headers() { 115 return headers; 116 } 117 118 @Override 119 public T body() { 120 return body; 121 } 122 123 @Override 124 public SSLParameters sslParameters() { 125 return sslParameters; 126 } 127 128 @Override 129 public URI uri() { 130 return uri; 145 * @throws UnsupportedOperationException if getting a RawChannel over 146 * this connection is not supported. 147 * @throws IOException if an I/O exception occurs while retrieving 148 * the channel. 149 */ 150 @Override 151 public synchronized RawChannel rawChannel() throws IOException { 152 if (rawchan == null) { 153 ExchangeImpl<?> exchImpl = exchangeImpl(); 154 if (!(exchImpl instanceof Http1Exchange)) { 155 // RawChannel is only used for WebSocket - and WebSocket 156 // is not supported over HTTP/2 yet, so we should not come 157 // here. Getting a RawChannel over HTTP/2 might be supported 158 // in the future, but it would entail retrieving any left over 159 // bytes that might have been read but not consumed by the 160 // HTTP/2 connection. 161 throw new UnsupportedOperationException("RawChannel is not supported over HTTP/2"); 162 } 163 // Http1Exchange may have some remaining bytes in its 164 // internal buffer. 165 final ByteBuffer remaining =((Http1Exchange<?>)exchImpl).getBuffer(); 166 rawchan = new RawChannelImpl(exchange.client(), connection, remaining); 167 } 168 return rawchan; 169 } 170 171 @Override 172 public CompletableFuture<HttpHeaders> trailers() { 173 throw new UnsupportedOperationException("Not supported yet."); 174 } 175 176 static void logResponse(Response r) { 177 if (!Log.requests()) { 178 return; 179 } 180 StringBuilder sb = new StringBuilder(); 181 String method = r.request().method(); 182 URI uri = r.request().uri(); 183 String uristring = uri == null ? "" : uri.toString(); 184 sb.append('(') 185 .append(method) 186 .append(" ") 187 .append(uristring) 188 .append(") ") 189 .append(r.statusCode()); 190 Log.logResponse(sb.toString()); 191 } 192 } | 1 /* 2 * Copyright (c) 2015, 2017, 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 jdk.incubator.http; 27 28 import java.io.IOException; 29 import java.net.URI; 30 import java.nio.ByteBuffer; 31 import java.util.Optional; 32 import java.util.concurrent.CompletableFuture; 33 import java.util.function.Supplier; 34 import javax.net.ssl.SSLParameters; 35 import jdk.incubator.http.internal.websocket.RawChannel; 36 37 /** 38 * The implementation class for HttpResponse 39 */ 40 class HttpResponseImpl<T> extends HttpResponse<T> implements RawChannel.Provider { 41 42 final int responseCode; 43 final Exchange<T> exchange; 44 final HttpRequest initialRequest; 45 final Optional<HttpResponse<T>> previousResponse; 46 final HttpHeaders headers; 47 final SSLParameters sslParameters; 48 final URI uri; 49 final HttpClient.Version version; 50 RawChannel rawchan; 51 final HttpConnection connection; 52 final Stream<T> stream; 53 final T body; 54 55 public HttpResponseImpl(HttpRequest initialRequest, 56 Response response, 57 HttpResponse<T> previousResponse, 58 T body, 59 Exchange<T> exch) { 60 this.responseCode = response.statusCode(); 61 this.exchange = exch; 62 this.initialRequest = initialRequest; 63 this.previousResponse = Optional.ofNullable(previousResponse); 64 this.headers = response.headers(); 65 //this.trailers = trailers; 66 this.sslParameters = exch.client().sslParameters(); 67 this.uri = response.request().uri(); 68 this.version = response.version(); 69 this.connection = exch.exchImpl.connection(); 70 this.stream = null; 71 this.body = body; 72 } 73 74 // // A response to a PUSH_PROMISE 75 // public HttpResponseImpl(Response response, 76 // HttpRequestImpl pushRequest, 77 // ImmutableHeaders headers, 78 // Stream<T> stream, 79 // SSLParameters sslParameters, 80 // T body) { 81 // this.responseCode = response.statusCode(); 82 // this.exchange = null; 83 // this.initialRequest = null; // ## fix this 84 // this.finalRequest = pushRequest; 85 // this.headers = headers; 86 // //this.trailers = null; 87 // this.sslParameters = sslParameters; 88 // this.uri = finalRequest.uri(); // TODO: take from headers 89 // this.version = HttpClient.Version.HTTP_2; 90 // this.connection = stream.connection(); 91 // this.stream = stream; 92 // this.body = body; 93 // } 94 95 private ExchangeImpl<?> exchangeImpl() { 96 return exchange != null ? exchange.exchImpl : stream; 97 } 98 99 @Override 100 public int statusCode() { 101 return responseCode; 102 } 103 104 @Override 105 public HttpRequest request() { 106 return initialRequest; 107 } 108 109 @Override 110 public Optional<HttpResponse<T>> previousResponse() { 111 return previousResponse; 112 } 113 114 @Override 115 public HttpHeaders headers() { 116 return headers; 117 } 118 119 @Override 120 public T body() { 121 return body; 122 } 123 124 @Override 125 public SSLParameters sslParameters() { 126 return sslParameters; 127 } 128 129 @Override 130 public URI uri() { 131 return uri; 146 * @throws UnsupportedOperationException if getting a RawChannel over 147 * this connection is not supported. 148 * @throws IOException if an I/O exception occurs while retrieving 149 * the channel. 150 */ 151 @Override 152 public synchronized RawChannel rawChannel() throws IOException { 153 if (rawchan == null) { 154 ExchangeImpl<?> exchImpl = exchangeImpl(); 155 if (!(exchImpl instanceof Http1Exchange)) { 156 // RawChannel is only used for WebSocket - and WebSocket 157 // is not supported over HTTP/2 yet, so we should not come 158 // here. Getting a RawChannel over HTTP/2 might be supported 159 // in the future, but it would entail retrieving any left over 160 // bytes that might have been read but not consumed by the 161 // HTTP/2 connection. 162 throw new UnsupportedOperationException("RawChannel is not supported over HTTP/2"); 163 } 164 // Http1Exchange may have some remaining bytes in its 165 // internal buffer. 166 Supplier<ByteBuffer> initial = ((Http1Exchange<?>)exchImpl)::drainLeftOverBytes; 167 rawchan = new RawChannelImpl(exchange.client(), connection, initial); 168 } 169 return rawchan; 170 } 171 172 @Override 173 public String toString() { 174 StringBuilder sb = new StringBuilder(); 175 String method = request().method(); 176 URI uri = request().uri(); 177 String uristring = uri == null ? "" : uri.toString(); 178 sb.append('(') 179 .append(method) 180 .append(" ") 181 .append(uristring) 182 .append(") ") 183 .append(statusCode()); 184 return sb.toString(); 185 } 186 } |