Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2011-2013 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.vertx.core.http.impl;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.ReferenceCountUtil;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.VertxException;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.WebSocket;
import io.vertx.core.http.WebsocketVersion;
import io.vertx.core.http.impl.ws.WebSocketFrameInternal;
import io.vertx.core.impl.ContextImpl;
import io.vertx.core.impl.VertxInternal;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.impl.ConnectionBase;
import io.vertx.core.net.impl.NetSocketImpl;
import io.vertx.core.net.impl.VertxNetHandler;
import io.vertx.core.spi.metrics.HttpClientMetrics;
import java.net.URI;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
/**
*
* This class is optimised for performance when used on the same event loop. However it can be used safely from other threads.
*
* The internal state is protected using the synchronized keyword. If always used on the same event loop, then
* we benefit from biased locking which makes the overhead of synchronized near zero.
*
* @author Tim Fox
*/
class ClientConnection extends ConnectionBase {
private static final Logger log = LoggerFactory.getLogger(ClientConnection.class);
private final HttpClientImpl client;
private final String hostHeader;
private final boolean ssl;
private final String host;
private final int port;
private final ConnectionLifeCycleListener listener;
// Requests can be pipelined so we need a queue to keep track of requests
private final Queue requests = new ArrayDeque<>();
private final Handler exceptionHandler;
private final Object metric;
private final HttpClientMetrics metrics;
private WebSocketClientHandshaker handshaker;
private HttpClientRequestImpl currentRequest;
private HttpClientResponseImpl currentResponse;
private HttpClientRequestImpl requestForResponse;
private WebSocketImpl ws;
ClientConnection(VertxInternal vertx, HttpClientImpl client, Handler exceptionHandler, Channel channel, boolean ssl, String host,
int port, ContextImpl context, ConnectionLifeCycleListener listener, HttpClientMetrics metrics) {
super(vertx, channel, context, metrics);
this.client = client;
this.ssl = ssl;
this.host = host;
this.port = port;
if ((port == 80 && !ssl) || (port == 443 && ssl)) {
this.hostHeader = host;
} else {
this.hostHeader = host + ':' + port;
}
this.listener = listener;
this.exceptionHandler = exceptionHandler;
this.metrics = metrics;
this.metric = metrics.connected(remoteAddress(), remoteName());
}
@Override
protected Object metric() {
return metric;
}
protected HttpClientMetrics metrics() {
return metrics;
}
synchronized HttpClientRequestImpl getCurrentRequest() {
return currentRequest;
}
synchronized void toWebSocket(String requestURI, MultiMap headers, WebsocketVersion vers, String subProtocols,
int maxWebSocketFrameSize, Handler wsConnect) {
if (ws != null) {
throw new IllegalStateException("Already websocket");
}
try {
URI wsuri = new URI(requestURI);
if (!wsuri.isAbsolute()) {
// Netty requires an absolute url
wsuri = new URI((ssl ? "https:" : "http:") + "//" + host + ":" + port + requestURI);
}
WebSocketVersion version =
WebSocketVersion.valueOf((vers == null ?
WebSocketVersion.V13 : vers).toString());
HttpHeaders nettyHeaders;
if (headers != null) {
nettyHeaders = new DefaultHttpHeaders();
for (Map.Entry entry: headers) {
nettyHeaders.add(entry.getKey(), entry.getValue());
}
} else {
nettyHeaders = null;
}
handshaker = WebSocketClientHandshakerFactory.newHandshaker(wsuri, version, subProtocols, false,
nettyHeaders, maxWebSocketFrameSize);
ChannelPipeline p = channel.pipeline();
p.addBefore("handler", "handshakeCompleter", new HandshakeInboundHandler(wsConnect, version != WebSocketVersion.V00));
handshaker.handshake(channel).addListener(future -> {
if (!future.isSuccess() && exceptionHandler != null) {
exceptionHandler.handle(future.cause());
}
});
} catch (Exception e) {
handleException(e);
}
}
private final class HandshakeInboundHandler extends ChannelInboundHandlerAdapter {
private final boolean supportsContinuation;
private final Handler wsConnect;
private final ContextImpl context;
private final Queue