How does Electron proxy URLs? - javascript

I created a small server which, for now, just outputs the request.url:
const http = require('http');
http.createServer(onRequest).listen(8080);
function onRequest(clientRequest, clientResponse) {
console.log(clientRequest.url);
}
Using the Electron APIs we can set up a proxy: to proxy all the urls through this server.
So, I'm running my server on localhost:8080 and use the --proxy-server http://localhost:8080 to redirect the traffic through my proxy server. This allows me to change some snippets in the HTML and only then render it in Electron.
When I access http://ionicabizau.net the request.url on the server side is http://ionicabizau.net.
How come that we can override the request url in such a way? What does Electron in the background?
First I thought that it just has to do with appending it like this:
http://localhost:8080/http://ionicabizau.net
But actually, that arrives on the server like /http://ionicabizau.net (notice the first slash).
What's the magic that Electron does to change the url of the request object?

When Electron (or anything else) makes an HTTP request, it connects to the target server and port and sends a message like the following:
GET / HTTP/1.1
Host: www.example.com
Most servers interpret this as an HTTP request for the full URL http://www.example.com/. When you specify a proxy server, that affects what server the HTTP client connects to, but it doesn't change the content of the request (so the requested URL is still http://www.example.com/).
So there's really nothing special that Electron needs to do to "override" the request URL... any HTTP client specifies the request URL as part of the message it sends to the server, and this is independent of which server that message is sent to.

Related

can someone please explain REQ in express plz

I dont get how we use req in express. I undrstand that the server can respond back to client,but when it comes to req object im confused. Is req when the server is asking for somethong from the client?
HTTP is an application, client-server protocol. Everytime that a client want the server to perform an action, it has to make a request. The HTTP protocol defines a set of actions or verbs that are available to the client so it can make each request using one specific verb (GET, POST, PATCH, PUT, DELETE, etc). It doesn't matter what verb the client uses, only the client can initiate a comunication with the server using one of that verbs. So this is how exactly an HTTP GET request looks like:
GET / HTTP/1.1
Host: example.com
User-Agent: curl/7.69.1
Accept: */*
The first line contains the verb used, in this case GET, the path requested, in this case /, and the protocol version, in this case HTTP/1.1. The next lines, are a set of key value pairs called the headers of that request, which can define a lot of aspects of the request made by the client to the server. By the way, an HTTP server never could or will start a request to a client, a client always is the one that make the request, and the server is always the one that response that request. One of the aspects of that request for example, is the destination host, that is present in the header host with the value of example.com. Bellow of the headers, all the HTTP requests have a blank line and then the body of the request, which normally contains the data that is sent from the client to the server. In this case, no data body is sent on the request.
Express is an HTTP server based on the HTTP module available on Node.js. Express simplifies the way that the native Node.js HTTP server works. Here is tipically how an Express app looks like:
const express = require('express');
const app = express();
// This is called a router
app.get('/path', (req, res) => {
// This router will perform some action with the req object
// And will send a response to the client
});
So, on the example above, the method app.get(...), available on Express applications, allows the server to deal with the GET requests that come from the client. The app.get() method takes two arguments, a path and a callback function. The path argument represent the string that goes after the name server, for example, in the URL www.example.com/test, the hostname is www.example.com, and the path is /test. That method app.get() is also called a Router. So, the router of the example will deal with the GET requests to that server which also define /path value as the path the request is sent to. Once a request to the server fit those two conditions, that callback will be triggered.
So, finally we get to the answer. The res variable is an object (a set of key-pair values separated by commas and locked into curly braces), that contains the data of the HTTP request, into a friendly legible object. For example, if you want to print to the console the path that the client used, you can print it like this console.log(req.path), or you can get all the headers of that HTTP request, you can use console.log(req.headers). The req object is one of the 5 main objects in Express, in fact the Express documentation defines a ton of methods that you can use with the request object (req). To get deep into the request object, you can see the official Express documentation in this link. The callback defined into the router, can use the req object, to extract information of the client's request, process it and return a response to the client later.
With an express server, you get two objects passed to a request handler.
req is data about the incoming request (things that were sent from the client). It contains the headers on the request, it contains a parsed query string, it contains the URL path, it's generally the object where middleware puts things for request handlers to use. While Express adds a bit more to this object, you can see the general concept of the req object by looking and the http.IncomingMessage object documented here. This is what the object starts out as and then Express adds more to it. The express version of the object is documented here.
res is the response object. This is all about sending a response. It will hold the outbound headers you want to send with the request. It contains the methods you use for sending a response. The core object is an http.ServerResponse object documented here and then Express adds some more things to the object on top of that which is document here.

Can´t make POST request from VUE to ESP32 https server

I´m trying to make a POST request from a vue web app to a ESP32 https server.
The request is always blocked by CORS because self-signed certificates.
ESP32 Starts in AP mode, generating his own Wifi network.
An https server, with SSL certificates generated by me, starts running (using this library: https://github.com/fhessel/esp32_https_server)
In a PC running locally the VUE app, I make the POST request to the ESP32 server (see code below)
(I´m using axios to make the request)
I have tried:
Adding a custom https aggent with rejectUnauthorized:
Adding same cert in POST request that ESP32 server uses
Adding CORS headers
Adding process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
Starting vue dev server in https mode with ESP32 same certs
Try to obtain the OPTIONS request in ESP32 server to allow the POST request
Making the request with curl or postman works fine!! It´s like a problem with the browser or vue.
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
axios.post(`https://192.168.4.1/config?ssid=${this.ssid}&ssidkey=${this.password}`, { httpsAgent })
.then((res) => {
...
});
The goal is to configure my WiFi credentials by conecting directly to the ESP32 in AP Mode first.
If I use curl or Postman to make the request its working fine, the ESP32 receive WiFi credentials and connect to my router, but it has been impossible to me to make the same with the vue web app...
You can find the full details of how the CORS mechanism works on the mozilla developers page: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
In summary, the browser automatically performs an HTTP request with the method OPTIONS with the same url of your original request to your server, and this request can't be avoid. The browser expect that this request responds with a status 200 and with the CORS headers ( for example:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
)
Once the response to the method OPTIONS is receive and looks valid for the browser, your original request is performed by the browser.
So, you need to configure your server to responde to the options method with the cors headers.

How to handle tcp/ip raw requests and http requests on the same server

I am working on a gps tracking system and have built a server on node js.
This is how the file looks like for reference.
const net = require('net');
const lora_packet = require('lora-packet');
const dataParser = require('./dataParser');
const clients = [];
net.createServer(function(socket) {
socket.name = socket.remoteAddress + ":" + socket.remotePort;
clients.push(socket);
socket.on('data', function(data) {
console.log("Buffer sent by terminal : ");
console.log(data);
const packet = lora_packet.fromWire(data, 'hex');
const str = packet._packet.PHYPayload.toString('hex');
dataParser.parse_data(str, socket);
});
socket.on('end', function() {
clients.splice(clients.indexOf(socket), 1);
//broadcast(socket.name + "has left the cartel.\n");
});
function broadcast(message, sender) {
clients.forEach(function(client) {
if (client === sender) client.write(message + "\nsent\n");
return;
client.write(message);
});
process.stdout.write(message);
}
}).listen(8080);
console.log("cartel is running on the port 8080\n");
This server file handles only requests from the hardware and processes raw tcp/ip requests.
I want the server to handle http requests also and want to incorporate routing feature in the server too for client side applicarions for browser.
1) Is there any way that http requests can also be handled by the same server or should I open another port and deploy an express node js app on that?
2) If I use the same 8080 port for http, how can the routing be achieved?
3) If I use different ports for http and raw tcp/ip, what would be the best way for communication between the two server. The communication between tcp/ip server and http server should happen via socket(sending data dynamically).
From http server using socket, data has to be sent dynamically to browser to update live location
So is the flow right?
Hardware (<---->)TCP/IP server(<--->)Http server(<--->)Browser
If more information is needed to solve the query, I'll provide with that!
Thank you
It's very complicated to try to speak multiple protocols on the same port. It requires some sort of scheme at the beginning of each connection to sample the incoming data and identify which protocol it is and then shunt that connection off to the right code to handle that protocol. I wouldn't suggest it.
It is way, way easier to just open a second server on a different port for an Express server to field your http requests. Very simple. You can do it right in the same app. Because both servers can be in the same app, you can just directly read from one connection and write to the other. There's no need for interprocess communication.
Is there any way that http requests can also be handled by the same server or should I open another port and deploy an express node js app on that?
Open another port. No need to write another app unless you have a specific reason to use two processes. You can put both the plain TCP server and the Express server in the same node.js app.
If I use the same 8080 port for http, how can the routing be achieved?
It's not easy. Not suggest to use the same port for multiple protocols.
If I use different ports for http and raw tcp/ip, what would be the best way for communication between the two server. The communication between tcp/ip server and http server should happen via socket(sending data dynamically).
You can put both servers in the same node.js app and then you can just read/write directly from one to the other with the same code. No need for interprocess communication.
From http server using socket, data has to be sent dynamically to browser to update live location
Sending data dynamically to a browser usually means you want the browser to hold something like a webSocket or socket.io connection to your server so you can then send data to the browser at any time over the existing connection. Otherwise, you would have to "wait" for the browser to request data and then respond with the data when it asks.

Making cross-domain requests while maintaining original IP address

My first attempt was to make a reverse proxy in Express which would allow me to request to localhost:3000/request and have it forward to somesite.com/request.
My code was:
var request = require('request');
app.get('/', function(req,res) {
var newurl = 'http://google.com/';
request(newurl).pipe(res);
});
This issue with this, is it changes the IP address of the request, to my server's IP.
My next attempt was JSONP, even though this is an HTML webpage, not a JSON file.
var tag = document.createElement("script");
tag.src = 'http://example.com/search?q=test';
document.getElementsByTagName("head")[0].appendChild(tag);
The error for that was: Uncaught SyntaxError: Unexpected token <
You can certainly get around CORS with a server-side proxy. You can use a pre-built module like node-http-proxy to do that and to handle most of the implementation for you.
However, the target destination site will see the request coming from the IP address of your proxy server and you cannot change that.
A proper proxy will insert headers into the original HTTP request that contains the original browser's IP address and the receiving server could look at those additional headers if it chose to. But, if it only looks at the IP address that the request actually comes from, then it will see the IP address of your proxy server and you can't change that. For data to flow from your proxy to the target destination server and then the request to come back through your proxy and back to the original browser, there will necessarily be a TCP connection between your server and the target destination and the source IP address has to be your server (that's the only way the data can flow back to your server so you can then forward it back to the browser).
As for JSONP, JSONP requires cooperative support from the target server (the requested data has to be sent back in a piece of Javascript that when run will call the desired callback function). If that server doesn't explicitly support JSONP, then you can't use it.

Javascript Server Side Events with C-client Server Program

Im looking for feasibility of calling C object(for copying a file from client to server) via Javascript Eventsource.
Ex:
I have a C-Client Program which can be executed as below:
./client ip
executing above file will
send a file from client machine to server running at port 8888.
Server will be running at 8888 will receive the file and will write at /folder1/receivedfile.
./server ip
I need to do this in Javascript Event source.
Javascript code example:
if(window.EventSource){
var source =new EventSource("c-object");
}else{
// Result to xhr polling :( xhttprequest
}
It is feasible. Your second line would be something like this:
var source = new EventSource("http://myserver.example.com:8888/c-object");
Your server must be running HTTP protocol, of course. If going down this route, be aware that calling a resource on a different origin will need all the CORS workarounds. In this case the resource is c-object, and the different origin is because of using a different port to where the HTML was served from.
Alternatively you could use Apache, and start c-object as a cgi program. Then it just needs to interact on stdin/stdout.
But, taking a step back, are you sure it is EventSource you want? If you are just trying to send a signal to the server to tell it to copy a file, and not receiving any data, then use a normal AJAX request. SSE is for the server to stream data to the client, one-way, continuously. After the initial connection is made, SSE cannot send anything to the server.

Categories

Resources