diff options
author | Tomasz Kramkowski <tomasz@kramkow.ski> | 2023-03-27 18:51:13 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tomasz@kramkow.ski> | 2023-03-27 19:01:34 +0100 |
commit | 058771b594e9382cd65f3366129e017e357d659b (patch) | |
tree | fc9883deffec9f125e7ce0e5d86e6fef8a2f6b7f | |
parent | 43384a64917cfe25af62376da19e311e628e0d4c (diff) | |
download | paste-058771b594e9382cd65f3366129e017e357d659b.tar.gz paste-058771b594e9382cd65f3366129e017e357d659b.tar.xz paste-058771b594e9382cd65f3366129e017e357d659b.zip |
Only handle PUT requests and respond correctly
Previously PUT and POST requests were handled the same way, this isn't
correct and POST should be used for the functionality where a random URL
is generated. Additionally PUT should reply with 201 when inserting and
204 when updating.
-rw-r--r-- | paste/__init__.py | 13 | ||||
-rw-r--r-- | paste/store.py | 21 |
2 files changed, 22 insertions, 12 deletions
diff --git a/paste/__init__.py b/paste/__init__.py index edf1951..76a20a3 100644 --- a/paste/__init__.py +++ b/paste/__init__.py @@ -249,14 +249,19 @@ def application(environ: Env, start_response: StartResponse) -> Response: ], ) return [] - elif environ["REQUEST_METHOD"] in {"POST", "PUT"}: + elif environ["REQUEST_METHOD"] == "PUT": content_type = environ.get("CONTENT_TYPE", "text/plain") content_length = int(environ["CONTENT_LENGTH"]) content = environ["wsgi.input"].read(content_length) - store.put(conn, name, content, content_type) - return redirect( - start_response, request_uri(environ).encode(), "text/x.redirect.302" + created, content_hash = store.put(conn, name, content, content_type) + start_response( + "201 Created" if created else "204 No Content", + [ + ("Location", request_uri(environ)), + ("ETag", f'"{b64encode(content_hash).decode()}"'), + ], ) + return [] elif environ["REQUEST_METHOD"] == "DELETE": store.delete(conn, name) return simple_response(start_response, "204 No Content") diff --git a/paste/store.py b/paste/store.py index 26643cf..82e66c0 100644 --- a/paste/store.py +++ b/paste/store.py @@ -7,17 +7,22 @@ def put(conn: Connection, name: str, content: bytes, content_type: str): "INSERT OR IGNORE INTO file (content) VALUES (?)", (content,), ) + (content_hash,) = conn.execute("SELECT DATA_HASH(?)", (content,)).fetchone() + cur = conn.execute( + """UPDATE link + SET content_type = ?, file_hash = ? + WHERE name_hash = DATA_HASH(?)""", + (content_type, content_hash, name), + ) + if cur.rowcount == 1: + return False, content_hash conn.execute( - """ - INSERT INTO link ( + """INSERT INTO link ( name, content_type, file_hash - ) VALUES (?, ?, DATA_HASH(?)) - ON CONFLICT DO UPDATE - SET - content_type = excluded.content_type, - file_hash = excluded.file_hash""", - (name, content_type, content), + ) VALUES (?, ?, ?)""", + (name, content_type, content_hash), ) + return True, content_hash def get(conn: Connection, name: str): |