Does C Have a Standerd Library For HTTP2 - c

[Intro]]
I have been practicing C for 4 Months 5 times a Week, I am attempting to make the best possible guess for moving into web server/client programming for HTTP2. I have worked with HTML5 & Javascript I also work with HTTP2 & have used SPDY on a low leval.
[Info]
Debian GNU/Linux (Buster), V.10
Compiler - Clang
headers HTTP2(?)
Headers HTTP(sys/socket.h, sys/types.h, signal.h, arpa/inet.h)
Network Protocol - TCP, HTTP2, HTTP.
[Question]
When playing around with Java you notice a-lot of HTTP2 being used in Game engines. HTTP2 is being standardized more & more in current languages as of 2021.(FOCUS POINT->) C has a standard Library for working with HTP & TCP.
HTTP2 uses Encryption & as of my knowledge is based in "TCP". Is there a standard for C working with, "HTTP2 TCP" types. I need to be able to read the Text from HTTP2 & easily preform tasks(send(), recv().(<-FOCUS POINT END).
[FINAL]
Can I Realistically develop HTTP2 Programs Using C standard POSIX Library's.
How would I go about using HTTP2 in C & is it even posible.

HTTP is a protocol. It defines the way computers communicate with each other. There a lot of different protocols out there; HTTP/2 and HTTP is based on TCP/IP, which almost all computers use to connect to servers. TCP/IP specifies how to create a connection between a client and a specific server, and send raw bytes. HTTP(2) is a layer over this, which defines how a client should tell the server what resource it wants.
The API provided by base POSIX extends to only raw TCP/IP. Here's an example of what an application could send to a web server to request a web page (this is an HTTP/1 request, HTTP/2 is binary and encrypted, making it not human-readable)
GET /somepage HTTP/1.0
Host: example.com
However, it's kind of inconvenient to assemble these requests manually in your program, especially when you start doing things like sending parameters, encryption, etc. In this case, people should use some libraries on the machine. It's important that these are nonstandard. Probably one of the most common ones is libcurl.
Here's a libcurl tutorial. To summarize:
You can compile your program with libcurl by providing some flags to the compiler and the linker. You can get these by running curl-config --cflags and curl-config --libs.
Initialize libcurl with curl_global_init(bitfield). The bitfield can have CURL_GLOBAL_WIN32 and CURL_GLOBAL_SSL as its values. You probably need CURL_GLOBAL_SSL since you want to use encryption.
libcurl has two interfaces: easy and multi. I am going to cover easy.
Get an easy handle by calling curl_easy_init(). This handle allows you to make requests.
Set options on the handle by using curl_easy_setopt(handle, option, value). handle is the "easy handle" you obtained, option is a constant - for example CURLOPT_URL for setting the URL to request - and value is the value you want to set it to. It's often a string.
Set a callback function with option as CURLOPT_WRITEFUNCTION. It should have the signature size_t(void *buffer, size_t size, size_t nmemb, void *userp). It's called when libcurl receives data from the server. Usually, it's called many times. nmemb points out the size of the data in buffer. It should return the count of bytes it successfully processed. Normally this is nmemb.
Execute the request with curl_easy_perform(handle).
When you're done with every request you want to make, call curl_global_cleanup().

Within C standard library there is no part dedicated to http2.
However, working with http2 in C is definitely possible, well documented and widely used. For example:
curl - info: https://curl.se/docs/http2.html
nghttp2
More info about http2 and various programming languages can be found here: https://github.com/httpwg/http2-spec/wiki/Implementations

Related

Client/Server communication using TCP/IP under TLS 1.3

I want to write a client and server in C preferably, simple C++ if necessary.
The server will run on some flavor of Linux, the client is for testing the server.
I want to ensure messages are received and error free; therefore I will use TCP.
I want them to communicate securely; thus I will use the latest version of TLS (v1.3).
I intend to use the GnuTLS library for reasons:
Actively updated by reputable open source project
License permits selling product
Given the above, if implemented and tested, I could claim that the client/server communication is secure, reliable (a.k.a. assured), and error-checked. Yes?
Am I missing something? Is anything patently false?
Edit: certificates... i think i'm missing something about certificates to protect against man in the middle attacks...
TLS is a complex topic. Depending on your specific code the TLS connection might succeed even if you fail to properly validate the certificate. Thus, just based on what you state so far in your question it cannot be assured that the data are transferred with proper end-to-end protection and that no man in the middle can manipulate the data.

Using WinHTTP to transfer data without headers

I am trying to incorporate some SSL/TLS into some Windows Sockets. I can't find any good examples so right now I am looking into the WinHTTP API.
I am wondering if this can be used like traditional socket send() and recv() functionality? I found an example of some code from Windows here:
https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/WinhttpWebsocket/cpp/WinhttpWebsocket.cpp
I have compiled it and tested using nc and I am getting the HTTP Headers printed to the command prompt. I don't need any of those headers as I want to create my own protocol and send my own data. Is it possible to not use those headers and not use any kind of GET/POST keywords and just treat this as normal socket operations?
Or should I be looking somewhere else? I don't want to use OpenSSL or any 3rd party libraries.
WinHTTP was developed as a light-weight HTTP library to replace WinINet in service applications. It is basically WinINet without FTP/Gopher support and no user preferences.
I doubt WinHTTP allows you to perform connections that are not based on the HTTP protocol, you need to go to a lower layer like SChannel for example. SChannel supports SSL and TLS.
The Windows SDK used to have a SSPI example.

How to develop http server with libcurl

I m working with libcurl. It's very good (as client) and I used to open a socket to a server and then send my http packets.
I'm wondering if it's possible to develop http server with the libcurl. the http server will listen on a given port then when it receive a http packet then the http server return a need to a digest authentication.
I made some research in stackoverflow and in the curl website but without result.
Is it possible to do that with libcurl ? and how to do it?
To repeat what others have said: no, libcurl is not for servers. It is even said in the curl FAQ:
5.17 Can I write a server with libcurl?
No. libcurl offers no functions or building blocks to build any kind
of internet protocol server. libcurl is only a client-side library.
For server libraries, you need to continue your search elsewhere but
there exist many good open source ones out there for most protocols
you could possibly want a server for. And there are really good
stand-alone ones that have been tested and proven for many years.
There's no need for you to reinvent them!
You need some HTTP server library (since libcurl is only an HTTP client librart) I would suggest to use libonion but there are several other HTTP server frameworks (libmicrohttpd, POCO & Wt in C++, ....).
HTTP is a complex protocol, even if coding a server for a tiny subset (like plain GET requests, without all the useful features like conditional requests, encoding & compression, etc...) of it is reasonably feasible. Hence I recommend using a full-fledged HTTP server library, and that cannot be a tiny library.

Any HTTP library in C that allows direct communication with the server?

Do you know of any HTTP client library in C (with SSL support) that also allows direct communication with the remote server?
I have a client-server application where the client uses HTTP to start a session in the server and then tells the server to switch the connection from HTTP to a different protocol. All communication is encapsulated in SSL. It is written in Perl and works well, but I'm looking into implementing the client in C.
I know libcurl gives you access to the underlaying socket but it's not enough because of the SSL requirement.
Notice that libcurl doesn't do the SSL part by itself, it uses OpenSSL. So, if you can get the socket handle from libcurl after the first HTTP interactions, AND the session key it uses (some spelunking required) you can go on directly with OpenSSL from that point.
I think that you must be looking for this otherwise you must have to write it yourself, like this
Sounds like you want Web Sockets. Don't know if there's a C library available though. I would assume there is, if you dig.

Why is separate getaddrinfo-like() + connect() not refactored into a (theoretical) connect_by_name()?

Most of the applications I've seen that use TCP, do roughly the following to connect to remote host:
get the hostname (or address) from the configuration/user input (textual)
either resolve the hostname into address and add the port, or use getaddrinfo()
from the above fill in the sockaddr_* structure with one of the remote addresses
use the connect() to get the socket connected to the remote host.
if fails, possibly go to (3) and retry - or just complain about the error
(2) is blocking in the stock library implementation, and the (4) seems to be most frequently non-blocking, which seems to give a room for a lot of somewhat similar yet different code that serves the purpose to asynchronously connect to a remote host by its hostname.
So the question: what are the good reasons not to have the additional single call like following:
int sockfd = connect_by_name(const char *hostname, const char *servicename)
?
I can come up with three:
historic: because that's what the API is
provide for custom per-application policy mechanism for address selection/connection retry: this seems a bit superficial, since for the common case ("get me a tube to talk to remote host") the underlying OS should know better
provide the visual feedback to the user about the exact step involved ("name resolution" vs "connection attempt"): this seems rather important, lookup+connection attempt may take time
Only the last of them seems to be compelling enough to rewrite the resolve/connect code for every client app (as opposed to at least having and using a widely used library that would implement the connect_by_name() semantics in addition to the existing sockets API), so surely there should be some more reasons that I am missing ?
(one of the reasons behind the question is that this kind of API would appear to help the portability to IPv6, as well as possibly to other stream transport protocols significantly)
Or, maybe such a library exists and my google-fu failed me ?
(edited: corrected the definition to look like it was meant to look, thanks LnxPrgr3)
Implementing such an API with non-blocking characteristics within the constraints of the standard library (which, crucially, isn't supposed to start its own threads or processes to work asynchronously) would be problematic.
Both the name lookup and connecting part of the process require waiting for a remote response. If either of these are not to block, then that requires a way of doing asychronous work and signalling the change in state of the socket to the calling application. connect is able to do this, because the work of the connect call is done in the kernel, and the kernel can mark the socket as readable when the connect is done. However, name lookup is not able to do this, because the work of a name lookup is done in userspace - and without starting a new thread (which is verboten in the standard library), giving that name lookup code a way to be woken up to continue work is a difficult problem.
You could do it by having your proposed call return two file descriptors - one for the socket itself, and another that you are told "Do nothing with this file descriptor except to check regularly if it is readable. If this file descriptor becomes readable, call cbn_do_some_more_work(fd)". That is clearly a fairly uninspiring API!
The usual UNIX approach is to provide a set of simple, flexible tools, working on a small set of object types, that can be combined in order to produce complex effects. That applies to the programming API as much as it does to the standard shell tools.
Because you can build higher level APIs such as the one you propose on top of the native low level APIs.
The socket API is not just for TCP, but can also be used for other protocols that may have different end point conventions (i.e. the Unix-local protocol where you have a name only and no service). Or consider DNS which uses sockets to implement itself. How does the DNS code connect to the server if the connection code relies on DNS?
If you would like a higher level abstraction, one library to check out is ACE.
There are several questions in your question. For instance, why not
standardizing an API with such connect_by_name? That would certainly
be a good idea. It would not fit every purpose (see the DNS example
from R Samuel Klatchko) but for the typical network program, it would
be OK. A paper exploring such APIs is "Simplifying Internet Applications Development
With A Name-Oriented Sockets Interface" by Christian Vogt. Note
that another difficulty for such an API would be "callback"
applications, for instance a SIP client asking to be called back: the
application has no easy way to know its own name and therefore often
prefer to be called back by address, despite the problems it make, for
instance with NAT.
Now, another question is "Is it possible to build such
connect_by_name subroutine today?" Partly yes (with the caveats
mentioned by caf) but, if written in userspace, in an ordinary
library, it would not be completely "name-oriented" since the Unix
kernel still manages the connections using IP addresses. For instance,
I would expect a "real" connect_by_name routine to be able to
survive renumbering (for instance because a mobile host renumbered),
which is quite difficult to do in userspace.
Finally, yes, it already exists a lot of libraries with similar
semantics. For a HTTP client (the most common case for a program whose
network abilities are not the main feature, for instance a XML
processor), you have Neon and libcURL. With libcURL, you can
simply write things like:
#define URL "http://www.velib.paris.fr/service/stationdetails/42"
...
curl_easy_setopt(curl, CURLOPT_URL, URL);
result = curl_easy_perform(curl);
which is even higher-layer than connect_by_name since it uses an
URL, not a domain name.

Resources