struts 2 Closing network connections after result - networking

I use network connection from a struts application to connect to a network resource and download a file directly to the browser without storing it on the struts running server (need to avoid polluting the struts server with transported files). I use the result type stream to actually download the inputstream from the network resource directly to the user's browser and the inputstream is automatically closed but the network connection that carries the stream is never returned (there is a connection pool as I use httpclient for the network connection).
is there any way anyone can see to actually get code called after the result (of type stream) is finished (file has downloaded to the browser)?

In fact this is indeed solved by an interceptor:
I have written the following in an interceptor of the Action:
public String intercept(ActionInvocation invocation) throws Exception {
try {
return invocation.invoke();
} finally {
DownloadAction da = (DownloadAction) invocation.getAction();
if (null != da && null != da.getResponse()) {
logger.debug("###### connection releasing");
da.getResponse().releaseConnection();
}else{
logger.error("###### connection cannot be released");
}
}
}
Contrary to my previous belief this actually runs only after all results are executed (stream downloaded). It turns out I had been releasing the connection way to soon so I was getting a confusing error in the logs that I thought it was because the interceptor was running too soon. I was wrong.
I hope this may one day help someone else out there.

Related

Azure Functions: An existing connection was forcibly closed by the remote host. Already using static HttpClient

My function invocations keep failing with the error message An existing connection was forcibly closed by the remote host. According to this to mitigate this problem I am to use static Http Clients, which I am already doing, but still the error keeps occurring.
However, I do have 4 of those static clients, which I guess is more than strictly 1. But still I would have thought to fare better with 4 static ones than with multiple (non-static) instances.
I would like to really have only 1 client but I do not know how to make it work. There is one function app which as the below helper class defined in it. In Addition there are 3 services which have been extracted to separate class libraries (because they are used in different projects also) I include in my function app and use via DI. The function app and all of the 3 libs include the below helper class.
public static class Http
{
private static HttpClient _client = new HttpClient();
public static async Task<HttpResponseMessage> GetAsync(string url, Dictionary<string, string>? headers = null)
{
var req = new HttpRequestMessage(HttpMethod.Get, url);
if (headers != null) req._addRequestHeaders(headers);
var response = await _client.SendAsync(req);
response.EnsureSuccessStatusCode();
return response;
}
}
The services in the libs use HTTP to do their own stuff. How would I be able to have the app and all of the libs it references to use the same static http client?
Or do you think the multiple static http classes are not the cause of the problem? There is no such error when running the function app locally in vs code (i.e outside of Azure).
Cheers
Or do you think the multiple static http classes are not the cause of the problem?
This. The error code you're seeing is WSAECONNRESET (10054):
Connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
The fact that you're seeing an exception for this indicates it's an unexpected reset (there are other times when WSAECONNRESET is normal, and HttpClient handles those for you).
There's a lot of possible reasons for unexpected resets. If it's always happening, it could be a security (TLS) setting mismatch, or a malformed request. If it's sometimes happening, it could just be another service restarting/crashing at just the wrong time. Which happens in the cloud, and your service should retry.
There is no such error when running the function app locally in vs code (i.e outside of Azure).
The next thing I'd try is to turn the logging up to 11.

Spring MVC Returns Response Before Completion of Controller Method

I have the following method which is returning an incorrect response to the browser before the method is even complete. This is in Spring 3.2.
#RequestMapping(value="/process1/createEditContract/validate", method=RequestMethod.POST)
public #ResponseBody StatusResponse validateProcess1(#ModelAttribute("contractEditForm") #Valid Process1CreateEditContractDTO dto, BindingResult bindingResult) {
StatusResponse response = new StatusResponse();
response.setSuccess(true);
if (bindingResult.hasErrors()) {
log.debug("Errors found. Processing status response");
response.setSuccess(false);
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fe: fieldErrors) {
response.getMessages().add(messageSource.getMessage(fe, null));
}
}
return response;
}
StatusResponse is a simple object that a javascript function in the JSP reads to generate a Javascript alert stating whether the action was successful or errors occurred. The method makes it all the way through, but as soon as it tries to write the response, I get this:
java.net.SocketException: Software caused connection abort: socket write error
I've been stuck for a day now, any help would be appreciated.
UPDATE
I rolled back from Spring 3.2 to Spring 3.1, and the wording of the error message changed enough to give me more information.
Basically, I'm getting now seeing this:
IllegalStateException: Response already committed
What I don't see is what is causing the response to commit so quickly. Maybe a conflict with the OpenSessionInViewFilter?
This error can occur when the local network system aborts a connection, such as when WinSock closes an established connection after data retransmission fails (receiver never acknowledges data sent on a datastream socket).". See this MSDN article. See also Some information about 'Software caused connection abort.
To prove which component fails I would monitor the TCP/IP communication using wireshark and look who is actaully closing the port, also timeouts could be relevant.
The javascript runs in browser, and your controller runs on server. You cannot pass a complex object from the controller to the javascript without converting it to a textual format such as xml or json.
So you should :
choose a format (say json)
add a produces="application/json" in your RequestMapping annotation
do generate json in your controller method

Why we do not need to close connections opened to a remote EJB server

When I do a JDBC Connection lookup from java, after i am done with it, i am supposed to close the connection.
I wonder how come when we look up a remote EJB, we are still opening some kind of a 'connection' to the EJB remote server. But hey, we never close an EJb remote interface after we are done calling its business methods.
I am assuming you're grabbing remote EJB using JNDI. According to JNDI specification, Context has close method.
http://docs.oracle.com/javase/6/docs/api/javax/naming/Context.html
A standard library should implement this close method and use it as shown in below code.
Code snippet from GenericURLContext.java -
public Object lookup(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.lookup(res.getRemainingName());
} finally {
ctx.close();
}
}
Reference -
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/com/sun/jndi/toolkit/url/GenericURLContext.java#GenericURLContext.lookup%28java.lang.String%29

WebRequest fails when executed in Asp.net server side but passes when executed from Windows application

IIS 8 & Windows 8
I have below sample code which I am trying to check whether a url exists, when I ran from console app it works fine, response is obtained, but when executed from server side ASP.net page it throws socket exception.
Sample code:
try
{
Uri uri = new Uri("HTTPS://test");
WebRequest http = HttpWebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)http.GetResponse();
Stream stream = response.GetResponseStream();
}
catch (UriFormatException sds)
{
}
catch (IOException sdsd)
{
}
Error:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Any suggestions in this regard would helpful.
Without more information, my guess would be that the asp.net application is running under an account which does not have enough privs to access a network resource. You can try changing the account under which the asp.net application runs or impersonate a user with network access rights.

The remote host closed the connection. The error code is 0x80070057

I'm getting a lot of these error messages in my logs on one of my servers and intermittently on two others.
Googling didn't reveal very much information, mostly related to file uploads or downloads being interrupted.
My pages are basically just text files with "ok" in them that only have .aspx extension for future plans, there's no actual code powering the pages. Servers are all Windows Server 2008 RC2 x64 running IIS7 / ASP.NET 4.
Statistically it's happening well under 1% of the time but because of the volume of traffic that still clutters my event log with 2 or 3 of these messages per minute.
Edit:
I tracked down the problem, setting buffering to true stopped it occurring.
I know this has been answered, but on the off chance this helps someone else, it happened in my MVC project sometimes when I had one dbContext set at the top of a repository. When I switched to a using statement for database connections, the error never appeared again.
So, I went from this at the top of each repository:
DbContext db = new DbContext();
To this for each individual connection:
using (DbContext db = new DbContext())
{
//db connection stuff here....
}
Worth saying that no one ever reported seeing the error and no error was ever shown to the browser, but nice to get it off the logs all the same!
Are you returning a Stream?
You might need to close it after the method finishes.
Check out this: Closing Returned Streams in WCF
Here is the code this blog suggests:
public Stream GetFile(string path)
{
Stream fileStream = null;
try
{
fileStream = File.OpenRead(path);
}
catch(Exception)
{
return null;
}
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted +=
new EventHandler(delegate(object sender, EventArgs args)
{
if (fileStream != null) fileStream.Dispose();
});
return fileStream;
}

Resources