Skip to content

Commit cae2688

Browse files
committed
Initial commit
1 parent 0d34192 commit cae2688

File tree

4 files changed

+45
-118
lines changed

4 files changed

+45
-118
lines changed

.prettierrc

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"printWidth": 140,
3-
"singleQuote": true,
3+
"singleQuote": false,
44
"semi": true,
5-
"useTabs": true
5+
"useTabs": false,
6+
"tabWidth": 4
67
}

README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Gemini Proxy on a Cloudflare Worker
2+
3+
This is an attempt to build a barebones HTTP-Gemini proxy on Cloudflare Workers.
4+
5+
The implementation is mostly complete (aside from support for client certificates),
6+
but it's currently broken as there's no way to accept arbitrary self-signed certificates
7+
in Workers for now.
8+
9+
Trying to use `NODE_TLS_REJECT_UNAUTHORIZED = 0` does not work either.
10+
11+
I've opened an feature request for allowing unauthorized certificates here: [cloudflare/workers-sdk #6503](https://github.com/cloudflare/workers-sdk/issues/6503).

src/index.ts

+27-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1-
/**
2-
* Welcome to Cloudflare Workers! This is your first worker.
3-
*
4-
* - Run `npm run dev` in your terminal to start a development server
5-
* - Open a browser tab at http://localhost:8787/ to see your worker in action
6-
* - Run `npm run deploy` to publish your worker
7-
*
8-
* Bind resources to your worker in `wrangler.toml`. After adding bindings, a type definition for the
9-
* `Env` object can be regenerated with `npm run cf-typegen`.
10-
*
11-
* Learn more at https://developers.cloudflare.com/workers/
12-
*/
1+
import { connect } from "cloudflare:sockets";
132

143
export default {
15-
async fetch(request, env, ctx): Promise<Response> {
16-
return new Response('Hello World!');
17-
},
4+
async fetch(request): Promise<Response> {
5+
try {
6+
const address = new URL(request.url).pathname.substring(1);
7+
const url = new URL(address);
8+
url.port = url.port.length == 0 ? "1965" : url.port;
9+
10+
const socketAddress: SocketAddress = {
11+
hostname: url.hostname,
12+
port: Number(url.port),
13+
};
14+
const socketOptions: SocketOptions = {
15+
secureTransport: "starttls",
16+
allowHalfOpen: false
17+
};
18+
const socket = connect(socketAddress, socketOptions).startTls();
19+
20+
const writer = socket.writable.getWriter();
21+
const encoder = new TextEncoder();
22+
const encoded = encoder.encode(`${url.pathname}\r\n`);
23+
await writer.write(encoded);
24+
25+
return new Response(socket.readable, { headers: { "Content-Type": "text/plain" } });
26+
} catch (error) {
27+
return new Response("Socket connection failed: " + error, { status: 500 });
28+
}
29+
},
1830
} satisfies ExportedHandler<Env>;

wrangler.toml

+4-101
Original file line numberDiff line numberDiff line change
@@ -4,105 +4,8 @@ main = "src/index.ts"
44
compatibility_date = "2024-08-06"
55
compatibility_flags = ["nodejs_compat"]
66

7-
# Automatically place your workloads in an optimal location to minimize latency.
8-
# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure
9-
# rather than the end user may result in better performance.
10-
# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
11-
# [placement]
12-
# mode = "smart"
7+
[placement]
8+
mode = "smart"
139

14-
# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables)
15-
# Docs:
16-
# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
17-
# Note: Use secrets to store sensitive data.
18-
# - https://developers.cloudflare.com/workers/configuration/secrets/
19-
# [vars]
20-
# MY_VARIABLE = "production_value"
21-
22-
# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network
23-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai
24-
# [ai]
25-
# binding = "AI"
26-
27-
# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function.
28-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets
29-
# [[analytics_engine_datasets]]
30-
# binding = "MY_DATASET"
31-
32-
# Bind a headless browser instance running on Cloudflare's global network.
33-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering
34-
# [browser]
35-
# binding = "MY_BROWSER"
36-
37-
# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database.
38-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases
39-
# [[d1_databases]]
40-
# binding = "MY_DB"
41-
# database_name = "my-database"
42-
# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
43-
44-
# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers.
45-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms
46-
# [[dispatch_namespaces]]
47-
# binding = "MY_DISPATCHER"
48-
# namespace = "my-namespace"
49-
50-
# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model.
51-
# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps.
52-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects
53-
# [[durable_objects.bindings]]
54-
# name = "MY_DURABLE_OBJECT"
55-
# class_name = "MyDurableObject"
56-
57-
# Durable Object migrations.
58-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations
59-
# [[migrations]]
60-
# tag = "v1"
61-
# new_classes = ["MyDurableObject"]
62-
63-
# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers.
64-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive
65-
# [[hyperdrive]]
66-
# binding = "MY_HYPERDRIVE"
67-
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
68-
69-
# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs.
70-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces
71-
# [[kv_namespaces]]
72-
# binding = "MY_KV_NAMESPACE"
73-
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
74-
75-
# Bind an mTLS certificate. Use to present a client certificate when communicating with another service.
76-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates
77-
# [[mtls_certificates]]
78-
# binding = "MY_CERTIFICATE"
79-
# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
80-
81-
# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer.
82-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues
83-
# [[queues.producers]]
84-
# binding = "MY_QUEUE"
85-
# queue = "my-queue"
86-
87-
# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them.
88-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues
89-
# [[queues.consumers]]
90-
# queue = "my-queue"
91-
92-
# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files.
93-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets
94-
# [[r2_buckets]]
95-
# binding = "MY_BUCKET"
96-
# bucket_name = "my-bucket"
97-
98-
# Bind another Worker service. Use this binding to call another Worker without network overhead.
99-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
100-
# [[services]]
101-
# binding = "MY_SERVICE"
102-
# service = "my-service"
103-
104-
# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases.
105-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes
106-
# [[vectorize]]
107-
# binding = "MY_INDEX"
108-
# index_name = "my-index"
10+
[vars]
11+
NODE_TLS_REJECT_UNAUTHORIZED = 0

0 commit comments

Comments
 (0)