adventofcode 2023-11-17

Using Cloudflare Workers for this is very convenient: It’s deployed in seconds and you can just edit and test the worker code in their browser console. You could follow this example, I just deployed it in under 2 minutes: https://developers.cloudflare.com/workers/examples/cors-header-proxy/ handleOptions and handleRequest are the important functions here. If you don’t want to create a Cloudflare account but are interested, feel free to ping me and you could use my worker.

@trost.mario I thought about that but wouldn't that be costly if everyone would go through my worker?

The free tier is 100'000 requests per day. Paid tier is minimum charge of $5 per month, 1 million requests cost $0.15 So you'd need lots of users to get it to what I call expensive! Every Clojure dev and then some? :)

what about network traffic though? downloading those inputs and serving them up

"Up to 10ms CPU time per request", what do they mean by that? 10ms seems not a lot

When you wait for requests it doesn’t count

You can fetch third party apis that take multiple seconds and that doesn’t count at all

Seem great, why has nobody done this before for AOC then ;)

> Up to 10ms CPU time per request This often gets misunderstood: You can make requests to other third party services and also to Cloudflare services like Cache, Images, KV storage, Durable Objects etc. and all of that does not count to the limit

> Seem great, why has nobody done this before for AOC then ;) Haven’t they? 😄

> what about network traffic though? downloading those inputs and serving them up I think it’s free. If they notice you do stuff in the free account, that isn’t “fair use”, like proxying a Media Server with lots of traffic, then they just stop your worker.

I would do this, but only if I can be 100% sure I won't receive a bill because of overnight bots trying to spam my worker

I guess compared with the amount of network traffic their “normal” product (reverse proxy for half the internet) the free workers traffic is just a rounding error

In the free tier it just stops serving requests when you reach the limit of 100k per day

I’m not even sure you have to give them your credit card details 🤷

last time I didn't

cool, so I could make an aoc app that is powered by squint worker and a squint playground to do the solutions

and maybe a popup to enter your aoc session which can be stored in a cookie

Yes, I guess that shouldn’t be that difficult!

ok, I might have a go at this tomorrow...

Very cool! I wanted to try out the Remix.run Cloudflare Workers template and adjust it to use Squint, but never came around to it. But just using a vanilla Cloudflare Workers setup shouldn’t be too difficult. Or: You could even try using Cloudflare Pages (it is powered by Cloudflare Workers): It’s similar to Netlify and Vercel in that you can connect your repository and do some basic configuration (build command and directory) and they build and deploy it for you plus preview deployments for every pull request.

I already figured out how to deploy code for just a vanilla worker: https://github.com/borkdude/squint-bun-cloudflare

🙌 1

not strictly necessary, just mixing various hyped technologies all at once: bun loader + cloudflare workers

Trailblazing as usual 🚀 And hype driven engineering is a legit thing 😄 Especially when the hype is warranted thanks for sharing! I’m off to bed now, good night to you

And: wish you success tomorrow 🙂

🙏 1

I guess I could limit access to the worker only from a specific domain, like the squint github pages right?

but that's probably easy to fake with a CLI http client

Yes, you could limit it to domain plus set a secure, http-only cookie on the first request and check for that on subsequent ones

Both can be faked outside a browser, but gets harder and harder, the more you add. Some hidden inputs that get sent along on form submits, CSRF tokens etc.

it's very strange, in bun at least, when I use js/fetch to call another API, it calls my own worker

(defn ^:async fetch [req _env _ctx]
  (if-let [aoc-token (some-> req :headers (.get :cookie) (cookie/parse) :AOC_TOKEN)]
    (let [params (-> req :url (js/URL.) :searchParams)
          {:keys [day year]} params]
      (if (and day year)
        (let [resp (js-await (js/fetch (js/Request. (str "" year "/day/" day "/input"))))]
          (if-not (:ok resp)
            (do
              (prn :not-ok!!!)
              (js/console.log resp)
              (let [txt (js-await (.text resp))]
                (js/console.log :txt txt)
                (js/Response. txt)))
            (js/Response. "dude")))
        (js/Response. "Set 'day' and 'year' as a URL query parameter")))
    (do
      (prn :ending-up-here)
      (js/Response. "Set 'AOC_TOKEN' as a cookie." {:status 400}))))

somehow the "url" of the response is empty:

url: ""

oh dang... I called my function fetch which overwrites js/fetch facepalm

thanks duckie

🙌 1

it works magically now

The entire code for this worker:

(ns index
  (:require ["cookie" :as cookie]))

(defn ^:async handler [req _env _ctx]
  (if-let [aoc-token (some-> req :headers (.get :cookie) (cookie/parse) :AOC_TOKEN)]
    (let [params (-> req :url (js/URL.) :searchParams)
          {:keys [day year]} params]
      (if (and day year)
        (let [resp (js-await (js/fetch (str "" year "/day/" day "/input")
                                       {:headers {:cookie (str "session=" aoc-token)}}))]
          resp)
        (js/Response. "Set 'day' and 'year' as a URL query parameter")))
    (js/Response. "Set 'AOC_TOKEN' as a cookie." {:status 400})))

(def default
  {:fetch handler})

curl '' --cookie "AOC_TOKEN=<your-session>"

I'm still running into CORS issues when I do the request from the website and I'm about to give up on this

ERR_CONTENT_DECODING_FAILED - some other error

aaaah got it, I just copied too much from the original response

duckie

😄 1

the server (adventofcode) would need to respond with the appropriate CORS headers to allow cross-origin requests

otherwise you would need to proxy the request through a non-browser environment

yeah, it's a bit inconvenient since this doesn't let you solve AoC puzzles from a browser playground I guess I could write a service that requests the input on your behalf