HTTPNetworkProxy.java
// Copyright (c) ZeroC, Inc.
package com.zeroc.Ice;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
final class HTTPNetworkProxy implements NetworkProxy {
public HTTPNetworkProxy(String host, int port) {
_host = host;
_port = port;
_protocolSupport = Network.EnableBoth;
}
private HTTPNetworkProxy(InetSocketAddress address, int protocolSupport) {
_address = address;
_protocolSupport = protocolSupport;
}
@Override
public void beginWrite(InetSocketAddress endpoint, Buffer buf) {
String addr = Network.addrToString(endpoint);
StringBuilder str = new StringBuilder();
str.append("CONNECT ");
str.append(addr);
str.append(" HTTP/1.1\r\nHost: ");
str.append(addr);
str.append("\r\n\r\n");
byte[] b = str.toString().getBytes(StandardCharsets.US_ASCII);
//
// HTTP connect request
//
buf.resize(b.length, false);
buf.position(0);
buf.b.put(b);
buf.position(0);
buf.limit(buf.size());
}
@Override
public int endWrite(Buffer buf) {
// Once the request is sent, read the response
return buf.b.hasRemaining() ? SocketOperation.Write : SocketOperation.Read;
}
@Override
public void beginRead(Buffer buf) {
//
// Read the HTTP response
//
buf.resize(7, true); // Enough space for reading at least HTTP1.1
buf.position(0);
}
@Override
public int endRead(Buffer buf) {
//
// Check if we received the full HTTP response, if not, continue
// reading otherwise we're done.
//
int end = new HttpParser().isCompleteMessage(buf.b, 0, buf.b.position());
if (end < 0 && !buf.b.hasRemaining()) {
//
// Read one more byte, we can't easily read bytes in advance
// since the transport implenentation might be be able to read
// the data from the memory instead of the socket.
//
buf.resize(buf.size() + 1, true);
return SocketOperation.Read;
}
return SocketOperation.None;
}
@Override
public void finish(Buffer readBuffer, Buffer writeBuffer) {
HttpParser parser = new HttpParser();
parser.parse(readBuffer.b, 0, readBuffer.b.position());
if (parser.status() != 200) {
throw new ConnectFailedException();
}
}
@Override
public NetworkProxy resolveHost(int protocol) {
assert (_host != null);
return new HTTPNetworkProxy(
Network.getAddresses(_host, _port, protocol, false, true).get(0), protocol);
}
@Override
public InetSocketAddress getAddress() {
assert (_address != null); // Host must be resolved.
return _address;
}
@Override
public String getName() {
return "HTTP";
}
@Override
public int getProtocolSupport() {
return _protocolSupport;
}
private String _host;
private int _port;
private InetSocketAddress _address;
private int _protocolSupport;
}