Java Connection reset exception but working with postman - apache-commons-httpclient

I suddenly started to get a connection reset exception with an api that I have been communicating with for 4 years. The server provider is telling me that he didn't change anything and I didn't either. Whats weird is that I get a success response when I call the same api on postman. I have even tried python to call it but I get the same error.
http client to call the api
HttpClient client = new HttpClient();
client.getHttpConnectionManager().
getParams().setConnectionTimeout(5000);
client.getHttpConnectionManager().
getParams().setSoTimeout(60000);
GetMethod method = new GetMethod(smsUrl);
method.setQueryString(new NameValuePair[] {
new NameValuePair("username", user),
new NameValuePair("password", pass),
new NameValuePair("action", "sendsms"),
new NameValuePair("from", "Sender"),
new NameValuePair("to", toMobile),
new NameValuePair("text", textBody)
});
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
String responseBody = method.getResponseBodyAsString();
System.out.println(new String(responseBody));
}
} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
method.releaseConnection();
}
Error stacktrace
Fatal transport error: Connection reset
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:709)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)

I have also faced similar problem. But solved when upgrading client JDK from 7 to 8.
Ref link

Related

Laravel 9 HTTP client exception handling

I'm trying to catch errors that occur during HTTP client operations. If debugging is enabled APP_DEBUG=true then I get an error trace, if it is off, then it comes json response "message": "Server Error". But I need to catch exceptions, it doesn't work. Tried catch (\Illuminate\Http\Client\ConnectionException $e), but it didn't work. What am I doing wrong?
public function ExampleMethod()
{
try {
$response =
Http::withBasicAuth(env('REMOTE_LOGIN'), env('REMOTE_PASSWORD'))
->accept('application/json')
->retry(3, 2000)->timeout(12)
->withBody("dummy body content", "application/json")
->post($host . $url);
if ($response->ok()) {
//Do something
}
} catch (Exception $e) {
dd("CATCH IT");
}
}
There is an example from the documentation, the domain does not exist, and an exception handler should work somewhere, but it does not work
public function catchExceptins()
{
try {
$url = "domain-is-not-exist.com";
$response = Http::get($url);
if ($response->ok()) {
dd("200 OK");
}
//
if($response->failed()){
dd("FAILED");
}
//Below are the handlers that should work,
//but they do not respond when there is no domain
//or for example if the server response is 505
if($response->serverError()) {
dd("FAILED");
}
if($response->clientError()) {
dd("FAILED");
}
$response->throw(function($response, $e){
dd("FAILED");
})->json();
} catch (Exception $e) {
dd($e);
}
}
Laravel's HTTP client wrapper offers a mechanism for handling errors with a bunch of useful methods.
public function ExampleMethod()
{
try{
$response = Http::withBasicAuth(env('REMOTE_LOGIN'), env('REMOTE_PASSWORD'))
->accept('application/json')
->retry(3, 2000)->timeout(12)
->withBody("dummy body content", "application/json")
->post($host . $url);
//Check for any error 400 or 500 level status code
if($response->failed()){
// process the failure
}
//Check if response has error with 500 level status code
if($response->serverError()) {
//process on server error
}
//Check if response has error with 400 level status code
if($response->clientError()) {
//process on client error
}
// It also allows to throw exceptions on the $response
//If there's no error then the chain will continue and json() will be invoked
$response->throw(function($response, $e){
//do your thing
})->json();
}
catch(\Exception $e) {
//$e->getMessage() - will output "cURL error 6: Could not resolve host" in case of invalid domain
}
}
Laravel Docs - Http Client - Exception Handling
When you set APP_DEBUG=false, it just shows a generic error to the end user for security, but should give you the detailed error inside of the Laravel logs. 'All' APP_DEBUG=true does, is make the development process easier by displaying the log on the front end.
Your Laravel logs should be inside of "/storage/logs".
https://laravel.com/docs/9.x/configuration#debug-mode
https://laravel.com/docs/9.x/errors#configuration

spring boot DeferredResult onError how to invoke the callback?

Need to perform some asynchronous processing in a Rest service without holding up the server's Http threads .
I think DeferredResult would be a good option.
However when I am trying to ensure my callback on error gets called - am not able to do so .
Here is a naive attempt on my part:
#GetMapping("/getErrorResults")
public DeferredResult<ResponseEntity<?>> getDeferredResultsError(){
final String METHOD_NAME = "getDeferredResultsError";
logger.info("START : {}",METHOD_NAME);
DeferredResult<ResponseEntity<?>> deferredOutput = new DeferredResult<>();
ForkJoinPool.commonPool().submit(() -> {
logger.info("processing in separate thread");
int age = 0;
try {
age = age / 0;
}catch(Exception e) {
logger.error("we got some error");
logger.error(e);
throw e;
}
logger.info("after try catch block");
});
deferredOutput.onError((Throwable t) -> {
logger.error("<<< HERE !!! >>>");
deferredOutput.setErrorResult(
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(t.getMessage()));
});
logger.info("done");
return deferredOutput;
}
When I call this Rest endpoint from Postman - I can see in server logs the arithmetic exception by zero but dont see the 'onError' getting invoked.
After some time get a response in Postman as follows:
{
"timestamp": "2019-07-30T09:57:16.854+0000",
"status": 503,
"error": "Service Unavailable",
"message": "No message available",
"path": "/dfr/getErrorResults"
}
So my question is how does the 'onError' get invoked ?
You need to pass the DeferredResult object to the asynchronous operation so you could update it in case of success or failure:
#GetMapping(value = "/getErrorResults")
public DeferredResult<ResponseEntity<String>> getDeferredResultsError() {
DeferredResult<ResponseEntity<String>> deferredResult = new DeferredResult<>();
ForkJoinPool.commonPool().submit(() -> {
System.out.println("Processing...");
int age = 0;
try {
age = age / 0;
deferredResult.setResult(ResponseEntity.ok("completed"));
}catch(Exception e) {
System.out.println("Failed to process: " + e.getMessage());
deferredResult.setErrorResult(
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(e.getMessage()));
}
});
return deferredResult;
}
In the code you posted, you returned the DeferredResult object without passing it to the asynchronous operation. So after your return it, SpringMVC holds the client connection and wait until the DeferredResult object will be assigned with some kind of result. But in your case, the DeferredResult is not held by the asynchronous operation and will never updated so you get "Service Unavailable".
Here you can find working (light) project example.

When trying to use GetPrivateConversationData I get: Security token for MicrosoftAppId: is unauthorized to post to connector

When I try using this code:
StateClient sc = new StateClient(new Microsoft.Bot.Connector.MicrosoftAppCredentials());
BotData userData;
try
{
userData = sc.BotState.GetPrivateConversationData(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
}
catch (Exception ex)
{
throw;
}
I get this error:
"Security token for MicrosoftAppId: is unauthorized to post to connector!"
I am trying to follow the directions here:
http://docs.botframework.com/en-us/csharp/builder/sdkreference/stateapi.html#contextualproperties
but that code simply wont compile. The method signatures are incorrect.
This code appears to work:
StateClient sc = activity.GetStateClient();
BotData userData = sc.BotState.GetPrivateConversationData(activity.ChannelId, activity.Conversation.Id, activity.From.Id);

IPCapture library for Processing returns error

I've been trying to use this library:
ipcapture: Processing library for MJPEG stream acquisition from IP cameras
But I'm not having any luck. I've tried Processing 2 and 3 on a Mac, and keep getting this error:
Unable to open I/O streams: Server returned HTTP response code: 401 for URL: http://192.168.0.14/videostream.cgi
The Foscam IP camera streams to a webpage like this:
http://192.168.0.14/videostream.cgi?user=admin&pwd=
So in Processing I used this:
cam = new IPCapture(this, "http://192.168.0.14/videostream.cgi", "admin", "");
What am I overlooking or misinterpreting?
Thanks.
401 is UnAuthorized, probably means your password did not go through.
I would try still sending the authentication as part of the url.
Try this
1)
cam = new IPCapture(this, "http://192.168.0.14/videostream.cgi?user=admin&pwd=", "", "");
And comment out
try {
conn = (HttpURLConnection)url.openConnection();
//comment out the following line.
//conn.setRequestProperty("Authorization", "Basic " + base64.encode(user + ":" + pass));
httpIn = new BufferedInputStream(conn.getInputStream(), 8192);
}
catch (IOException e) {
System.err.println("Unable to connect: " + e.getMessage());
return;
}
I'm going by what i found at https://code.google.com/p/ipcapture/source/browse/src/IPCapture.java?r=5f5996377689334b4bb7c1d24319f4932694f4a8
Hope it helps!

Volley retry request

I am currently testing out the volley library. But when request fails (404) it doesn't get executed again or at least there are no errors.However there is data missing. Is this the right way to retry a request if it has been failed ?
Thanks in advance
req.setRetryPolicy(new DefaultRetryPolicy(5000,1,1.0f));
queue.add(req);
Usage :
JsonObjectRequest req = null;
for(int i=0;i<profielen.size();i++){
final int pos = i;
req = new JsonObjectRequest(Request.Method.GET, imageLocUrl, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
setImageOnProfile(pos,response.get("thumbnail").toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
req.setRetryPolicy(new DefaultRetryPolicy(5000,1,1.0f));
queue.add(req);
}
No, that is not the right way.
Asides:
HTTP 404 is not a status code I would expect a normally-behaved HTTP
client under normal condition to retry.
You most like are receiving an error via the error listener you
supply to the request, but your error listener is a NOOP so maybe
you're not noticing?
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html has OK
descriptions of the status code meanings.)
The request's retry policy only applies to failures due to: open socket timeouts, socket opening timeouts, HTTP 401s and HTTP 403s. All other failures are not automatically retried, AFAIK.
I think that to retry a 404 with Volley you need to retry it by hand in onErrorResponse.
(Ficus: it would be nice if the RetryPolicy was consulted for error status codes. I would like to be able to set a policy that retries on 503s.)

Resources