Arvancloud Edge Computing: An Unmatched Experience of Speed and Security

With Arvancloud Edge Computing, you can run your scripts and processing codes for your online services at the closest point to the user without the need for a server, providing a new level of speed and security.

blur Arvancloud Edge Computing: An Unmatched Experience of Speed and Security
Free SSL Certificate

Free SSL Certificate

All domains added to the Edge Computing platform automatically receive free SSL certificates.

Fast and Easy Setup

Fast and Easy Setup

With the Arvancloud panel or CLI, launch and deploy your business’s online services in less than 30 seconds.

Optimized Performance

Optimized Performance

All your business code is hosted on Arvancloud CDN PoPs and executed from the nearest point to the user.

High Security

High Security

Enjoy Arvancloud’s advanced CDN security features to develop your services in a safe and reliable environment.

Features

Develop Your Online Services with Super Advanced Features

Serverless Solution

You can develop your online services without the need for a cloud or virtual server, and run the content from the nearest point to the user.

High Scalability

Use the unlimited resources of the content delivery network without server load balancing, or distribute traffic across multiple PoPs.

One-Click Deployment

With ready-to-use codes and templates, you can deploy your service with just one click and customize features based on your needs.

Cost-Effective

Deploying applications with Arvancloud Edge Computing allows you to deliver your services to users at minimal cost.

Debug Before Release

Easily edit and debug your final versions with the Console Log before launching your website or application to the public.

Quick Replies

With Arvancloud Edge Computing, respond to user requests from the nearest location, and boost your service delivery speed.

Over 40

PoPs in high-traffic regions around the world

99.99%

Uptime and constant service availability

500 Million

Request handling capacity per hour
Ready-to-Use Templates

Develop functional services with just a single click.

Round Robin Load balancer

Hotlink Protection

Basic Auth

SSR HTMX

Round Robin Load balancer

With Round Robin Load Balancer, your incoming requests are evenly distributed across multiple servers. This offers balanced traffic distribution and better performance, and helps you remain available and stable under heavy traffic conditions.

View
Copied
                                            
'use strict';

// Upstream URLs
const UPSTREAM_URLS = [
    new URL("http://localhost:4000"),
    new URL("http://localhost:4001"),
    new URL("http://localhost:4002"),
    new URL("http://localhost:4003"),
];

let NEXT_UPSTREAM_INDEX = 0;
async function handleRequest(request) {
    let upstreamIdx = NEXT_UPSTREAM_INDEX;
    NEXT_UPSTREAM_INDEX = (NEXT_UPSTREAM_INDEX + 1) % UPSTREAM_URLS.length;
    let upstream = UPSTREAM_URLS[upstreamIdx];
    return await doRequest(request, upstream);
}
function doRequest(request, upstream) {
    let newUrl = new URL(request.url);
    newUrl.protocol = upstream.protocol;
    newUrl.host = upstream.host;
    let newReq = new Request(newUrl.toString(), request);
    return fetch(newReq);
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Hotlink Protection

By enabling Hotlink Protection, you can protect your website images, videos, etc. from being misused on other websites. This not only reduces bandwidth consumption and costs but also improves your service’s security and protects your content.

View
Copied
                                            
'use strict';

// Your domains that is allowed to access hotlinks
const DOMAINS = ["time.ir", "fa.wikipedia.org"];
// Upstream url
const UPSTREAM_URL = "http://localhost:4000";
// File extensions that hotlink is against
const EXTENSIONS = ["jpg", "jpeg", "png", "ico", "gif"];

async function handleRequest(request) {
    const fileExt = extractUrlFileExtension(request.url);
    if (fileExt == null || !EXTENSIONS_SET.has(fileExt)) {
        return await doRequest(request);
    }
    else {
        return await checkReferrerAndDoRequest(request);
    }
}
async function doRequest(request) {
    let newUrl = new URL(request.url);
    newUrl.protocol = UPSTREAM_PROTOCOL;
    newUrl.host = UPSTREAM_HOST;
    let newReq = new Request(newUrl.toString(), request);
    return fetch(newReq);
}
async function checkReferrerAndDoRequest(request) {
    let response;
    const referrerHeader = request.headers.get("referer");
    if (referrerHeader != null) {
        let domain = extractDomainFromReferrer(referrerHeader);
        if (domain == null || DOMAINS_SET.has(domain)) {
            response = await doRequest(request);
        }
        else {
            response = UNAUTHORIZED_RESPONSE;
        }
    }
    else {
        response = await doRequest(request);
    }
    return response;
}
function extractDomainFromReferrer(referrer) {
    try {
        return new URL(referrer).hostname;
    }
    catch (e) {
        return null;
    }
}
function extractUrlFileExtension(url) {
    try {
        let pathname = new URL(url).pathname;
        let lastDotIdx = pathname.lastIndexOf(".");
        if (lastDotIdx == -1) {
            return null;
        }
        else {
            return pathname.substring(1 + lastDotIdx);
        }
    }
    catch (e) {
        return null;
    }
}
const DOMAINS_SET = (() => {
    const set = new Set();
    DOMAINS.forEach((i) => set.add(i));
    return set;
})();
const EXTENSIONS_SET = (() => {
    const set = new Set();
    EXTENSIONS.forEach((i) => set.add(i));
    return set;
})();
const UNAUTHORIZED_RESPONSE = new Response(null, {
    status: 401,
});
const UPSTREAM_PROTOCOL = new URL(UPSTREAM_URL).protocol;
const UPSTREAM_HOST = new URL(UPSTREAM_URL).host;

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Basic Auth

The Basic Auth template allows you to easily control access to protected sections of your website with a simple username and password. This script is quick to implement and meets your service’s basic security needs.

View
Copied
                                            
'use strict';

// Credentials for users
const UserPassList = [{ user: "admin", pass: "adminpass" }];
// Upstream url
const UPSTREAM_URL = "http://localhost:4000";

async function handleRequest(request) {
    const authHeader = request.headers.get("Authorization");
    let response;
    if (authHeader != null && authHeader.startsWith("Basic")) {
        let encodedCredential = authHeader.substring(6);
        if (CREDENTIALS.has(encodedCredential)) {
            let newUrl = new URL(request.url);
            newUrl.protocol = UPSTREAM_PROTOCOL;
            newUrl.host = UPSTREAM_HOST;
            let newReq = new Request(newUrl.toString(), request);
            newReq.headers.delete("Authorization");
            response = await fetch(newReq);
        }
        else {
            response = UNAUTHORIZED_INVALID_CREDENTIALS_RESPONSE;
        }
    }
    else {
        response = UNAUTHORIZED_NEEDS_LOGIN_RESPONSE;
    }
    return response;
}
const UNAUTHORIZED_NEEDS_LOGIN_RESPONSE = new Response(null, {
    //TODO: Add realm and/or charset if needed
    headers: new Headers({
        "WWW-Authenticate": "Basic",
    }),
    status: 401,
});
const UNAUTHORIZED_INVALID_CREDENTIALS_RESPONSE = new Response(null, {
    status: 401,
});
// Key: Base64 encoded username:password
// Value: username
const CREDENTIALS = (() => {
    const map = new Map();
    for (let i of UserPassList) {
        // TODO: this may not properly work with utf8
        const encoded = btoa(`${i.user}:${i.pass}`);
        map.set(encoded, i.user);
    }
    return map;
})();
const UPSTREAM_PROTOCOL = new URL(UPSTREAM_URL).protocol;
const UPSTREAM_HOST = new URL(UPSTREAM_URL).host;

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
SSR HTMX

With the Server-Side Rendering template in HTMX, you can dynamically render web pages from the server and update various sections without a full page reload. This will help improve loading speed and user experience.

View
Copied
                                            
'use strict';

const TODO_LIST = ["test"];
function createDb() {
    return {
        add: async (title) => {
            TODO_LIST.push(title);
        },
        list: async () => TODO_LIST,
    };
}
const DefaultDB = createDb();

var Index = "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <title>Todo list</title>\n  <script src=\"https://unpkg.com/htmx.org@1.9.5\"></script>\n  <link rel=\"stylesheet\" href=\"/styles.css\">\n</head>\n\n<body>\n  <div>\n    <div>\n      <h1>To-Do List</h1>\n    </div>\n    <form hx-post=\"/add\" hx-target=\"#list\" hx-swap=\"beforeend\">\n      <div>\n        <input type=\"text\" placeholder=\"Task title\" name=\"title\" required />\n        <button type=\"submit\">Add</button>\n      </div>\n    </form>\n    <div id=\"list\" hx-get=\"/list\" hx-trigger=\"load\"></div>\n  </div>\n</body>\n\n</html>";

var Styles = "h1 {\n  color: red;\n}\n";

async function handleRequest(request) {
    // simple router:
    let content = "";
    const url = new URL(request.url);
    switch (url.pathname) {
        case "/":
            content = Index;
            break;
        case "/styles.css":
            return new Response(Styles, {
                headers: { "Content-Type": "text/css" },
            });
        case "/add":
            const data = await request.formData();
            const title = data.get("title").toString();
            await DefaultDB.add(title);
            content = `<li>${title}</li>`;
            break;
        case "/list":
            content = (await DefaultDB.list()).map((x) => `<li>${x}</li>`).join("");
            break;
        default:
            content = "Not found :(";
    }
    if (request.url)
        return new Response(content, {
            headers: { "Content-Type": "text/html; charset=utf-8" },
        });
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Pricing

Affordable Infrastructure for Online Businesses

Pay-as-You-Go

Free incoming traffic
100 Edge Computing instances (applications)
100,000 free requests per month
Start for Free

Enterprise

Free incoming traffic
500 Edge Computing instances (applications)
Unlimited requests
Submit a Request
The final cost of Arvancloud Edge Computing is calculated based on your usage of various features. See more details on the pricing page.
Edge Computing Pricing

High Speed and Unbreakable Security with Arvancloud Edge Computing

Develop your services without the need for multiple cloud infrastructures.