How can a synchronous WinHttp request be cancelled? - winapi

My service has a thread that may potentially be executing a WinHttpSendRequest when someone tries to stop my service.
The WinHttpCloseHandle documentation says:
An application can terminate an in-progress synchronous or asynchronous request by closing the HINTERNET request handle using WinHttpCloseHandle
But, then later on the same documentation seems to contradict this. It says:
An application should never WinHttpCloseHandle call on a synchronous request. This can create a race condition.
I've found this blog post that seems to agree I can't call WinHttpCloseHandle.
I'm wondering how can I cancel this operation so that my service can be stopped gracefully? I can't really wait for the WinHttpSendRequest to timeout naturally because it takes too long and my service doesn't stop quickly enough. I think windows reports this as an error and then forcefully kills the service in a shutdown.
An ideas would be appreciated.

Calling WinHttpCloseHandle off a background thread to force handle close is perhaps not the best solution. Still it works, and the original caller would receive something like "bad handle" error code and the request would be forcefully terminated.
It would be possibly unsafe to abuse this power, and one would rather implement async requests instead. However, in case of shutting down stale service it is going to work fine.

Related

Why my Go server app exits if I cancel an ongoing HTTP request on the client side

I'm working on a http server using Go.
However I have this weird issue that I don't understand.
When I cancel an ongoing HTTP request on the client (I use Insomnia) side,
the server will exit with logs like this:
2017/05/15 11:25:24 context canceled
Process finished with exit code 1
Can someone help me explain why the server exits itself ?
I use pressly/chi to implement my http handlers.
I figured it out.
Apparently, in one place, I call log.Fatalf() when there's an error, causing the app to exit when the context canceled.
Furthermore, my lack of understanding of how context cancelling works makes it difficult to make debug the problem.

Should I process WM_ENDSESSION, WM_QUERYENDSESSION, both or neither?

If a system is trying to shut down, an app can block this shutdown by overriding OnQueryEndSession() and returning FALSE. Surely that means WM_ENDSESSION is the only definitive message to respond to regarding shutdown.
On the other hand, the top answer to this question quotes no less than Raymond Chen as saying that responding to WM_ENDSESSION is essentially pointless. So this is confusing.
Is there some kind of "best practice" principles to apply in deciding which of these messages (if any) one should respond to for doing what kinds of application shutdown work?
In particular, if neither message is handled, will a shutdown process cause an application to be closed as if the user had closed the application manually (e.g. click on red X close button)?
This article from Microsoft gives a very comprehensive discussion of end-of-session best practice both pre- and post-Vista. The article makes it quite clear that one should assume that if one receives a WM_QUERYENDSESSION then shutdown will occur at some point.
As soon as all applications have responded to the WM_ENDSESSION message, or been forced to terminate within 5 seconds of receiving the WM_ENDSESSION message, Windows may shut down at any time. This may limit what can be done in response to WM_ENDSESSION.
If an application requires more time to clean itself up:
If your application may need more than 5 seconds to complete its shutdown processing in response to WM_ENDSESSION, it should call ShutdownBlockReasonCreate() in its WM_QUERYENDSESSION handler, and promptly respond TRUE to WM_QUERYENDSESSION so as not to block shutdown. It should then perform all shutdown processing in its WM_ENDSESSION handler.
Windows will apparently not send any additional messages to your application to allow it to exit "gracefully" (e.g. WM_CLOSE). Rather, it will simply call TerminateProcess. If you want a graceful close, you have to build it yourself within the above constraints.
You do need to close down your application in WM_ENDSESSION, at least if you want to support the Restart Manager API. I think both MSDN and Raymond are wrong here. (Maybe it changed recently, or they overlooked the Restart Manager?)
The Restart Manager API is used by installers to close and restart exes which have files locked that they need to replace. To support being restarted by it, you call RegisterApplicationRestart and then need to have a window which handles WM_QUERYENDSESSION and WM_ENDSESSION.
If you don't shut down your app in the WM_ENDSESSION handler than it will simply keep running and block the Restart Manager, and in turn the installers trying to use it.
I found this out the hard way. MSDN explicitly says you don't need to call PostQuitMessage, but if I don't do that then my process keep running.
I suspect the documentation didn't realise the Restart Manager is different, and less forceful, compared to what happens when the entire OS shuts down.
(Edit: I should add, this was with a simple ATL COM EXE server, but as far as I can tell there was nothing about that complicating things, and Windows simply wasn't triggering a WM_QUIT to the message loop unless I did it myself.)

Web-Api: When getting a request - give a response but then continue do a job related to the request

We have a web-api based server, and the users do requests.
Many requests have consequences that go beyond the answer that we need to give the user.
So we want to give him/her the answer but then continue processing the implications.
Sometimes we need this "next actions" to happen fast. sometimes we can wait a bit.
I though of the following options:
Before giving the response - open another thread for the job
But seems to me very expensive, and maybe even won't work.
Before giving the response - put the job on some queue that listen to
But seems to me that it might postpone the execution to much
Am I right? Am I wrong?
What are the guidelines/best practices for this kind of questions
I think that the best way to do background processing in that case is to use some queue e.g. azure webjobs or maybe something more complex like NServiceBus. You have to just send message/order processing and return response which inform user that this order has been accepted. There is even special HTTP code (202) for such actions.
Opening another thread is not so good because you lose control on that. There is no easy way to monitor that. What if that thread crash or application pool recycle? You lose all data, user will be waiting forever. It's just not reliable

Boost.Asio SSL ungraceful close

I am trying to handle SSL error scenarios where, for example, SSL async_handshake() is taking too long.
After some time (say 20sec) i want to close this connection (lowest_layer().close()).
I pass shared_ptr with connection object as a parameter to async_handshake(), so object still exists, eventually handshake handler is invoked and object gets destroyed.
But, still I'm getting sporadic crashes! Looks like after close() SSL is still trying to read or operate on read buffer.
So, the basic question - is it safe to hard close() SSL connection?
Any ideas?
Typically the method I've used stop outstanding asynchronous operations on a socket is socket::cancel as described in the documentation. Their handlers will be invoked with asio::error::operation_aborted as the error parameter, which you'll need to handle somehow.
That said, I don't see a problem using close instead of cancel. Though it is difficult to offer much help or advice without some code to analyze.
Note that some Windows platforms have problems when canceling outstanding asynchronous operations. The documentation has suggestions for portable cancelation if your application needs to support Windows.

Restarting a windows service

I want to schedule a restart of my custom services
automatically using a batch file with net stop, net start.
When net stop runs does it abort anything that is being done
immediately?
Just wondering what will happen if in the middle of processing?
Malcolm
It will call into your code asynchronously and it will be up to you to deal with it. You could enact a clean or abort as you see fit.
It really depends on how the service is implemented. "net stop" essentially calls into the service and says "would you kindly stop". Most services will comply with this command and stop in a timely fashion. However there are the bad services which do not comply and refuse to stop. In this case, net stop will take no further action.
It really depends on the service. I suspect most will try to get into a good state before stopping. It isn't a kill.
A service registers to receive events (via RegisterServiceCtrlHandler). When you do a net stop the registered callback will receive a callback with the SERVICE_CONTROL_STOP operation. How the service responds to that callback is up to the service implementation. It would make sense for the service to do regular application shutdown processing.
Like the others said, when you call net stop, it will invoke the OnStop in the Windows Service. If the OnStop does not kill all the threads in the app, or doesn't shut everything down properly, your service might not stop. (I've seen this happen in one of our WCF services: we didn't close the ServiceHost in OnStop, and therefore, the app would not stop at our command - we'd have to kill the process by hand.)
One common pattern I've seen is to try calling stop on the service, and if it doesn't die within a timeout (10 seconds), kill the process by force. As an alternative to batch files, PowerShell has some pretty good support for dealing with services.

Resources