|
| 1 | +# Cloudflare Worker |
| 2 | + |
| 3 | +Альтернативный (полностью бесплатный, не нужно покупать домен в отличии от [CfProxy](./CfProxy.md)) способ проксирования. |
| 4 | + |
| 5 | +Прокси возвращает доступ к тому, что раньше не загружалось (реакции, некоторые стикеры). Если на аккаунте без Premium с данным способом все еще не загружаются фото/видео, оставьте в блоке `DC → IP` только `4:149.154.167.220` |
| 6 | + |
| 7 | +## |
| 8 | + |
| 9 | +1. **Добавьте в [zapret](https://github.com/Flowseal/zapret-discord-youtube/) или в любое другое ПО следующие домены:** |
| 10 | +``` |
| 11 | +cloudflare.com |
| 12 | +cloudflare.dev |
| 13 | +workers.dev |
| 14 | +``` |
| 15 | +2. Создайте аккаунт в [Cloudflare](https://dash.cloudflare.com/) (или войдите в существующий) |
| 16 | + * **После создания аккаунта подтвердите почту с помощью письма, который вам пришел на email** |
| 17 | +3. Слева в панели выберите `Compute` → `Workers & Pages` |
| 18 | + <img width="250" height="768" alt="image" src="https://github.com/user-attachments/assets/d81e3522-045a-4e65-9c2e-5545b7ad409a" /> |
| 19 | + |
| 20 | +4. Нажмите сверху справа кнопку **`Create application`** → `Start with Hello World!` → `Deploy` |
| 21 | + <img width="1406" height="193" alt="image" src="https://github.com/user-attachments/assets/7ac65944-8761-42a6-ab6d-ba5f9080c883" /> |
| 22 | + <img width="586" height="379" alt="image" src="https://github.com/user-attachments/assets/ff901439-c2a1-4867-95de-e11b82a37044" /> |
| 23 | + <img width="624" height="694" alt="image" src="https://github.com/user-attachments/assets/bb68d49a-166d-42a0-8fe2-bd2b16c0d066" /> |
| 24 | + |
| 25 | +5. Сверху справа нажмите кнопку **`Edit code`**, замените код слева на тот, [что находится внизу этой страницы](./CfWorker.md#код-workerа) |
| 26 | + * Если у вас не загружается код, то вы не выполнили первый пункт |
| 27 | + <img width="911" height="117" alt="image" src="https://github.com/user-attachments/assets/6bcdf839-d776-47e9-9d18-ba0efdf53244" /> |
| 28 | + <img width="1027" height="512" alt="image" src="https://github.com/user-attachments/assets/daf131ed-82d5-40f0-a7eb-daeb598bea40" /> |
| 29 | + |
| 30 | + |
| 31 | +6. Нажмите сверху справа кнопку **`Deploy`** |
| 32 | + <img width="415" height="138" alt="image" src="https://github.com/user-attachments/assets/58d8f83e-d8b5-40cf-a30f-741d7311047b" /> |
| 33 | + |
| 34 | +7. Скопируйте домен из поля справа и укажите его в настройках **Cloudflare Worker** (или через аргумент `--cfproxy-worker-domain`) |
| 35 | + * Пример домена: `random-symbols-1234.username.workers.dev` |
| 36 | + <img width="414" height="182" alt="image" src="https://github.com/user-attachments/assets/4fb0b111-8026-4d17-b993-6c70ec37f1f5" /> |
| 37 | + |
| 38 | + |
| 39 | +### Код Worker'а |
| 40 | +```javascript |
| 41 | +import { connect } from "cloudflare:sockets"; |
| 42 | + |
| 43 | +function toBytes(data) { |
| 44 | + if (data instanceof ArrayBuffer) { |
| 45 | + return new Uint8Array(data); |
| 46 | + } |
| 47 | + if (typeof data === "string") { |
| 48 | + return new TextEncoder().encode(data); |
| 49 | + } |
| 50 | + if (data && typeof data.arrayBuffer === "function") { |
| 51 | + return data.arrayBuffer().then((ab) => new Uint8Array(ab)); |
| 52 | + } |
| 53 | + return new Uint8Array(); |
| 54 | +} |
| 55 | + |
| 56 | +export default { |
| 57 | + async fetch(request) { |
| 58 | + if ((request.headers.get("Upgrade") || "").toLowerCase() !== "websocket") { |
| 59 | + return new Response("Expected websocket", { status: 426 }); |
| 60 | + } |
| 61 | + |
| 62 | + const url = new URL(request.url); |
| 63 | + if (url.pathname !== "/apiws") { |
| 64 | + return new Response("Not found", { status: 404 }); |
| 65 | + } |
| 66 | + |
| 67 | + const dst = url.searchParams.get("dst"); |
| 68 | + const pair = new WebSocketPair(); |
| 69 | + const client = pair[0]; |
| 70 | + const server = pair[1]; |
| 71 | + server.accept(); |
| 72 | + |
| 73 | + const socket = connect({ hostname: dst, port: 443 }); |
| 74 | + const tcpReader = socket.readable.getReader(); |
| 75 | + const tcpWriter = socket.writable.getWriter(); |
| 76 | + |
| 77 | + server.addEventListener("message", async (event) => { |
| 78 | + try { |
| 79 | + await tcpWriter.write(await toBytes(event.data)); |
| 80 | + } catch { |
| 81 | + try { |
| 82 | + server.close(1011, "tcp write failed"); |
| 83 | + } catch {} |
| 84 | + } |
| 85 | + }); |
| 86 | + |
| 87 | + server.addEventListener("close", async () => { |
| 88 | + try { |
| 89 | + await tcpWriter.close(); |
| 90 | + } catch {} |
| 91 | + try { |
| 92 | + socket.close(); |
| 93 | + } catch {} |
| 94 | + }); |
| 95 | + |
| 96 | + (async () => { |
| 97 | + try { |
| 98 | + while (true) { |
| 99 | + const { value, done } = await tcpReader.read(); |
| 100 | + if (done) { |
| 101 | + break; |
| 102 | + } |
| 103 | + if (value) { |
| 104 | + server.send(value); |
| 105 | + } |
| 106 | + } |
| 107 | + } catch { |
| 108 | + } finally { |
| 109 | + try { |
| 110 | + server.close(); |
| 111 | + } catch {} |
| 112 | + try { |
| 113 | + tcpReader.releaseLock(); |
| 114 | + } catch {} |
| 115 | + try { |
| 116 | + socket.close(); |
| 117 | + } catch {} |
| 118 | + } |
| 119 | + })(); |
| 120 | + |
| 121 | + return new Response(null, { status: 101, webSocket: client }); |
| 122 | + }, |
| 123 | +}; |
| 124 | +``` |
0 commit comments