Modern HTTP(s) Support - #977
Conversation
|
@TcT2k , Also, which *nix libcurl isnot available? Embedded platform? Will this be turned off there? Can configure distinguish such cases? |
|
Since most of the applications using this suggested API will be a wxWidgets application, doesn't it make more sense to use events? Also, in order to make this class usable in a secondary thread, a "sync" API should be offered too. (Maybe it can be based on a style bit: wxHTTP_USE_EVENTS?) A side note: These are my thoughts :) |
vadz
left a comment
There was a problem hiding this comment.
This looks like an excellent start, thanks a lot!
I can think of many possible extensions, of course, but mostly I think they can be safely postponed until (much) later. One of the things I think we do need to decide from the beginning is whether we need to provide support for any native async APIs because it seems clear to me that after implementing this the next step is to provide some wxHTTPRequestThread that would send and receive HTTP requests and communicate with the main thread via events because the main thread should never perform any network operations directly. We will almost certainly need to have a generic version of this anyhow because I don't think libcurl provides any async APIs (or does it?), but if there is native async support anywhere, we need to ensure that the API is compatible with it. Notably, it should be possible to cancel a request.
To answer @oneeyeman1, we will have wxUSE_HTTPREQUEST, of course, and configure will set it to 0 if libcurl is not found, but this is not the interesting part.
Thanks again Tobias!
Sounds like a good idea. To support both usage scenarios it would probably make sense to make two methods like
Technically we are always sending something (request headers and the URL) and |
vadz
left a comment
There was a problem hiding this comment.
Nothing really important, API still looks good to me.
It would be nice to have an example of async use in the class description too, I think it could be made quite short using Bind().
Thanks!
|
I've changed to API to async only and changed the structure a little.
|
catalinr
left a comment
There was a problem hiding this comment.
Fixed a few typos, and a couple of other comments.
4a7599e to
08fcaf2
Compare
|
Not really to add any invaluable comment but I would lie to thank @TcT2k and everyone taking this. I would love to test it when the need be (in Windows, Mac and Linux) Great work! |
baf9af2 to
508287e
Compare
|
I've finalized the API to what I think should work with every purposed backend offered by Windows, macOS and libcurl. The Like the current |
|
How will you fix the |
Disabling is probably the most sensible when building with incomplete headers, like with other semi "modern" windows apis used by wxWidgets. |
No real changes, just use the same name as in the other backends for consistency (we could also rename m_sessionImpl in the other ones to m_sessionCURL and m_sessionURLSession respectively, but this would have been more work and the latter name is really not great).
It's better not to have this method in the public class, even if it means that we need to pass a wxWebSessionImpl object to wxWebRequestImpl ctor explicitly now. No real changes.
This allows to retrieve the handles used internally in order to do something not supported by the public API yet.
|
I don't understand what's going on with the tests under AppVeyor... all we get is i.e. it crashes somewhere without any other information. I can't reproduce this locally, I'll try to find some way to get a stack trace from AppVeyor but if I don't manage to do it quickly, I'll just disable the tests there as I really want to merge this, finally, instead of postponing it yet again. |
Also have no idea why this happens, just wanted to let you know that it's possible to connect via remote desktop to appveyor. I don't remember how it works, but it was documented in the appveyor documentation. Maybe it could give some insight. |
|
I am getting the segfault: m_handler is invalid in And seems to be caused by |
|
So I traced it down to calling Notice that this would also generate two |
|
Thanks! This is indeed wrong, and I can reproduce this if I insert some sleep calls into the worker thread (but still not, weirdly, without it). Anyhow, I think:
|
Add a trivial wxWinHTTPCloseHandle() wrapper calling wxLogLastError() if closing the handle failed -- this is really not expected to happen, so make sure to at least log it if it does.
Under MSW, don't set the state to State_Cancelled as soon as Cancel() was called, as the request was still used from the other threads afterwards, resulting in race conditions and crashes. Fix this by just removing the SetState(State_Cancelled) call from the main thread, as it was redundant anyhow. This also makes the behaviour correspond to the documentation, which indicates that Cancel() works asynchronously. Also ensure, for all backends, that we actually cancel the request only once, even if public Cancel() is called multiple times. This required renaming the existing wxWebRequestImpl::Cancel() to DoCancel().
We shouldn't call SetState() to switch to the state that we're currently already in, normally. Add an assert to verify that this indeed doesn't happen. Also improve the logging statement to show both the old and the new states.
|
Unfortunately I've found another problem which I think needs to be fixed now: The simplest solution I can see is to handle Any better ideas/objections to this one? |
This is more consistent with the other backends, which all change the state before actually launching the asynchronous request.
Semantics of this function wasn't really clear and it was used only once, so just inline it at the point of use and define better what happens for various states there. Also use a switch rather than testing for individual states to make sure this code is updated if another state is added in the future. No real changes.
Call GetResponse() only once. Also put the code for State_Completed inside the case for this state in the switch instead of testing for it separately later. No real changes.
This is required in order to allow doing something with the request when it already have a valid native handle, but hasn't actually started yet.
This state can never be returned to, once the state becomes active.
Check that GetNativeHandle() behaves as documented.
No real changes, just try to organize the code in a more logical order.
|
With the latest changes I can call I'll merge this tomorrow (sorry for the short delay, but I might be unavailable next week) if there are no objections. |
Hopefully this might provide more information about the failure of this test in MSVS 2008 build on AppVeyor.
|
I've also found another problem: |
No real changes, just make sure we use an (exhaustive) switch rather than a less obvious sequence of if statements.
This event was processed in a worker thread, which was different from all the other events and also almost surely not thread-safe, so change this and queue it for processing in the main thread instead. Use wxMemoryBuffer instead of non-owning pointer in wxWebRequestEvent and reset the buffer used internally every time to ensure the data is still available by the time the event is processed. Also increase the amount of data downloaded in the "advanced" page of the sample as it has to be greater than wxWEBREQUEST_BUFFER_SIZE, which is currently 64KiB, to have a chance of seeing the value actually change, otherwise all the data arrives in a single event. As it is, using the maximal size supported by the httpbin service, we only get 2 events.
|
I've changed the code to process Any comments/reviews and even reminders of something important I forgot to do are still very welcome, of course! |
|
Congratulations to everyone who made this possible. |
This is my proposal for a simple HTTP request class which would allow modern HTTP and HTTP/s connections based on APIs provided by the operating system.
Please have a look at the interface file to see the complete documentation.
Usage would look like this:
As always any feedback is welcome. I don't have an ETA on when or if I would implement this, but I've experience with the proposed underlying APIs and it should be easy to get started.
Initial todo for a basic (but functional) implementation:
Storage_Fileevent paramsStorage_Noneevent paramswxCredentialEntryDialogFurther improvements in the future could be:
wxCredentialEntryDialogThe following APIs would be used:
Sample App Screenshots