use of com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException in project service-proxy by membrane.
the class Request method parseStartLine.
@Override
public void parseStartLine(InputStream in) throws IOException, EndOfStreamException {
try {
String firstLine = HttpUtil.readLine(in);
Matcher matcher = pattern.matcher(firstLine);
if (matcher.find()) {
method = matcher.group(1);
uri = matcher.group(2);
version = matcher.group(3);
} else if (stompPattern.matcher(firstLine).find()) {
method = firstLine;
uri = "";
version = "STOMP";
} else {
throw new EOFWhileReadingFirstLineException(firstLine);
}
} catch (EOFWhileReadingLineException e) {
if (e.getLineSoFar().length() == 0)
// happens regularly at the end of a keep-alive connection
throw new NoMoreRequestsException();
throw new EOFWhileReadingFirstLineException(e.getLineSoFar());
}
}
use of com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException in project service-proxy by membrane.
the class Response method parseStartLine.
@Override
public void parseStartLine(InputStream in) throws IOException, EndOfStreamException {
String line;
try {
line = HttpUtil.readLine(in);
} catch (EOFWhileReadingLineException e) {
if (e.getLineSoFar().length() == 0)
throw new NoResponseException(e);
throw new EOFWhileReadingFirstLineException(e.getLineSoFar());
}
Matcher matcher = pattern.matcher(line);
boolean find = matcher.find();
if (!find) {
throw new RuntimeException("Invalid server response: " + line);
}
version = matcher.group(1);
statusCode = Integer.parseInt(matcher.group(2));
statusMessage = matcher.group(4);
}
use of com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException in project service-proxy by membrane.
the class HttpClient method call.
public Exchange call(Exchange exc, boolean adjustHostHeader, boolean failOverOn5XX) throws Exception {
if (exc.getDestinations().isEmpty())
throw new IllegalStateException("List of destinations is empty. Please specify at least one destination.");
int counter = 0;
Exception exception = null;
Object trackNodeStatusObj = exc.getProperty(Exchange.TRACK_NODE_STATUS);
boolean trackNodeStatus = trackNodeStatusObj != null && trackNodeStatusObj instanceof Boolean && (Boolean) trackNodeStatusObj;
disableStreamingForRetries(exc);
while (counter < maxRetries) {
Connection con = null;
String dest = getDestination(exc, counter);
HostColonPort target = null;
try {
log.debug("try # " + counter + " to " + dest);
target = init(exc, dest, adjustHostHeader);
if (counter == 0) {
con = exc.getTargetConnection();
if (con != null) {
if (!con.isSame(target.host, target.port)) {
con.close();
con = null;
} else {
con.setKeepAttachedToExchange(true);
}
}
}
SSLProvider sslProvider = getOutboundSSLProvider(exc, target);
if (con == null) {
con = conMgr.getConnection(target.host, target.port, localAddr, sslProvider, connectTimeout, getSNIServerName(exc), proxy, proxySSLContext);
con.setKeepAttachedToExchange(exc.getRequest().isBindTargetConnectionToIncoming());
exc.setTargetConnection(con);
}
if (proxy != null && sslProvider == null)
// if we use a proxy for a plain HTTP (=non-HTTPS) request, attach the proxy credentials.
exc.getRequest().getHeader().setProxyAutorization(proxy.getCredentials());
Response response;
String newProtocol = null;
if (exc.getRequest().isCONNECTRequest()) {
handleConnectRequest(exc, con);
response = Response.ok().build();
newProtocol = "CONNECT";
} else {
response = doCall(exc, con);
if (trackNodeStatus)
exc.setNodeStatusCode(counter, response.getStatusCode());
if (exc.getProperty(Exchange.ALLOW_WEBSOCKET) == Boolean.TRUE && isUpgradeToResponse(response, "websocket")) {
log.debug("Upgrading to WebSocket protocol.");
newProtocol = "WebSocket";
}
if (exc.getProperty(Exchange.ALLOW_TCP) == Boolean.TRUE && isUpgradeToResponse(response, "tcp")) {
log.debug("Upgrading to TCP protocol.");
newProtocol = "TCP";
}
if (exc.getProperty(Exchange.ALLOW_SPDY) == Boolean.TRUE && isUpgradeToResponse(response, "SPDY/3.1")) {
log.debug("Upgrading to SPDY/3.1 protocol.");
newProtocol = "SPDY/3.1";
}
}
if (newProtocol != null) {
setupConnectionForwarding(exc, con, newProtocol, streamPumpStats);
exc.getDestinations().clear();
exc.getDestinations().add(dest);
con.setExchange(exc);
exc.setResponse(response);
return exc;
}
boolean is5XX = 500 <= response.getStatusCode() && response.getStatusCode() < 600;
if (!failOverOn5XX || !is5XX || counter == maxRetries - 1) {
applyKeepAliveHeader(response, con);
exc.getDestinations().clear();
exc.getDestinations().add(dest);
con.setExchange(exc);
response.addObserver(con);
exc.setResponse(response);
return exc;
}
// java.net.SocketException: Software caused connection abort: socket write error
} catch (ConnectException e) {
exception = e;
log.info("Connection to " + (target == null ? dest : target) + " refused.");
} catch (SocketException e) {
if (e.getMessage().contains("Software caused connection abort")) {
log.info("Connection to " + dest + " was aborted externally. Maybe by the server or the OS Membrane is running on.");
} else if (e.getMessage().contains("Connection reset")) {
log.info("Connection to " + dest + " was reset externally. Maybe by the server or the OS Membrane is running on.");
} else {
logException(exc, counter, e);
}
exception = e;
} catch (UnknownHostException e) {
log.warn("Unknown host: " + (target == null ? dest : target));
exception = e;
if (exc.getDestinations().size() < 2) {
// don't retry this host, it's useless. (it's very unlikely that it will work after timeBetweenTriesMs)
break;
}
} catch (EOFWhileReadingFirstLineException e) {
log.debug("Server connection to " + dest + " terminated before line was read. Line so far: " + e.getLineSoFar());
exception = e;
} catch (NoResponseException e) {
throw e;
} catch (Exception e) {
logException(exc, counter, e);
exception = e;
} finally {
if (trackNodeStatus) {
if (exception != null) {
exc.setNodeException(counter, exception);
}
}
}
counter++;
if (exc.getDestinations().size() == 1) {
// as documented above, the sleep timeout is only applied between successive calls to the same destination.
Thread.sleep(timeBetweenTriesMs);
}
}
throw exception;
}
use of com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException in project service-proxy by membrane.
the class HttpServletHandler method run.
public void run() {
try {
srcReq = createRequest();
exchange.received();
try {
DNSCache dnsCache = getTransport().getRouter().getDnsCache();
String ip = dnsCache.getHostAddress(remoteAddr);
exchange.setRemoteAddrIp(ip);
exchange.setRemoteAddr(getTransport().isReverseDNS() ? dnsCache.getHostName(remoteAddr) : ip);
exchange.setRequest(srcReq);
exchange.setOriginalRequestUri(srcReq.getUri());
invokeHandlers();
} catch (AbortException e) {
exchange.finishExchange(true, exchange.getErrorMessage());
writeResponse(exchange.getResponse());
return;
}
// read if not alread read
exchange.getRequest().readBody();
writeResponse(exchange.getResponse());
exchange.setCompleted();
} catch (EndOfStreamException e) {
log.debug("stream closed");
} catch (EOFWhileReadingFirstLineException e) {
log.debug("Client connection terminated before line was read. Line so far: (" + e.getLineSoFar() + ")");
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
exchange.detach();
}
}
use of com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException in project service-proxy by membrane.
the class HttpServerHandler method run.
public void run() {
// see Request.isBindTargetConnectionToIncoming()
Connection boundConnection = null;
try {
updateThreadName(true);
setup();
while (true) {
srcReq = new Request();
endpointListener.setIdleStatus(sourceSocket, true);
try {
srcIn.mark(2);
if (srcIn.read() == -1)
break;
srcIn.reset();
} finally {
endpointListener.setIdleStatus(sourceSocket, false);
}
if (boundConnection != null) {
exchange.setTargetConnection(boundConnection);
boundConnection = null;
}
srcReq.read(srcIn, true);
exchange.received();
if (srcReq.getHeader().getProxyConnection() != null) {
srcReq.getHeader().add(Header.CONNECTION, srcReq.getHeader().getProxyConnection());
srcReq.getHeader().removeFields(Header.PROXY_CONNECTION);
}
process();
if (srcReq.isCONNECTRequest()) {
log.debug("stopping HTTP Server Thread after establishing an HTTP connect");
return;
}
boundConnection = exchange.getTargetConnection();
exchange.setTargetConnection(null);
if (!exchange.canKeepConnectionAlive())
break;
if (exchange.getResponse().isRedirect()) {
break;
}
exchange.detach();
exchange = new Exchange(this);
}
} catch (SocketTimeoutException e) {
log.debug("Socket of thread " + counter + " timed out");
} catch (SocketException se) {
log.debug("client socket closed");
} catch (SSLException s) {
if (showSSLExceptions) {
if (s.getCause() instanceof SSLException)
s = (SSLException) s.getCause();
if (s.getCause() instanceof SocketException)
log.debug("ssl socket closed");
else
log.error("", s);
}
} catch (IOException e) {
log.error("", e);
} catch (EndOfStreamException e) {
log.debug("stream closed");
} catch (AbortException e) {
log.debug("exchange aborted.");
} catch (NoMoreRequestsException e) {
// happens at the end of a keep-alive connection
} catch (NoResponseException e) {
log.debug("No response received. Maybe increase the keep-alive timeout on the server.");
} catch (EOFWhileReadingFirstLineException e) {
log.debug("Client connection terminated before line was read. Line so far: (" + e.getLineSoFar() + ")");
} catch (Exception e) {
log.error("", e);
} finally {
endpointListener.setOpenStatus(sourceSocket, false);
if (boundConnection != null)
try {
boundConnection.close();
} catch (IOException e) {
log.debug("Closing bound connection.", e);
}
closeConnections();
exchange.detach();
updateThreadName(false);
}
}
Aggregations