public HttpRequest generateRequest(
final InternalState state,
final InternalConnManager connManager) throws IOException, HttpException {
final HttpClientContext localContext = state.getLocalContext();
final HttpAsyncRequestProducer requestProducer = state.getRequestProducer();
final HttpRoute route = state.getRoute();
final RouteTracker routeTracker = state.getRouteTracker();
final NHttpClientConnection managedConn = connManager.getConnection();
if (!state.isRouteEstablished()) {
int step;
loop:
do {
final HttpRoute fact = routeTracker.toRoute();
step = this.routeDirector.nextStep(route, fact);
switch (step) {
case HttpRouteDirector.CONNECT_TARGET:
this.connmgr.initialize(managedConn, route, localContext);
routeTracker.connectTarget(route.isSecure());
break;
case HttpRouteDirector.CONNECT_PROXY:
this.connmgr.initialize(managedConn, route, localContext);
final HttpHost proxy = route.getProxyHost();
routeTracker.connectProxy(proxy, false);
break;
case HttpRouteDirector.TUNNEL_TARGET:
if (this.log.isDebugEnabled()) {
this.log.debug("[exchange: " + state.getId() + "] Tunnel required");
}
final HttpRequest connect = createConnectRequest(route);
state.setCurrentRequest(HttpRequestWrapper.wrap(connect));
break loop;
case HttpRouteDirector.TUNNEL_PROXY:
throw new HttpException("Proxy chains are not supported");
case HttpRouteDirector.LAYER_PROTOCOL:
this.connmgr.upgrade(managedConn, route, localContext);
routeTracker.layerProtocol(route.isSecure());
break;
case HttpRouteDirector.UNREACHABLE:
throw new HttpException("Unable to establish route: " +
"planned = " + route + "; current = " + fact);
case HttpRouteDirector.COMPLETE:
this.connmgr.routeComplete(managedConn, route, localContext);
state.setRouteEstablished(true);
state.setRouteTracker(null);
break;
default:
throw new IllegalStateException("Unknown step indicator "
+ step + " from RouteDirector.");
}
} while (step > HttpRouteDirector.COMPLETE);
}
HttpRequestWrapper currentRequest = state.getCurrentRequest();
if (currentRequest == null) {
currentRequest = state.getMainRequest();
state.setCurrentRequest(currentRequest);
}
if (state.isRouteEstablished()) {
state.incrementExecCount();
if (state.getExecCount() > 1
&& !requestProducer.isRepeatable()
&& state.isRequestContentProduced()) {
throw new NonRepeatableRequestException("Cannot retry request " +
"with a non-repeatable request entity.");
}
if (this.log.isDebugEnabled()) {