/** * Executes a method with the current hostConfiguration. * * @throws IOException if an I/O (transport) error occurs. Some transport exceptions can be * recovered from. * @throws HttpException if a protocol exception occurs. Usually protocol exceptions cannot be * recovered from. */ private void executeWithRetry(final HttpMethod method) throws IOException, HttpException { /** How many times did this transparently handle a recoverable exception? */ int execCount = 0; // loop until the method is successfully processed, the retryHandler // returns false or a non-recoverable exception is thrown try { while (true) { execCount++; try { if (LOG.isTraceEnabled()) { LOG.trace("Attempt number " + execCount + " to process request"); } if (this.conn.getParams().isStaleCheckingEnabled()) { this.conn.closeIfStale(); } if (!this.conn.isOpen()) { // this connection must be opened before it can be used // This has nothing to do with opening a secure tunnel this.conn.open(); if (this.conn.isProxied() && this.conn.isSecure() && !(method instanceof ConnectMethod)) { // we need to create a secure tunnel before we can execute the real method if (!executeConnect()) { // abort, the connect method failed return; } } } applyConnectionParams(method); method.execute(state, this.conn); break; } catch (HttpException e) { // filter out protocol exceptions which cannot be recovered from throw e; } catch (IOException e) { LOG.debug("Closing the connection."); this.conn.close(); // test if this method should be retried // ======================================== // this code is provided for backward compatibility with 2.0 // will be removed in the next major release if (method instanceof HttpMethodBase) { MethodRetryHandler handler = ((HttpMethodBase) method).getMethodRetryHandler(); if (handler != null) { if (!handler.retryMethod( method, this.conn, new HttpRecoverableException(e.getMessage()), execCount, method.isRequestSent())) { LOG.debug( "Method retry handler returned false. " + "Automatic recovery will not be attempted"); throw e; } } } // ======================================== HttpMethodRetryHandler handler = (HttpMethodRetryHandler) method.getParams().getParameter(HttpMethodParams.RETRY_HANDLER); if (handler == null) { handler = new DefaultHttpMethodRetryHandler(); } if (!handler.retryMethod(method, e, execCount)) { LOG.debug( "Method retry handler returned false. " + "Automatic recovery will not be attempted"); throw e; } if (LOG.isInfoEnabled()) { LOG.info( "I/O exception (" + e.getClass().getName() + ") caught when processing request: " + e.getMessage()); } if (LOG.isDebugEnabled()) { LOG.debug(e.getMessage(), e); } LOG.info("Retrying request"); } } } catch (IOException e) { if (this.conn.isOpen()) { LOG.debug("Closing the connection."); this.conn.close(); } releaseConnection = true; throw e; } catch (RuntimeException e) { if (this.conn.isOpen()) { LOG.debug("Closing the connection."); this.conn.close(); } releaseConnection = true; throw e; } }