org.apache.http.NoHttpResponseException: XX.XX.XX.XX:443 failed to respond - httpclient

Currently I am using Apache http components client V4.3.5. In my case, I can upload small file(1kb), but it is not working on large file(100kb) when I run the code and get the exception "org.apache.http.NoHttpResponseException: 192.168.128.109:443 failed to respond". Can anyone take a look at my code and let me know what causes my issue?
Here is my code:
public static void main(String[] args) throws IOException,
KeyStoreException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.disableContentCompression();
builder.setSSLSocketFactory(sslsf);
SocketConfig config = SocketConfig.custom().setSoKeepAlive(true).setSoTimeout(300000).build();
builder.setDefaultSocketConfig(config);
CloseableHttpClient httpclient = builder.build();
HttpPost httppost = new HttpPost("https://192.168.128.109/upload");
String encodedAuthorization = DatatypeConverter
.printBase64Binary("admin:itronitr".getBytes());
httppost.setHeader("Authorization", "Basic " + encodedAuthorization);
FileBody bin = new FileBody(new File("c:\\test.txt"));
String boundary = "hK1oPL5_XSfbm6lkCNlKI63rltrew5Bqik0ul";
HttpEntity reqEntity = MultipartEntityBuilder.create()
.setBoundary(boundary).addPart("upfile", bin).build();
httppost.setEntity(reqEntity);
System.out.println(httppost.getEntity().getContentLength());
System.out
.println(httppost.getEntity().getContentType().toString());
CloseableHttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
String content = EntityUtils.toString(resEntity);
System.out.println(content);
} catch (Exception exc) {
exc.printStackTrace();
}
}
Thanks,
Bill

Finally I fix the issue and it is caused by buffer size. By default, buffer size of httpclient is 8k. So I change it to 4k and my code works well.
Here is the code that changes buffer size:
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setBufferSize(4128)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultConnectionConfig(connectionConfig)
.build();

This is what worked for me; may or may not work for you!!
I recently encountered the same issue and tried all the suggestions whatever I was able to find on internet i.e upgrading httpClient to latest version and adding a re-try handler ; but none fixed it for me.
I already had a re-try handler built in my code and was running on the latest Apache client, but it was still failing with the exception Caused by: org.apache.http.NoHttpResponseException: xxxxx:443 failed to respond
So, took me almost 2 days to debug this issue and find the root cause (at-least in my case)
There seems to be a bug in older Java versions up to Java 11.0.3 included that prevents Apache HTTP Client from sending payloads bigger than 16368 bytes caused by https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214339.
I was running on java 11.0.2 and when I upgraded to 11.0.10, it worked for me and I was able to send the bigger payload without any code changes

I also faced the similar problem. I went through many blogs and forums and tried various things but none worked for me. So, I tried a workaround. I added retry handler as below. And it worked for me:
HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.setRetryHandler(new DefaultHttpRequestRetryHandler() {
#Override
public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext context) {
if (exception instanceof NoHttpResponseException) {
return true;
}
return super.retryRequest(exception, executionCount, context);
}
})
.build();
Although it is not a correct fix and just a workaround but it is working for me for now. I'll stick to this solution till I won't get any permanent solution. Sharing it here in case someone might get benefit from it.

Related

Apache FOP: upgrading from 1.1 to 2.1

I am following the migration guide, but I don't seem to get it right.
In FOP 1.1 I have this working code:
public class XsltFactory {
private static final String FO_CONFIG_FILE = "/path/to/fop-config.xml";
private static FopFactory fopFactory;
private static synchronized void initFopFactory(final ServletContext context) throws Exception {
Configuration cfg = new DefaultConfigurationBuilder().build(XsltFactory.class.getResourceAsStream(FO_CONFIG_FILE));
fopFactory = FopFactory.newInstance();
fopFactory.setURIResolver(new ServletContextURIResolver(context));
fopFactory.setUserConfig(cfg);
}
}
I adapted the above code to stick with FOP 2.1:
public class XsltFactory {
private static final String FO_CONFIG_FILE = "/path/to/fop-config.xml";
private static FopFactory fopFactory;
private static synchronized void initFopFactory(final ServletContext context) throws Exception {
Configuration cfg = new DefaultConfigurationBuilder().build(XsltFactory.class.getResourceAsStream(FO_CONFIG_FILE));
FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(
new URI(ServletContextURIResolver.SERVLET_CONTEXT_PROTOCOL),
new URIResolverAdapter(new ServletContextURIResolver(context))
);
fopFactoryBuilder.setConfiguration(cfg);
fopFactory = fopFactoryBuilder.build();
}
}
But I get the following error:
java.lang.Exception: Fail to create PDF
at ....web.controller.PrintPdfController.renderPdf(PrintPdfController.java:181)
[...]
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: java.net.URISyntaxException: Expected scheme-specific part at index 16: servlet-context:
at java.net.URI$Parser.fail(URI.java:2829)
at java.net.URI$Parser.failExpecting(URI.java:2835)
at java.net.URI$Parser.parse(URI.java:3038)
at java.net.URI.<init>(URI.java:595)
[...]
... 42 common frames omitted
The PDF fails to load, since it failed at being created.
EDIT:
After adding + "///" after SERVLET_CONTEXT_PROTOCOL the context, I now get:
Caused by: java.net.MalformedURLException: unknown protocol: servlet-context
at java.net.URL.<init>(URL.java:592)
at java.net.URL.<init>(URL.java:482)
at java.net.URL.<init>(URL.java:431)
at java.net.URI.toURL(URI.java:1096)
at org.apache.fop.fonts.FontDetectorFactory$DefaultFontDetector.detect(FontDetectorFactory.java:94)
... 59 common frames omitted
After a few days of investigation, the migration has finally been done successfully. The problem was coming from the URI resolver, and fixing this problem created new problems, which I solved subsequently.
The guide at https://xmlgraphics.apache.org/fop/2.1/upgrading.html is of relatively limited help.
The core of the problem is the URI resolver. You now have to define a custom resolver, but NOT as in the example provided at:
https://xmlgraphics.apache.org/fop/2.0/servlets.html
ResourceResolver resolver = new ResourceResolver() {
public OutputStream getOutputStream(URI uri) throws IOException {
URL url = getServletContext().getResource(uri.toASCIIString());
return url.openConnection().getOutputStream();
}
public Resource getResource(URI uri) throws IOException {
return new Resource(getServletContext().getResourceAsStream(uri.toASCIIString()));
}
};
The right way of doing it is:
ResourceResolver resolver = new ResourceResolver() {
public OutputStream getOutputStream(URI uri) throws IOException {
URL url = context.getResource(uri.getPath());
return url.openConnection().getOutputStream();
}
public Resource getResource(URI uri) throws IOException {
return new Resource(context.getResourceAsStream(uri.getPath()));
}
};
Instead of uri.toASCIIString(), the correct syntax is uri.getPath().
In addition, we had to remove all "servlet-context:" markup in fonts URIs (in fop-config.xml) and images URIs (in any XSL transformation file or template).
Finally, I got an issue with hyphenation: FOP could not find .hyp files anymore, because for some reason, the baseUri was being used instead of the custom context resolver (I had to dig into FOP's source files to find out). So, I had to modify the getResource method of my custom resolver. I know this is a hack, but it works and it is sufficient for me as I already spent three days on this problem):
public OutputStream getOutputStream(URI uri) throws IOException {
URL url = context.getResource(uri.getPath());
return url.openConnection().getOutputStream();
}
public Resource getResource(URI uri) throws IOException {
InputStream stream = null;
/*
* For some reason, in FOP 2.x, the hyphenator does not use the
* classpath fop-hyph.jar.
*
* This causes trouble as FOP tries to find "none.hyp" in the
* war directory. Setting
* <hyphenation-base>/WEB-INF/hyph</hyphenation-base> in the
* fop-config.xml file does not solve the issue. The only
* solution I could find is to programmatically detect when a
* .hyp file is trying to be loaded. When this occurs, I modify
* the path so that the resolver gets the right resource.
*
* This is a hack, but after spending three days on it, I just
* went straight to the point and got a workaround.
*/
if (uri.getPath().endsWith('.hyp')) {
String relUri = uri.getPath().substring(uri.getPath().indexOf(baseUri.getPath()) + baseUri.getPath().length());
stream = context.getResourceAsStream(FopManager.HYPH_DIR + relUri);
} else {
stream = context.getResourceAsStream(uri.getPath());
}
Resource res = new Resource(stream);
return res;
}
};
Note that I also had to create the none.hyp file manually, since it does not exist in the .hyp files provided by OFFO. I just copied en.hyp and renamed it none.hyp. This solved my last problem.
I hope this saves someone a few days of work ;)

Is RESTEasy RegisterBuiltin.register necessary when using ClientResponse<T>

I am developing a REST client using JBOSS app server and RESTEasy 2.3.6. I've included the following line at the beginning of my code:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
Here's the rest of the snippet:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(host, port, AuthScope.ANY_REALM), new UsernamePasswordCredentials(userid,password));
ClientExecutor executor = createAuthenticatingExecutor(httpclient, host, port);
String uriTemplate = "http://myhost:8080/webapp/rest/MySearch";
ClientRequest request = new ClientRequest(uriTemplate, executor);
request.accept("application/json").queryParameter("query", searchArg);
ClientResponse<SearchResponse> response = null;
List<MyClass> values = null;
try
{
response = request.get(SearchResponse.class);
if (response.getResponseStatus().getStatusCode() != 200)
{
throw new Exception("REST GET failed");
}
SearchResponse searchResp = response.getEntity();
values = searchResp.getValue();
}
catch (ClientResponseFailure e)
{
log.error("REST call failed", e);
}
finally
{
response.releaseConnection();
}
private ClientExecutor createAuthenticatingExecutor(DefaultHttpClient client, String server, int port)
{
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
HttpHost targetHost = new HttpHost(server, port);
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create ClientExecutor.
ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(client, localContext);
return executor;
}
The above is a fairly simple client that employs the ClientRequest/ClientResponse<T> technique. This is documented here. The above code does work (only left out some trivial variable declarations like host and port). It is unclear to me from the JBOSS documentation as to whether I need to run RegisterBuiltin.register first. If I remove the line completely - my code still functions. Do I really need to include the register method call given the approach I have taken? The Docs say I need to run this once per VM. Secondly, if I am required to call it, is it safe to call more than one time in the same VM?
NOTE: I do understand there are newer versions of RESTEasy for JBOSS, we are not there yet.

quickfix SocketInitiator has no response and no exception

I'm trying to connect to a ForexTrading broker FIX API and do some trading.
I tried my best to read through the Quickfix for .net. and almost understand the process of how the quickfix works. However, when I try to initiate the socketinitiator, I failed to do that and there are no complaints and exceptions from VS 2012. It is simply stuck there.
Here's my code:
private void iFind_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
QuickFix.SessionSettings settings = new QuickFix.SessionSettings("C:\\Users\\Administrator\\Documents\\My Box Files(shewenhao#hotmail.com)\\Work With Mr.Liu\\ForexAutoTradingSystem\\ForexAutoTradingSystem\\integralfix.cfg");
IntegralFixAPI integralFixAPIApplication = new IntegralFixAPI();
QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(
integralFixAPIApplication, storeFactory, settings, logFactory);
MessageBox.Show(settings.ToString());
integralFixAPIApplication.MyInitiator = initiator;
initiator.Start();
while (true)
{
Thread.Sleep(200);
MessageBox.Show("true");
}
//initiator.Stop();
}
catch (System.Exception systeme)
{
Console.WriteLine(systeme.Message);
Console.WriteLine(systeme.StackTrace);
}
}
You may notice that I have a MessageBox right below the SocketInitiator and it pops up before this QuickFix.Transport.SocketInitiator line. I do not get it that why I failed at this point. On the page of quickfix .Net http://quickfixn.org/tutorial/creating-an-application, it says that you simply need to replace the threadedacceptor with the socketinitiator. However, I can not pass through this initiation line.

httpunit PutMethodWebRequest throws IOException; bad file descriptor

Could someone explain why this httpunit test case keeps failing in wc.getResponse with "bad file descriptor". I added the is.close() as a guess and moved it before and after the failure but that had no effect. This tests put requests to a Dropwizard app.
public class TestCircuitRequests
{
static WebConversation wc = new WebConversation();
static String url = "http://localhost:8888/funl/circuit/test.circuit1";
#Test
public void testPut() throws Exception
{
InputStream is = new FileInputStream("src/test/resources/TestCircuit.json");
WebRequest rq = new PutMethodWebRequest(url, is, "application/json");
wc.setAuthentication("FUNL", "foo", "bar");
WebResponse response = wc.getResponse(rq);
is.close();
}
No responses? So I'll try myself based on what I learned fighting this.
Httpunit is an old familiar tool that I'd use if I could. But it hasn't been updated in more than two years, so I gather its support for #PUT requests isn't right.
So I converted to Jersey-client instead. After a bunch of struggling I wound up with this code which does seem to work:
#Test
public void testPut() throws Exception
{
InputStream is = new FileInputStream("src/test/resources/TestCircuit.json");
String circuit = StreamUtil.readFully(is);
is.close();
Authenticator.setDefault(new MyAuthenticator());
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
com.sun.jersey.api.client.WebResource service = client.resource(url);
Builder builder = service.accept(MediaType.APPLICATION_JSON);
builder.entity(circuit, MediaType.APPLICATION_JSON);
builder.put(String.class, circuit);
return;
}
This intentionally avoids JAX-RS automatic construction of beans from JSON strings.

Form Instantiation time in Restlet

I am new to Restlet framework and I have the following time issue in the post method of my server resource.
My post method code
#Post
public Representation represent(Representation entity){
try{
//Thread.sleep(1000);
long start = System.currentTimeMillis();
Form aForm = new Form(getRequestEntity());
System.err.println("FORM Instantiation TIME: " + (System.currentTimeMillis()-start));
}catch(Exception ex){
ex.printStackTrace();
}
return new StringRepresentation("hello");
}
On different trails, the output that I am getting is 1900-1999 ms. But if I uncomment the line Thread.sleep(1000), then the time output is 900-999 ms. Can any one please confirm what is happening when instantiation the Form object and why the time is always 1900+ ms. Sorting out this time issue is important for me as I have to implement token based authentication to reduce the post method processing time.
Sorry for late reply. The restlet version I am using is 2.0.7
Here is the details
public static void main(String[] args) throws Exception {
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
VirtualHost aHost = component.getDefaultHost();
aHost.attach("/sample", new MyApplication());
component.getLogger().setLevel(Level.OFF);
component.start();
System.err.println("REST SERVICE STARTED ON PORT NUMBER 8182...");
}
I am running this application in local and not in any Web/App Server.