npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

multi-type-proxy

v1.0.2

Published

advanced nodejs proxy server supports http, socks4 and socks5

Downloads

1

Readme

advanced nodejs proxy server supports http, socks4 and socks5

can transfer both http and https data

can intercept the http/https data to make an rotating proxy, an cache to save bandwith or to spy on http requests

Can handle 1 gigabit of download and upload at the same time with only 50MB ram usage and 2% cpu usageon an I5 10400

Can make an blazing fast proxy supporting http socks4 and socks5 connections at the same time with low CPU and RAM usage

Only uses the internal net and dns module of node

Can handle authentification on socks5 http and partially on socks4

let proxyAPI = require("multi-type-proxy")
// require the module
// It returns a class, so you have to call new on it

let proxyServer = new proxyAPI()
// create a new server
// currently its not listening to any data

proxyServer.listen(port)
// make the server listen to the port given

proxyServer.close()
// Closes the server, cannot be listened to again
// You need to make another server after calling this

function proxyServer.connected
// The first when calling the function is an object with the port
// and address of the  upstream server

// The second argument is the authentification used by the client
// it may be undefined if there is no authentification used
// or it may be a {username, password} object

proxyServer.connected = (address, auth) => {
    if(user){
        console.log(`user ${auth.username} with password ${auth.password}`)
    }

    console.log(`connecting to server ${address.address}:$${address.port}`)
}

function proxyServer.dnsError
// Its called when the DNS server returns a error
// or the returned IP is the null IP (0.0.0.0)
// The only argument is the error itself

function proxyServer.procError
// Its called when the network processor returns a error
// Should never happen unless the network is unstable
// The only argument is the error itself

function proxyServer.data_processor
// This is used to transfer data between the client
// and the upstream server

// Pretty much everything is handled by this module, so
// you only have to do the bare minimum

// the first argument is an object {port, address} of the server to connect to
// the second argument is an object {up, down}
// up is the new connection you are connecting
// down is the client socket

// ********** example function ***********

let net = require("node:net")

proxyServer.data_processor = (upConnection, connections, authGood) => {
    return new Promise((resolve, reject) => {        
        let upstream = net.connect(upConnection.port, upConnection.address, () => {
            connections.up.pipe(upstream)
            upstream.pipe(connections.down)

            resolve(upstream)
        })
    })
}

function proxyServer.dnsGet
// you have to return a promise!
// the only argument gives is the address (It may be an domain or an IP)
// if its an IP you can just return it back to save time and bandwith
// if its an domain you have to use an custom DNS server to get an IP address 
// from the domain

// ********** example function ***********

let dns = require("node:dns")

proxyServer.dnsGet = (address) => {
    return new Promise((resolve, reject) => {
        dns.lookup(address, (err, newAddress) => {
            if (err) return reject(err)
            if (newAddress == "0.0.0.0") return reject(`Invalid address`)

            resolve(newAddress)
        })
    })
}

function proxyServer.authenticate
// should return a promise
// if the promise resolves with true then the socket will be usable
// if the promise resolves with false then the socket will receive
// a error 407 for http or an similar code for socks4/socks5

// The only argument may be undefined if there is no auth
// or an {username, password} Object
// password may be of length 0 if you are using socks4
// because socks4 only has username authentification

proxyServer.authenticate = (auth, authGood) => {
    if(!auth){
        return false // no credentials
    } else {
        if(auth.username == "user123" && auth.password == "password") return true

        return false // incorrect credentials
    }
}

function proxyServer.handler
// should return a promise
// if the promise resolves with true then the socket will be usable
// if the promise resolves with anything then the socket will receive
// a error 503 for http or an similar code for socks4/socks5 or the
// value that is in place of true

// the first argument is the type of proxy (socks4/socks5/http)
// the second argument is the stage of the connection
// the third argument is the result of the parsed data from the current stage

// the only stage in http has the data:
{
    isTTL, // whatever the connection is https
    host, // the domain/ip of the server connecting to
    port, // port of the server connecting to
    request: data, // The data send by the client before this request
    finished: true, // Its always going to be true for http proxy
    authType: "user:pass" || "none", // If it has authentification
    skipAuth: false, // always false for http
    auth, // The auth used, will be undefined if authType is "none"
}

// the only stage in socks4 has the data:
{
    isTTL, // whatever the connection is https
    host, // the domain/ip of the server connecting to
    port, // port of the server connecting to
    request: data, // The data send by the client before this request
    finished: true, // Its always going to be true for socks4 proxy
    authType: "user:pass" || "none", // If it has authentification
    skipAuth: false, // always false for socks4
    auth, // The auth used (only username), will be undefined if authType is "none"
}

// The stages of socks5:

//stage 0:

{
    request: data, // The data send by the client before this request
    finished: false, // false for stage 0 and 1
    authType: "user:pass" || "none", // none if there is no authentification used
    skipAuth: false || true, // true if there is no authentification used
}

//stage 1 (Only when using authentification):

{
    request: data, // The data send by the client before this request
    finished: false, // false for stage 0 and 1
    authType: "user:pass"
    skipAuth: false,
    auth: {username, password}, // Object with the username and password of the user
}

//stage 2:
// NOTE: You can get the authentification data
// only from the past request.
// If you dont use proxyServer.handler but use proxyServer.authenticate
// then this wont matter to you

{
    isTTL: port, // whatever the connection is https
    host, // the domain/ip of the server connecting to
    port, // the port of the server connecting to
    finished: true,
    request: data, // // Its always going to be true for http proxy
}

proxyServer.handler = (type, stage, result) => {
    console.log(`processing ${type} request at stage ${stage}`)
    
    if(result.finished){
        console.log(`finished processing ${type} request`)
        console.log(`Upstream server: ${result.host}:${result.port}`)
    }
}