{"id":15083922,"url":"https://github.com/MAKS11060/protocols","last_synced_at":"2025-10-04T14:30:45.871Z","repository":{"id":252720789,"uuid":"841244325","full_name":"MAKS11060/deno-protocols","owner":"MAKS11060","description":"Implementation of simple protocols in typescript","archived":false,"fork":false,"pushed_at":"2025-01-07T00:58:40.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-01-07T01:29:59.871Z","etag":null,"topics":["deno","stun","typescript","upnp","websocket"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MAKS11060.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-12T02:33:42.000Z","updated_at":"2025-01-07T00:58:45.000Z","dependencies_parsed_at":"2024-10-04T01:45:55.091Z","dependency_job_id":null,"html_url":"https://github.com/MAKS11060/deno-protocols","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"81873fcc1fc2caa0d4f21d206e8efc0c4f77022d"},"previous_names":["maks11060/deno-protocols"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MAKS11060%2Fdeno-protocols","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MAKS11060%2Fdeno-protocols/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MAKS11060%2Fdeno-protocols/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MAKS11060%2Fdeno-protocols/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MAKS11060","download_url":"https://codeload.github.com/MAKS11060/deno-protocols/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235262486,"owners_count":18961960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","stun","typescript","upnp","websocket"],"created_at":"2024-09-25T07:00:24.010Z","updated_at":"2025-10-04T14:30:45.865Z","avatar_url":"https://github.com/MAKS11060.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Implementation of protocols in TypeScript using modern Web API\n\n- [SOCKS5 Server (RFC 1928)](#socks5-server-rfc-1928)\n- [WebSocket Stream Server (RFC 6455)](#websocket-stream-server-rfc-6455)\n- [UPnP Client (RFC 6970)](#upnp-client-rfc-6970)\n  - [Methods](#methods)\n- [STUN Client (RFC 5389)](#stun-client-rfc-5389)\n\n## Features\n- Based on [Web Stream API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)\n- Using [`@std/`](https://jsr.io/@std)\n\n\n## [SOCKS5 Server (RFC 1928)](https://datatracker.ietf.org/doc/html/rfc1928)\n\n- [Full Example](socks/socks5.test.ts)\n\n```ts\n// socks/test.ts\nserveTcp({port: 40443}, async (conn) =\u003e {\n  try {\n    const socks5 = await upgradeSocks5(conn, bndAddrFromNetAddr(conn.localAddr))\n    if (!socks5) throw new Error('SOCKS5 upgrade failed')\n\n    const metric = await Promise.all([\n      // client -\u003e server\n      copy(conn, socks5.distConn),\n      // server -\u003e client\n      copy(socks5.distConn, conn),\n    ])\n    metric // Statistic\n      ? console.log('close conn', {RX: metric[1], TX: metric[0]})\n      : console.log('close conn')\n  } catch (e) {\n    if (e instanceof Error) {\n      console.error(e.name, e.message)\n    }\n  }\n})\n```\n\n## [WebSocket Stream Server (RFC 6455)](https://datatracker.ietf.org/doc/html/rfc6455)\n\nImplementing Websocket as a [WebSocketStream](https://github.com/ricea/websocketstream-explainer) server using [StreamApi](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)\n\nUsage:\n\n```ts\n#!/usr/bin/env -S deno run -A --watch-hmr\n\nimport {serveTcp} from 'https://raw.githubusercontent.com/MAKS11060/deno-protocols/main/utils.ts'\nimport {upgradeWebSocketStream} from 'https://raw.githubusercontent.com/MAKS11060/deno-protocols/main/websocket/ws.ts'\n\nserveTcp({port: 8000}, async (conn) =\u003e {\n  console.log(conn.remoteAddr.hostname)\n\n  const {url, headers, readable, writable} = await upgradeWebSocketStream(conn)\n  console.log(url, headers)\n\n  const writer = writable.getWriter()\n  for await (const msg of readable.values()) {\n    console.log({msg})\n    writer.write(msg) // loopback\n  }\n\n  console.log('[WebSocketStream] Close')\n})\n```\n\n## [UPnP Client (RFC 6970)](https://datatracker.ietf.org/doc/html/rfc6970)\n\nThe UPnP Client provides a simple interface for managing network port mappings.\n\n### Methods\n- `getExternalIp()`: Returns the public IP address.\n- `setMapping(options)`: Opens a port with the specified options.\n- `getMapping()`: Returns a list of all current port mappings.\n- `unmap(options)`: Removes a port mapping with the specified options.\n- `unmapAll()`: Removes all port mappings.\n\nUsage:\n\n```ts\n#!/usr/bin/env -S deno run -A --unstable-net\n\nimport {UPnP} from 'https://raw.githubusercontent.com/MAKS11060/deno-protocols/main/upnp/upnp.ts'\n\nconst upnp = new UPnP()\n\n// Get public address\nconsole.log('my ip', await upnp.getExternalIp())\n\n// Open port\nawait upnp.setMapping({remotePort: 8000, ttl: 150})\nconsole.log('upnp list', await upnp.getMapping())\n\n// Remove port\n// await this.unmap({remotePort: 8000})\n\n// Remove all ports\n// await this.unmapAll()\n```\n\n## [STUN Client (RFC 5389)](https://datatracker.ietf.org/doc/html/rfc5389)\n\nUsage:\n\n```ts\n#!/usr/bin/env -S deno run -A --unstable-net\n\nimport {STUN} from 'https://raw.githubusercontent.com/MAKS11060/deno-protocols/main/stun/stun.ts'\n\nconst stun = new STUN('stun.l.google.com:19302')\n\nconsole.log(await stun.getMappedAddress()) // { hostname: \"178.68.144.103\", port: 49646, family: \"IPv4\" }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMAKS11060%2Fprotocols","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMAKS11060%2Fprotocols","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMAKS11060%2Fprotocols/lists"}