Logo

dev-resources.site

for different kinds of informations.

How I Build a Scratch Proxy Server Using Node.js

Published at
7/9/2024
Categories
node
proxy
javascript
core
Author
avinash_tare
Categories
4 categories in total
node
open
proxy
open
javascript
open
core
open
Author
12 person written this
avinash_tare
open
How I Build a Scratch Proxy Server Using Node.js

You might be curious about how proxy servers work and how they serve data over the internet. In this blog, I am going to implement a proxy server using core NodeJs.I achieved this using a core NodeJs package called net which already comes with NodeJs.

How Proxy Works

a proxy server is an agent between the client and the server. When a

client sends a request to a server it is forwarded to a target proxy
server. The targeted proxy server processes the request and sends it
to the main server and the main server sends the back request to the
proxy server and the proxy server sends the request to the client.

preview image

Set up Proxy Server

Before, starting programming you know little about socket and NodeJs.You know what a is socket and how they work.
In NodeJs There are two methods to implement a proxy server. First I custom method and second in-build. Both are easy to understand.

To test your proxy server you can run your local HTTP serve on your local machine and then target the host machine.

  • Now, I will define the net package and then write the target server and port number.
const net = require('net');

// Define the target host and port
const targetHost = 'localhost'; // Specify the hostname of the target server. For Ex: (12.568.45.25)
const targetPort = 80; // Specify the port of the target server
Enter fullscreen mode Exit fullscreen mode
  • Creating and listening TCP server.
const server = net.createServer((clientSocket) => {

});

// Start listening for incoming connections on the specified port
const proxyPort = 3000; // Specify the port for the proxy server
server.listen(proxyPort, () => {
    console.log(`Reverse proxy server is listening on port ${proxyPort}`);
});
Enter fullscreen mode Exit fullscreen mode
  • we have created a server using the net package. it's a TCP server which is running port number 3000 as we define in using the proxyPort variable. if the server starts it will show the Reverse proxy server is listening on port 3000 message on the console.
  • when the client tries to connect the proxy server it runs the callback function which is inside createServer.
  • In server function callback we have one parameter clientSocket it's the user connection that we received for the connection.

  • accept and receive data from the user

const targetHost = 'localhost'; // Specify the hostname of the target server. For Ex: (12.568.45.25)
const targetPort = 80; // Specify the port of the target server

// Create a TCP server
const server = net.createServer((clientSocket) => {
    // Establish a connection to the target host
    net.createConnection({host: targetHost, port: targetPort}, () => {

        // When data is received from the client, write it to the target server
        clientSocket.on("data", (data) => {
            targetSocket.write(data);
        });

        // When data is received from the target server, write it back to the client
        targetSocket.on("data", (data) => {
            clientSocket.write(data);
        });
    });
});
Enter fullscreen mode Exit fullscreen mode
  • When a client tries to connect proxy server we will create a temporary connection to the server using create createConnection
  • createServer have 2 arguments
    • 1st Host where we want to connect in this case we have to connect to our server host which is defined in targetHost variable.
    • 2nd Port where we want to connect in this case we have to connect to our server port which is defined in targetPort variable.
  • Now, When user send data I will pass this data to server. using this code js clientSocket.on("data", (data) => { targetSocket.write(data); });
  • Then, the Server sends data I will send this data to the user, using this code js targetSocket.on("data", (data) => { clientSocket.write(data); });
  • Congratulations! you successfully created your proxy server.

Error Handling

While exploring the functionality of the proxy server is exciting, ensuring reliability requires robust error-handling methods to handle unexpected issues gracefully. To handle those types of errors we have an event called an error. It's very easy to implement.

    const server = net.createServer((clientSocket) => {
     // Establish a connection to the target host
     const targetSocket = net.createConnection({host: targetHost,port: targetPort}, () => {

       // Handle errors when connecting to the target server
       targetSocket.on('error', (err) => {
         console.error('Error connecting to target:', err);
         clientSocket.end(); // close connection
       });

       // Handle errors related to the client socket
       clientSocket.on('error', (err) => {
         console.error('Client socket error:', err);
         targetSocket.end(); // close connection
       });
     });
   });
Enter fullscreen mode Exit fullscreen mode
  • when any error occurs we will console the error and then close the connection.

ALL Code

  • replace host name and port number according to your preference. ```js const net = require('net');

// Define the target host and port
const targetHost = 'localhost'; // Specify the hostname of the target server
const targetPort = 80; // Specify the port of the target server

// Create a TCP server
const server = net.createServer((clientSocket) => {
// Establish a connection to the target host
const targetSocket = net.createConnection({
host: targetHost,
port: targetPort
}, () => {
// When data is received from the target server, write it back to the client
targetSocket.on("data", (data) => {
clientSocket.write(data);
});

  // When data is received from the client, write it to the target server
  clientSocket.on("data", (data) => {
     targetSocket.write(data);
  });
Enter fullscreen mode Exit fullscreen mode

});

// Handle errors when connecting to the target server
targetSocket.on('error', (err) => {
console.error('Error connecting to target:', err);
clientSocket.end();
});

// Handle errors related to the client socket
clientSocket.on('error', (err) => {
console.error('Client socket error:', err);
targetSocket.end();
});
});

// Start listening for incoming connections on the specified port
const proxyPort = 3000; // Specify the port for the proxy server
server.listen(proxyPort, () => {
console.log(Reverse proxy server is listening on port ${proxyPort});
});


# Built Method
To reduce client and server connection complexity we have built-in method `pipe`.I will replace this syntax 
```js
// Handle errors when connecting to the target server
targetSocket.on("data", (data) => {
   clientSocket.write(data);
});

// When data is received from the client, write it to the target server
clientSocket.on("data", (data) => {
   targetSocket.write(data);
});
Enter fullscreen mode Exit fullscreen mode

Into this syntax

// Pipe data from the client to the target
clientSocket.pipe(targetSocket);

// When data is received from the client, write it to the target server
targetSocket.pipe(clientSocket);
Enter fullscreen mode Exit fullscreen mode

Here is all code

const net = require('net');

// Define the target host and port
const targetHost = 'localhost';
const targetPort = 80;

// Create a TCP server
const server = net.createServer((clientSocket) => {
   // Establish a connection to the target host
   const targetSocket = net.createConnection({
      host: targetHost,
      port: targetPort
   }, () => {
      // Pipe data from the client to the target
      clientSocket.pipe(targetSocket);

      // Pipe data from the target to the client
      targetSocket.pipe(clientSocket);
   });

   // Handle errors
   targetSocket.on('error', (err) => {
      console.error('Error connecting to target:', err);
      clientSocket.end();
   });

   clientSocket.on('error', (err) => {
      console.error('Client socket error:', err);
      targetSocket.end();
   });
});

// Start listening for incoming connections
const proxyPort = 3000;
server.listen(proxyPort, () => {
   console.log(`Reverse proxy server is listening on port ${proxyPort}`);
});
Enter fullscreen mode Exit fullscreen mode

A Working Proxy Server!

Follow Me On GitHub avinashtare, Thanks.

core Article's
30 articles in total
Favicon
Understanding Process Management in Operating Systems
Favicon
Introduction to Operating Systems
Favicon
What is SignalR? A Real-Time Communication Framework for .NET
Favicon
[KOSD] Change of FromQuery Model Binding from .NET 6 to .NET8
Favicon
JDK, JVM, and JRE: The Three Musketeers of Java Development πŸ‡
Favicon
Optimizing Your Development Machine: How Many Cores and Threads Do You Need for Programming?
Favicon
ASP .NET Core Best Practices
Favicon
Build Scalable Blazor CRUD Apps in 30 Minutes with Azure SQL
Favicon
The Benefits of Having More Threads than Cores: Unlocking the Power of Multi-threading in Modern Computing
Favicon
Deep Dive ASP.NET Core Middleware : Part 1
Favicon
The Purpose of Computer Processors (CPUs) and How Multiple Cores Improve Speed and Performance
Favicon
Primitive Data Types in Java
Favicon
How I Build a Scratch Proxy Server Using Node.js
Favicon
Javascript Working Mechanism
Favicon
A Journey Into the World of Programming with First Core Java Program
Favicon
[KOSD] Learning from Issues: Troubleshooting Containerisation for .NET Worker Service
Favicon
CORE WEB VITAL ISSUE
Favicon
Migrate to TLS 1.2 for Azure Blob Storage
Favicon
Keyboard input in Node.js
Favicon
Criando sua primeira aplicação console em .net
Favicon
Enabling CORS in a .NET Core Server-Side Application
Favicon
Digital Image Processing Notes
Favicon
Top Benefits of Using Core App Dashboard
Favicon
Understanding JavaScript Execution Context β€” The Key to Efficient Code
Favicon
5 Interesting Things About Strings in Java
Favicon
πŸ”’ Introducing Serial Log and Metro Log: Simplifying Your Logging Experience In .NET MAUI! πŸ“πŸš‡
Favicon
Understanding Core.js and Zone.js: Key to JavaScript Libraries
Favicon
Apitable.com Net6 Rest Api
Favicon
Custom resolve handler in Microsoft's ServiceProvider (enabling property injection)
Favicon
ASP.NET CORE REACT APP: System.InvalidOperationException: SPA default page middleware failed to return default page /index.html

Featured ones: