From d5f705ae7296b2d1e0675af03298f40c828a76eb Mon Sep 17 00:00:00 2001 From: alyssadev Date: Mon, 18 Sep 2023 04:35:05 +1000 Subject: [PATCH] file support --- README.md | 12 +++--------- src/index.js | 27 ++++++++++++++------------- test.py | 41 ++++++++++++++++------------------------- 3 files changed, 33 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index b260781..b4833a0 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ Deploying * `wrangler kv:namespace create KV` * `wrangler kv:namespace create AUTH` * `wrangler kv:key put --binding AUTH "$AUTH_KEY" 1` (or any truthy value you prefer) +* `wrangler r2 bucket create files` * Update the namespace IDs in `wrangler.toml` per the two above namespaces. For test namespaces, pass `--preview` to the namespace create commands and update the preview IDs as well +* also add the binding for the r2 bucket, `{ binding = "FILES", bucket_name = "files" }` * While you're in wrangler.toml, update the custom domain in `routes[0].pattern` and the unauth redirect url in `vars.REDIR_URL` to your desired values * `wrangler dev -r` to test with provided preview namespaces, or `wrangler deploy` * Install python3 and python3-requests, then run `DEPLOY_HOST=https://linkie.username.workers.dev AUTH_KEY=$AUTH_KEY python3 test.py` to run tests to ensure linkie is functioning normally. If the script outputs nothing other than `Running on $DEPLOY_HOST`, the tests succeeded. @@ -26,15 +28,7 @@ Usage `curl -n -d u=http://example.com linkie/path` will make `http://linkie/path` 302 redirect to the provided url. use .netrc to store the auth username/password (inspired by ix.io). Yes it supports emoji -`curl -n -F 'u=<-' linkie/path` will make the path 302 redirect to the url provided on stdin. Doesn't support more than one url or anything that's not a url. For instance: - -``` -curl -F 'u=<-' linkie/_ < http://example.comhttp//example.com?2 -``` +`curl -n -F "u=@filename.json" linkie/path` now does file uploading to the connected R2 bucket, so that's neat. just don't forget the `u=` `curl -n -d u=http://example.com linkie/_`, if you provide an underscore as the path linkie will generate a four character path from a-z0-9. if it has a collision five times in a row it'll return 500.. at that point i'd probably increase the length of the random ids in the function at the top of index.js to 5 or something, and also i should get off the internet because i've generated 36^4 short urls with this service and that's insane diff --git a/src/index.js b/src/index.js index 2306953..7446895 100644 --- a/src/index.js +++ b/src/index.js @@ -53,10 +53,10 @@ async function add(request,host,path) { return new Response(`https://${host}/${path}`, {status:201}) } catch (e) { if (e instanceof TypeError) { -// await FILES.put(path, request.body) -// await KV.delete(path) -// return new Response(`https://${host}/${path}`, {status:201}) - return new Response("No valid URL provided",{status:400}); + await FILES.put(path, dest) + await KV.put(path,dest.type) + return new Response(`https://${host}/${path}`, {status:201}) +// return new Response("No valid URL provided",{status:400}); } else throw e; }; @@ -86,17 +86,18 @@ async function get(request,host,path) { if (!path) return Response.redirect(REDIR_URL,301) path = path.toLowerCase() - // URL shortening + const dest_file = await FILES.get(path) + if (dest_file) { + const mime = await KV.get(path) + const headers = new Headers() + dest_file.writeHttpMetadata(headers) + headers.set("etag", dest_file.httpEtag) + headers.set("content-type", mime) + return new Response(dest_file.body, { headers, } ) + } const dest = await KV.get(path) if (dest) return Response.redirect(dest, 302) - - // File uploading - const dest_file = await FILES.get(path) - if (!dest_file) return new Response("Path not found", {status:404}) - const headers = new Headers() - dest_file.writeHttpMetadata(headers) - headers.set("etag", object.httpEtag) - return new Response(object.body, { headers, } ) + return new Response("Path not found", {status:404}) } async function handleRequest(request) { diff --git a/test.py b/test.py index 7d3f22a..3dce193 100644 --- a/test.py +++ b/test.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from requests import request,get,put,post,patch,delete from os import environ +from mimetypes import guess_type host = environ.get("DEPLOY_HOST", "https://linkie.username.workers.dev") auth = {"Authorization": environ.get("AUTH_KEY", "")} @@ -27,26 +28,15 @@ try: # auth put wo data req = put(host + path,data={},headers=auth) assert req.status_code == 400 # auth put wo data - req = post(host + path,data={},headers=auth) - assert req.status_code == 400 # auth post wo data - req = patch(host + path,data={},headers=auth) - assert req.status_code == 400 # auth patch wo data - # auth put invalid url - req = put(host + path,data={"u": "golf sale"},headers=auth) - assert req.status_code == 400 # auth put invalid url - req = post(host + path,data={"u": "golf sale"},headers=auth) - assert req.status_code == 400 # auth post invalid url - req = patch(host + path,data={"u": "golf sale"},headers=auth) - assert req.status_code == 400 # auth patch invalid url +# # auth put invalid url +# req = put(host + path,data={"u": "golf sale"},headers=auth) +# assert req.status_code == 400 # auth put invalid url +# # invalid urls would now be stored as files instead # auth put wo path req = put(host,data={"u": "http://www.example.com"},headers=auth) assert req.status_code == 400 # auth put wo path - req = post(host,data={"u": "http://www.example.com"},headers=auth) - assert req.status_code == 400 # auth post wo path - req = post(host,data={"u": "http://www.example.com"},headers=auth) - assert req.status_code == 400 # auth patch wo path # auth put valid req = put(host + path,data={"u": "http://www.example.com/?put"},headers=auth) @@ -54,16 +44,6 @@ try: req = get(host + path, allow_redirects=False) assert req.status_code == 302 and req.headers["location"] == "http://www.example.com/?put" - req = post(host + path + "post",data={"u": "http://www.example.com/?post"},headers=auth) - assert req.status_code == 201 # auth post valid - req = get(host + path + "post", allow_redirects=False) - assert req.status_code == 302 and req.headers["location"] == "http://www.example.com/?post" - - req = patch(host + path + "patch",data={"u": "http://www.example.com/?patch"},headers=auth) - assert req.status_code == 201 # auth patch valid - req = get(host + path + "patch", allow_redirects=False) - assert req.status_code == 302 and req.headers["location"] == "http://www.example.com/?patch" - # auth delete wo path req = delete(host,headers=auth) assert req.status_code == 400 # auth delete wo path @@ -73,6 +53,17 @@ try: assert req.status_code == 200 # auth delete valid # req = get(host + path, allow_redirects=False) # assert req.status_code == 404 + + # auth put file valid + fn = "package.json" + mime = guess_type(fn)[0] + with open(fn, "rb") as f: + files = {'u': (fn, f, mime)} + req = put(host + path,headers=auth,files=files) + assert req.status_code == 201 # auth put file valid + req = get(host + path, allow_redirects=False) + assert req.status_code == 200 and req.headers["content-type"] == mime + except AssertionError: print(req,req.headers,req.text) raise