purge cache with DELETE method

This commit is contained in:
m5r
2025-09-20 14:35:51 +02:00
parent 2acd6e0bc4
commit a3d639df6c
4 changed files with 57 additions and 2 deletions

View File

@@ -19,6 +19,8 @@ This is a Cloudflare Workers project called "url-cleaner" built with TypeScript.
## API Usage
### Clean URL Endpoint
**Endpoint**: `GET /?url=<encoded-url>`
**Response**: Plain text containing the cleaned URL
@@ -27,6 +29,16 @@ This is a Cloudflare Workers project called "url-cleaner" built with TypeScript.
- `/?url=https://example.com?utm_source=test``https://example.com`
- `/?url=https://youtube.com/watch?v=abc&feature=share``https://youtube.com/watch?v=abc`
### Cache Purge Endpoint
**Endpoint**: `DELETE /?url=<encoded-url>`
**Response**: Plain text confirming cache deletion
**Examples**:
- `DELETE /?url=https://example.com?utm_source=test``Cache entry deleted` (200)
- `DELETE /?url=https://nonexistent.com``Cache entry not found` (404)
## Common Commands
### Development
@@ -67,7 +79,8 @@ test/
- **Fragment Cleaning**: Removes tracking from URL fragments/hash parameters (`#utm_campaign=test`)
- **Raw Rules Support**: Handles complex regex-based cleaning for advanced tracking patterns
- **Loop Prevention**: Tracks visited URLs to prevent infinite redirect loops
- **Response Caching**: 1-hour cache for improved performance
- **Response Caching**: 1-hour cache using Cloudflare Cache API for improved performance
- **Cache Management**: DELETE endpoint for manual cache purging
### Rule System

View File

@@ -6,7 +6,7 @@
"deploy": "wrangler deploy",
"dev": "wrangler dev",
"start": "wrangler dev",
"test": "vitest",
"test": "vitest --run",
"cf-typegen": "wrangler types",
"format": "prettier --write .",
"format:check": "prettier --check ."

View File

@@ -19,6 +19,17 @@ export default {
const cache = caches.default;
const cacheKey = new Request(`${url.origin}/cache/${encodeURIComponent(targetUrl)}`);
if (request.method === "DELETE") {
const deleted = await cache.delete(cacheKey);
return new Response(deleted ? "Cache entry deleted" : "Cache entry not found", {
status: deleted ? 200 : 404,
headers: {
"Content-Type": "text/plain",
"Access-Control-Allow-Origin": "*",
},
});
}
let response = await cache.match(cacheKey);
if (response) {
return response;

View File

@@ -157,4 +157,35 @@ describe("URL Cleaner worker", () => {
expect(response.status).toBe(200); // Should return original URL, not error
expect(await response.text()).toBe("not-a-valid-url");
});
it("deletes cache entry on DELETE request", async () => {
// First, make a GET request to cache the response
const testUrl = "https://tiktok.com/video?_t=tracking&_r=more&u_code=123&normal=keep&other=stay";
const getResponse = await SELF.fetch(`https://example.com/?url=${encodeURIComponent(testUrl)}`);
expect(getResponse.status).toBe(200);
expect(await getResponse.text()).toBe("https://tiktok.com/video?normal=keep&other=stay");
// Then delete the cache entry
const deleteResponse = await SELF.fetch(`https://example.com/?url=${encodeURIComponent(testUrl)}`, {
method: "DELETE",
});
expect(deleteResponse.status).toBe(200);
expect(await deleteResponse.text()).toBe("Cache entry deleted");
const subsequentDeleteResponse = await SELF.fetch(`https://example.com/?url=${encodeURIComponent(testUrl)}`, {
method: "DELETE",
});
expect(subsequentDeleteResponse.status).toBe(404);
expect(await subsequentDeleteResponse.text()).toBe("Cache entry not found");
});
it("returns 404 when deleting non-existent cache entry", async () => {
const testUrl = "https://nonexistent.com?param=value";
const deleteResponse = await SELF.fetch(`https://example.com/?url=${encodeURIComponent(testUrl)}`, {
method: "DELETE",
});
expect(deleteResponse.status).toBe(404);
expect(await deleteResponse.text()).toBe("Cache entry not found");
});
});