-1

Я пытаюсь сделать:Httpcomponents httpcore и HttpClient HTTP_STATUS 400

  1. Отправить запрос от HttpClient (основано на HttpComponents HttpClient 4,5).
  2. Получите этот запрос в HttpServer (на основе HttpComponents HttpCore 4.4.1).
  3. HttpServer должен отвечать на HttpClient с разными кодами HttpStatus и строковыми объектами как тело.

Проблема: Если HttpServer ответит кодом статуса 200 (или другими, не отмеченными), то он будет работать нормально и без исключений на стороне сервера. Но если сервер устанавливает код состояния ответа 400, то на сервере HttpServer происходит IOException. Описание на русском: «Удаленный хост принудительно разорвал первое подключение», по-английски я думаю, что это «Клиент закрытой связи». Простой: при статусе 200 нет проблем, на 400 это исключение произошло на сервере.

Исключение строки:

java.io.IOException: Удаленный хост принудительно разорвал существующее подключение на sun.nio.ch.SocketDispatcher.read0 (нативный метод) ~ [па: 1.7.0_51] на sun.nio.ch.SocketDispatcher.read (SocketDispatcher.java:43) ~ [na: 1.7.0_51] at sun.nio.ch.IOUtil.readIntoNativeBuffer (IOUtil.java:223) ~ [na: 1.7.0_51] at sun.nio.ch.IOUtil.read (IOUtil.java:197) ~ [na: 1.7.0_51] at sun.nio.ch.SocketChannelImpl.read (SocketChannelImpl.java:379) ~ [na: 1.7. 0_51] at org.apache.http.nio.reactor.ssl.SSLIOSession.receiveEncryptedData (SSLIOSession.java:449) ~ [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.nio. reactor.ssl.SSLIOSession.isAppInputReady (SSLIOSession.java:503) ~ [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady (AbstractIODispatch. java: 122) ~ [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.BaseIOReactor.readable (BaseIOReactor.java:164) [httpcore-nio-4.4 .1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent (AbstractIOReactor.java:339) [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents (AbstractIOReactor.java:317) [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor .AbstractIOReact or.execute (AbstractIOReactor.java:278) [httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.BaseIOReactor.execute (BaseIOReactor.java:106) [ httpcore-nio-4.4.1.jar: 4.4.1] at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor $ Worker.run (AbstractMultiworkerIOReactor.java:590) [httpcore-nio-4.4.1.jar : 4.4.1] на java.lang.Thread.run (Thread.java:744) [па: 1.7.0_51]

HttpServer код:

HttpProcessor httpproc = HttpProcessorBuilder.create() 
    .add(new ResponseDate()) 
    .add(new ResponseServer("HTTP/1.1 WTX Server")) 
    .add(new ResponseContent()) 
    .add(new ResponseConnControl()).build(); 
UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper(); 
reqistry.register("*", new HttpServerURLHandler()); 
HttpAsyncService protocolHandler = new HttpServerConnectionsHandler(httpproc, reqistry); 
try { 
     String keyStoreFile = Config.getString("HTTPServer.keyStoreFile"); 
     String keyStoreFilePassword = Config.getString("HTTPServer.keyStoreFilePassword"); 
     FileInputStream fin = new FileInputStream(keyStoreFile); 
     KeyStore keystore = KeyStore.getInstance("jks"); 
     keystore.load(fin, keyStoreFilePassword.toCharArray()); 
     KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     kmfactory.init(keystore, keyStoreFilePassword.toCharArray()); 
     KeyManager[] keymanagers = kmfactory.getKeyManagers(); 
     SSLContext sslcontext = SSLContext.getInstance("TLS"); 
     sslcontext.init(keymanagers, null, null); 
     NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory = new SSLNHttpServerConnectionFactory(sslcontext, null, ConnectionConfig.DEFAULT); 

     IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory); 

     IOReactorConfig config = IOReactorConfig.custom() 
       //.setIoThreadCount(10) 
       //.setSoTimeout(5000) 
       //.setConnectTimeout(4000) 
       //.setSoKeepAlive(true) 
       //.setSoReuseAddress(true) 
       //.setRcvBufSize(65535) 
       //.setTcpNoDelay(true) 
       .build(); 

     ListeningIOReactor ioReactor = new DefaultListeningIOReactor(config); 
     ioReactor.listen(new InetSocketAddress(socketAddr, socketPort)); 
     ioReactor.execute(ioEventDispatch); 

    } catch (Exception e) { 
     MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPSERVER.toString()); 
     logger.error("Error while creating HTTP Server instance.", e); 
    } 

URL-код Hander:

public class HttpServerURLHandler implements HttpAsyncRequestHandler<HttpRequest> { 

public static final Logger logger = LoggerFactory.getLogger(HttpServerURLHandler.class); 

private BasicHttpResponse httpResponse = null; 

public HttpServerURLHandler() { 
    super(); 
} 

public HttpAsyncRequestConsumer<HttpRequest> processRequest(final HttpRequest request, final HttpContext context) { 
    return new BasicAsyncRequestConsumer(); 
} 

public void handle(final HttpRequest httpRequest, final HttpAsyncExchange httpExchange, final HttpContext httpContext) throws HttpException, IOException { 
    String string1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ++++++++++++++++++++++++++++++++++++++++++++++++abcdefghijklmnopqrstuvwxyz"; 
    string1 +=  "ABCDEFGHIJKLMNOPQRSTUVWXYZ++++++++++++++++++++++++++++++++++++++++++++++++abcdefghijklmnopqrstuvwxyz"; 

    int httpCode = 400; 

    String httpCodeString = EnglishReasonPhraseCatalog.INSTANCE.getReason(httpCode, Locale.ENGLISH); 
    BasicHttpResponse httpResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, httpCode, httpCodeString); 
    NStringEntity answerEntity = new NStringEntity(stringXML, Consts.UTF_8); 
    httpResponse.setEntity(answerEntity); 
    httpExchange.submitResponse(new BasicAsyncResponseProducer(httpResponse)); 
} 

}

код клиента:

RequestConfig config = RequestConfig.custom() 
      .setConnectTimeout(20000) 
      .setConnectionRequestTimeout(20000) 
      .setSocketTimeout(20000) 
      .build(); 

    SSLContext sslContext = null; 
    try { 
     TrustStrategy trustStrategy = new TrustStrategy() { 
      public boolean isTrusted(X509Certificate[] arg0, String arg1) { 
       return true; 
      } 
     }; 
     sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build(); 
    } catch (Exception e) { 
     MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString()); 
     logger.error("Error while creating SSL context for making HTTP request", e); 
    } 

    CloseableHttpClient client = HttpClientBuilder.create() 
      .setDefaultRequestConfig(config) 
      .setSSLContext(sslContext) 
      .setSSLHostnameVerifier(new NoopHostnameVerifier()) 
      .build(); 

    String stringURL = "https://serverhost:port/"; 
    try { 
     HttpPost post = new HttpPost(stringURL); 
     post.setEntity(httpClientRequest.getEntity()); 
     CloseableHttpResponse httpResponse = client.execute(post); 

     // Consume entity code 
     HttpEntity responseEntity = httpResponse.getEntity(); 
     String stringXMLAnswer = EntityUtils.toString(responseEntity); 
     EntityUtils.consume(responseEntity); 

     // Some next operations with responseEntity 

    } catch (Exception e) { 
     MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString()); 
     logger.error("Error while make request.", e); 
    } finally { 
     try { 
      // Closing connection 
      client.close(); 
     } catch (Exception e) { 
      MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString()); 
      logger.error("Error while closing connection after making request", e); 
     } 
    } 
+0

Вы используете контент сообщения в случае ответа с статусом не 2xx? – oleg

+0

Нет, эта ситуация возникает только в том случае, если сервер задает код статуса ответа 400. Я тестировал коды 200, 401, 402 и нормально работал. Проблема заключается только в 400 кодах ошибок. И я должен добавить некоторую информацию: проблема с кодом 400 существует только с непустым сущностью. Если сервер не установил сущность или не установил пустой объект, он работает нормально. – lanmaster

+0

Вы потребляете контент ответного сообщения или нет? – oleg

ответ

0

Сброс соединения, скорее всего, вызван HTTPCLIENT-1655. Пожалуйста, попробуйте последние 4.5.x snapshot и посмотрите, не устраняет проблему.

0

Я был найти org.apache.http.protocol.ResponseConnControl с кодом

 if (status == HttpStatus.SC_BAD_REQUEST || 
      status == HttpStatus.SC_REQUEST_TIMEOUT || 
      status == HttpStatus.SC_LENGTH_REQUIRED || 
      status == HttpStatus.SC_REQUEST_TOO_LONG || 
      status == HttpStatus.SC_REQUEST_URI_TOO_LONG || 
      status == HttpStatus.SC_SERVICE_UNAVAILABLE || 
      status == HttpStatus.SC_NOT_IMPLEMENTED) { 
     response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); 
     return; 
    } 

Моя проблема воспроизводится этими кодами состояния.

Смежные вопросы