How to define routes with a custom protocol/scheme with node.js? - node.js

I scrapped the internet but did not find any good resource on how to create routes with a custom scheme (my-app://) with node.js.
Strictly speaking, it would not really be custom protocol, it would be http but served with another scheme.
How can I do that?
I can install any npm packages.

If it is HTTP then even though some other client application is using another scheme to connect, you will still get it as HTTP on the server side.
In fact, in the HTTP protocol you don't get the protocol scheme in the request. You get the host (hostname and port) in the Host heared and yu get the path (with query string but no fragment part) in the GET lite of the request (or POST etc.). At no point the client sends any indication of what protocol does it use, unless it's a request to a forward proxy server (but not if it's a reverse proxy).
It is your server that assumes which protocol scheme is used because it knows what protocol it speaks with on a given port. In the case that you describe of a client that uses some other protocol name in the URL but connects to your server using HTTP, your server will only need to know HTTP and the routes doesn't usually include the protocol anyway, maybe unless it's Diet.js but even then it's used in the listen argument, not in the routes.
This is an example HTTP request:
GET / HTTP/1.1
Host: localhost:3344
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,pl;q=0.6
The only place where it has "HTTP" is the first line defining the version of the protocol so that the client could understand the headers properly and this you would need to keep anyway so that your server could work if you want to use the built in http module or any framework in Node. If you changed that then you will have to write your own parser of the protocol.

Related

Can a server using http1.1 protocol be able to serve a request coming from browser using http2 protocol

For example I have a node server which uses the built-in module "http" (which is http1.1 version I assume). So will it be able to serve any XHR request from browser with http2 protocol?
Yes. Browsers negotiate HTTP/2 as part of the HTTPS setup (since browsers only support HTTP/2 over HTTPS). If HTTP/2 is not supported by both sides it will just use HTTP/1.1
Thanks one of the great things about HTTP/2 and why it’s made such headway - the ability to (almost!) seamlessly roll it out to the web without breaking existing sites/servers/browsers.

Confusion http/2,3 and cloudflare

When I start my API server on local it serves http/1.1 but I found that when it's deployed on VPS and set up with Cloudflare, the browser shows the protocol is http/3. So between the clients and Cloudflare is http/3 and Cloudflare and VPS is http/1.1 is this correct? That means http/3 is served only by DNS, my server is still plain http/1.1 and I need to migrate it to http/2 to be truly supported http/2. (I'm using node so it'll be a switch from http to http2 module)
When your web application / web API is behind Cloudflare, Cloudflare acts as a reverse proxy. This means that there are two "legs" of the connection:
From the end user's client (browser / mobile phone etc...) to Cloudflare
From Cloudflare to your origin server (in your case a VPS)
From a user point of view, they see leg (1) so it is quite easy to enable HTTP/2 or HTTP/3 (see documentation) even if your origin server does not support them. This is what you see in the browser when testing, depending on your configuration in the Cloudflare Dashboard.
For leg (2), only HTTP/1.1 is currently supported (as noted also in this Support KB). You can still optimize the setup of that leg by using features such as Argo Smart Routing or Argo Tunnel,
Update Jun 2022: HTTP/2 to the origin server is now supported and can be enabled in the dashboard. See here for more details.

Fetch in node receiving status code 464 but working in browser

I'm a requesting a url with fetch in my node app and the response status is 464 (without responseText and without any error message). But I could't find any info about that.
Also if I request the same url with my browser (Chrome) then it works fine (no need to send any cookies or auth, it works in incognito window too)
What could be causing this?
EDIT: seems to be a problem with AWS Load Balancer, my problem is exactly this:
https://forums.aws.amazon.com/message.jspa?messageID=964799
But there's no solution in that post, so maybe could be helpful to put it here if someone knows the problem (I'm suspecting is related with HTTP 2.0 but not sure, could it be?)
Response Header in Node is:
Server=awselb/2.0
Content-Length=0
HttpCode=464
But in Chrome:
server: nginx/1.18.0
I had this issue just today. My target group was configured for HTTP/2, but, the backend service was not prepared for that traffic. So, when I rebuilt the target group using HTTP/1.1, traffic began to function as expected.
When creating a target group, the options presented to me for HTTP protocol options were (as shown in the AWS Console):
HTTP/1.1
Send requests to targets using HTTP/1.1. Supported when the request
protocol is HTTP/1.1 or HTTP/2.
HTTP/2
Send requests to targets using HTTP/2. Supported when the request
protocol is HTTP/2 or gRPC, but gRPC-specific features are not
available.

What is difference between httpS and http/2?

I'm trying to understand what is the difference between HTTPS and http/2?
If I'm going to build a Node.js/express app, what should I use?
Can I use HTTPS with http/2?
Maybe if I use HTTPS, I don't need http/2 because it's the same, or HTTPS use http/2 under the hood?
I'm confused.
Someone is linked to me "difference between HTTP 1.1 and HTTP 2.0 [closed]", but I understand the difference between HTTP and HTTP2. I'm asking about HTTPS and HTTP/2
HTTP - A protocol used by clients (e.g. web browsers) to request resources from servers (e.g. web servers).
HTTPS - A way of encrypting HTTP. It basically wraps HTTP messages up in an encrypted format using SSL/TLS. The web is moving towards HTTPS more and more and web browsers are starting to put more and more warnings when a website is served over unencrypted HTTP. Unless you have a very good reason not to, use HTTPS on any websites you create now.
Digging into HTTP more we have:
HTTP/1.1 - this was the prevalent format of HTTP until recently. It is a text-based protocol and has some inefficiencies in it - especially when requesting lots of resources like a typical web page. HTTP/1.1 messages can be unencrypted (where web site addresses start http://) or encrypted with HTTPS (where web site address start with https://). The client uses the start of the URL to decide which protocol to use, usually defaulting to http:// if not provided.
HTTP/2 - a new version of HTTP released in 2015 which addresses some of the performance issues by moving away from a text based protocol to a binary protocol where each byte is clearly defined. This is easier to parse for clients and servers, leaves less room for errors and also allows multiplexing. HTTP/2, like HTTP/1.1, is available over unencrypted (http://) and encrypted (https://) channels but web browsers only support it over HTTPS, where it is decided whether to use HTTP/1.1 or HTTP/2 as part of the HTTPS negotiation at the start of the connection.
HTTP/2 is used by about a third of all websites at the time of writing (up to 50% of websites as of Jan 2020, and 67% of website requests). However not all clients support HTTP/2 so you should support HTTP/1.1 over HTTPS and HTTP/2 over HTTPS where possible (I believe node automatically does this for you when using the http module). I do not believe HTTP/1.1 will be retired any time soon. You should also consider supporting HTTP/1.1 over unencrypted HTTP and then redirect to HTTPS version (which will then use HTTP/1.1 or HTTP/2 as appropriate). A web server like Apache or Nginx in front of Node makes this easy.
HTTP/3 - the next version of HTTP, currently under development. It is expected to be finalised in 2020 though it will likely be late 2020 or even 2021 before you see this widely available in web servers and languages like node. It will be built on top of a UDP-based transport called QUIC (rather than the TCP-based protocol that HTTP/1.1 and HTTP/2 are based on top of). It will include part of HTTPS in the protocol so HTTP/3 will only be available over HTTPS.
In short you should use HTTP/1.1 over HTTPS, should consider HTTP/2 as well if easy to implement (not always possible as not quite ubiquitous yet - but getting there) and in future you might be using HTTP/3.
I suggest you get a firm understanding of all of these technologies (except maybe HTTP/3 just yet) if you want to do web development. It will stand you in good stead.

Shouldn't the IIS send Keep-Alive header

I've enabled "HTTP keep-alive" in IIS 7.5 settings.
But still, the IIS doesn't respond with Connection: keep-alive header (to both FF and Chrome)
As I noticed, Nginx responds with this header when I enable keep-alive on it.
Shouldn't the Connection: keep-alive header be sent by server in response to requests?
In HTTP/1.1 persistent connections are the default:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8
In other words, IIS doesn't really need to (however Apache seems to always send it).
You could verify this with netstat or as I tend to do with tcpview (a small sysinternals tool which you can download from microsoft:
http://technet.microsoft.com/en-us/sysinternals/bb897437.aspx)
It appears that IIS doesn't send the Connection: keep-alive. Still it doesn't close the connection and browser reuses it for further requests.

Resources