Tuesday | 23 APR 2024
[ previous ]
[ next ]

Writing a Proxy Server in 10 Lines

Title:
Date: 2023-03-12
Tags:  

What does a proxy server do? It acts as a middle man for you and so all a simple proxy server has to do is take your request, make it for you, and then pass back the response.

This is ignoring the complexities of proxies such as hiding things and submitting information to a website that needs to be saved. This will be a simple proxy that can get a web page for you.

The reason why I wrote this is because often times I want to write a small javascript snippet that requires fetching a resource not on my domain and due to cors, browsers won't allow that request. This means I need to use a proxy server to fetch things when writing javascript snippets.

Now without further ado:

Some packages we will need, you can skip axios and use fetch if your node version supports it.

pnpm init
pnpm install axios koa

The proxy server code.

const axios = require("axios");
const Koa = require("koa");

const app = new Koa();

app.use(async (ctx, next) => {
    if (ctx.path !== "/proxy") return await next();
    const response = await axios.get(ctx.request.query.url);
    ctx.body = response.data;
});

app.listen(5106);

Run it:

node index.js

Then we can navigate to:

http://some.ip.addr:5106/proxy?u=https://google.ca

Voila! With that we should see a broken page. We could resolve the URLs on the page so they go through the proxy as well and that would load images and other content.

Any relative urls in the page are now trying to find things on our server such as css files and javascript files. The safe thing to do would be to block these things out or re-write them to use the proxy server.

Now we can put nginx in front of our proxy server:

location / {
    add_header 'Access-Control-Allow-Origin' '*';
    proxy_pass http://localhost:5106;
}

This code is simple and light to show the logic of what is going on. I'm sure this code will get much bigger as I add more and more functionality but this stripped down version works well enough for now. The big thing to add add would be the koa-router to get a nicer route handling.

The last step is to start this as a service with pm2:

pm2 start index.js --name proxy-server

With that we can deploy this proxy server and begin using it in random fetch scripts.

let response = await fetch("https://example.com/proxy?u=http://www.cp24.com");