This is a great idea. A lot of people are going to say "why not use libcurl like everyone else?". Curl is great but this project is a better idea for client-side code.
libcurl is easy to integrate into C++ but hard to get right (this is not curl's fault). I see a lot of bad example code around the web that works(tm) but is not robust. I've seen so much bad curl code that I was moved to write[0] about some of the problems.
libcurl doesn't use OS-level features. It doesn't pick up the users proxy settings or use the cache or cookie store. This is sometimes what you want but for standard client apps Nfhttp's approach is better.
I agree in general that using native HTTP stacks is a good idea for all sorts of reasons, but it's worth calling out that NFHTTP is actually using CURL under the hood on Linux & Android platforms so this just ultimately wraps the CURL C API in a C++ API. On OSX it is using NSURL which is great, and on Windows it's using Microsoft's cpprestsdk library in order to talk with WinHTTP and UWP.
Honestly the biggest gain by using the platform API is that you get SSL support for free. Otherwise you have to cross compile OpenSSL for every android target you want to support and for a fat universal lib for iOS. Its a giant pain.
That was the reason I used the platform APIs in one app, and it is an awful mess.
Then people use Android 4.0 or Windows 2000/XP, and complain they cannot use TLS1.2. And you cannot use the platform defaults, or Android 4.x fails with TLS1.2, because it is not enabled in the defaults, despite being supported. So you enable TLS1.2 and all ciphers, and then Android 8 fails on TLS1.3 due to a trapdoor cipher. Every device trusts different CAs, so you cannot know if https will work, unless you include all the needed certs rather than using the platform certs. Or the platform API is just completely removed like Apache HttpComponents from Android, and you need to rewrite it.
There is, but it's Java - they would have to write JNI. I don't think there's anything wrong with using CURL. Should probably be a bit careful about calling it "native" though.
I just don't really see the point to how they've gone about this. Cpprestsdk is already structured in a way where writing different native client impls for each platform is part of the design. So, rather than adding more native implementations there, they've put another layer on top of cpprestsdk, and added some new client implementations in this new library, and for others it calls down and uses cpprestsdk's existing implementations.
This seems to fragment things more than if they had simply contributed to (or even forked) Microsoft's project.
I agree, curl is great but the API is very difficult to use. Self plug, I've built my own curl c++ wrapper [0] for making thousands of requests per second (libuv event loop driver) and I find a cleaner API gets new devs into it a lot easier. It's definitely far from feature complete but I get a lot of mileage out of it.
Generally yes. You just 'move' pointers through the callbacks and expose RAII request objects to the end user, they don't see any of the ugliness underneath.
I have written some cross platform mobile apps with djinni and C++ and always use the platform Network interfaces. Its just so much easier than having to worry about SSL/TLS and getting curl to compile.
I've been pointing out to people for some time now that Apple has docs (buried, of course, because it's Apple...) that outright indicate they do things behind the scenes with NSURLSession & co to make battery/radio management better. The effect of people dodging it in cross-platform frameworks has been something I've long wondered about.
I've long wondered about this, as well as the overhead of these cross-platform frameworks bundling an entire HTTP library (if they do? It's never easy to tell). Kudos to Kotlin Multiplatform, it seems that lets you use native APIs whenever you want.
This interested me too so I looked through the source to find out. NFHTTP seems to add 2 clients of its own, one that uses NSURL (for Apple) and another that uses CURL (for Linux). Everything else (WinHTTP, UWP, and the fallback Boost Asio client) simply call down and use the cpprestsdk implementations directly.
Seems like this library offers less itself than it says on the tin, given that 3/5 of its native impls just call down to cpprestsdk. It's a pity that spotify didn't simply add CURL and NSURL clients to cppressdk - that would have been far more useful IMO.
This is also my question. Having C ++ REST SDK as a dependency not only does not answer that but it adds additional questions. Also the duplicate use of libs (C ++ REST SDK already has JSON support).
This library seems to add a HTTP client impl built on top of NSURL, and another on top of CURL. It looks to me like everything else here is provided by Microsoft's CPPRestSDK - WinHTTP, UWP & Boost Asio based clients simply use the CppRestSDK impls under the hood.
Edit: Sorry, I misread your post. To add, cpprestsdk has 2 impls for Windows - one based on top of WinHTTP and the other based on WinRT APIs. On UWP, cpprestsdk uses the WinRT APIs and by extension so does NFHTTP.
What would you suggest instead? This is honest, not sarcastic. Cmake can be very powerful, and I don't know of a better option. For instance, it can even be set up to download the latest binary dependencies, which is very useful.
Downloading the latest binary dependencies is (IMO) not a good idea. You should download a known working version with a fixed hash. This will avoid unexpected version mismatches in production. When you want to upgrade, make it explicit.
As for a better alternative, I would suggest Bazel or Buck.
I meant the latest I have pushed to a specific server I run. This means I can push up and everyone working on the project can fetch them easily. It requires intervention, and I wouldn't push until I've tested thoroughly and made necessary changes.
I appreciate the recommendation, though it seems that bazel is heavily focused on java.
That approach has a scaling problem because it requires the central server not to forget to verify the new version against all of the users. Instead, I think that upgrades should be decided on the user side. That is where the tests etc. live.
Bazel is a multi-language system whose focus is actually on C++. This is because other languages have much simpler compilation models.
I don't see why it would be a downside to have additional language support in your C++ build-system. For example, what happens when you want to do Android?
Upgrades are basically decided by the user by updating their cmake config. It can check a specific page on the server and compare with a page in the repo to see if an update is necessary. The central server doesn't have to do anything, it's just dumb file hosting.
I've got nothing against additional language support, though having to install java to use it is a bit painful. I'll take a look at it; I appreciate the recommendation.
You originally commented that cmake was awkward and required "gluing together". I'll agree that the syntax is a little alien to those of us with a background in c-like syntax, but it's never seemed that clunky. Any reason why?
> Upgrades are basically decided by the user by updating their cmake config.
So why not hash the remote file to ensure integrity, and make the server an immutable store?
> I've got nothing against additional language support, though having to install java to use it is a bit painful. I'll take a look at it; I appreciate the recommendation.
I would prefer if they did not use Java also. However, you do not need to install a JVM to use Bazel since it ships with one internally. To the end user, Java is just an implementation detail.
> I'll agree that the syntax is a little alien to those of us with a background in c-like syntax, but it's never seemed that clunky.
This was all I was trying to say really :)
Looking at the repo, I think it would be considerable tweaking to take a dependency on Nfhttp when you already depend on some of its dependencies. With Bazel (and similar) you have a clear way to glue things together ("workspaces") so you would just ensure that all dependencies take the same workspace.
CMake ergonomics is death by a 1000 cuts. The syntax is unpleasant and the error messages are very poor.
Hehe, seeing this I thought "Cool, this is exactly how Spotify handles separation between the GUI frontend and the backend in the Spotify app" and then I saw the organization name in the URL.. doh!
How does this lib handle proxy settings? Does it provide an API to the current proxy settings on the supported platforms ? And an ability to use or not use the proxy per request?
libcurl is easy to integrate into C++ but hard to get right (this is not curl's fault). I see a lot of bad example code around the web that works(tm) but is not robust. I've seen so much bad curl code that I was moved to write[0] about some of the problems.
libcurl doesn't use OS-level features. It doesn't pick up the users proxy settings or use the cache or cookie store. This is sometimes what you want but for standard client apps Nfhttp's approach is better.
[0] https://sheep.horse/2019/3/using_libcurl_effectively_and_saf...