Skip to content

Commit 3c928e3

Browse files
committed
Prepare repo for open source
1 parent 716bb1e commit 3c928e3

3 files changed

Lines changed: 53 additions & 6 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 GIPHY
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# GIPHY Bandwidth Saver
22

3-
GIPHY Bandwidth Saver is a local demo proxy that validates GIPHY media with the origin while avoiding redundant media downloads when the same GIF rendition has already been observed. It is intentionally not a login proxy, not a crawler, and not an offline mirror. The design keeps GIPHY in the request path for freshness and removal semantics while reducing repeated transfer of identical media bytes.
3+
GIPHY Bandwidth Saver is an MIT-licensed reference implementation for a revalidating GIPHY media cache. It includes a local website/API proxy so you can demo the behavior against the live GIPHY website, plus conformance harnesses that other implementations can adapt to prove request accounting, revalidation, replacement, deletion, and range behavior.
4+
5+
This repository is intentionally not a drop-in production proxy, not a login proxy, not a crawler, and not an offline mirror. The reusable idea is narrower: keep GIPHY in the request path for freshness and removal semantics while avoiding redundant media-byte downloads when the same GIF rendition has already been observed.
46

57
<img width="1440" height="1058" alt="image" src="https://github.com/user-attachments/assets/49cf8b22-2c93-45fe-a6cf-7a5b4a4e34ef" />
68

@@ -20,7 +22,7 @@ This project demonstrates a corporate-friendly middle ground:
2022

2123
The result complies with the spirit of origin-controlled media delivery: GIPHY continues to receive validation traffic with enough request context to inform popularity-driven ranking and removal decisions, while consumers avoid unnecessary bandwidth spend and preserve user anonymity.
2224

23-
## Runtime
25+
## Demo Quick Start
2426

2527
This project uses pnpm and Node 24.
2628

@@ -37,7 +39,9 @@ Then open:
3739
https://web.localhost:8080
3840
```
3941

40-
The server listens on `127.0.0.1` and uses local HTTPS with HTTP/2 by default. That default matters: without HTTP/2, the browser-to-proxy side no longer behaves like the CDN path and media loading looks much slower than the cache design actually is. You can override runtime paths with:
42+
This starts the local website proxy for `giphy.com`, rewrites page/API/media URLs to local hostnames, and routes media requests through the revalidating media cache. Scroll the proxied GIPHY homepage to load GIFs, then scroll back through already-seen media while watching the TUI. Repeated media should still be revalidated upstream, but upstream `304` responses should let the proxy serve local bytes and count avoided downloads.
43+
44+
The server listens on `127.0.0.1` and uses local HTTPS with HTTP/2 by default. That default matters for the demo: without HTTP/2, the browser-to-proxy side no longer behaves like the CDN path and media loading looks much slower than the cache design actually is. You can override runtime paths with:
4145

4246
```sh
4347
PORT=8081 CACHE_DIR=cache pnpm dev
@@ -118,7 +122,7 @@ The web and API proxies rewrite GIPHY host strings based on response content typ
118122

119123
## Code Boundaries
120124

121-
The demo-only website/API rewriting code is intentionally isolated from the media cache. This keeps the reusable bandwidth-saving path obvious.
125+
The demo-only website/API rewriting code is intentionally isolated from the media cache. This keeps the reusable bandwidth-saving reference path obvious.
122126

123127
Demo proxy files:
124128

@@ -139,6 +143,8 @@ Shared infrastructure:
139143

140144
Architecture tests assert that media cache modules do not import demo rewrite helpers and demo rewrite modules do not import cache storage.
141145

146+
For another implementation, the media-cache contract is the part to study first. The website/API proxy is scaffolding for making the reference implementation easy to run in a browser.
147+
142148
## Upstream Networking
143149

144150
All upstream GIPHY calls use an explicit HTTPS keep-alive agent instead of relying on Node's global defaults. The agent keeps HTTP/1.1 connections reusable across requests, caps socket fan-out, and keeps a bounded pool of idle sockets:
@@ -276,7 +282,7 @@ Important edge-case contracts:
276282

277283
### Test Harness
278284

279-
The E2E tests use a simulated target media server and a conformance client:
285+
The E2E tests double as validation harnesses for the reference implementation. They use a simulated target media server and a conformance client:
280286

281287
- The target server accepts a response program per asset: repeated `304`s, replacement `200`s, deletion `404` / `410` steps, weighted transition windows, delays, and payload bodies.
282288
- The client sends unique fingerprints on every request and can vary method, range headers, `If-Range`, and browser validators.
@@ -296,6 +302,13 @@ CONFORMANCE_STRESS=1 CONFORMANCE_STRESS_COUNT=30000 CONFORMANCE_STRESS_CONCURREN
296302

297303
The stress scenarios cover tens of thousands of unique fingerprints across shared media GIF IDs, renditions (`giphy`, `200`, `200w`, `100`), and file types: GIFs as `.gif`, `.mp4`, and `.webp`; Clips as `.mp4`; Stickers as `.gif` and `.webp`.
298304

305+
To validate your own media proxy, adapt the harness model documented in [docs/media-proxy-conformance-harness.md](docs/media-proxy-conformance-harness.md): send each client request with a unique `x-giphy-conformance-fingerprint`, preserve that header on upstream validation/download requests, record target-server receipts, and compare planned fingerprints, client responses, upstream receipts, and final cache state. The lowest-friction path is to reuse the target server, synthetic client, scenario definitions, and assertion ledger under `test/support/`, then replace this repo's proxy startup with your proxy under test.
306+
307+
Use these helper scripts when shaping or debugging another implementation:
308+
309+
- `pnpm cache:summary [path/to/metadata.sqlite]` summarizes a local cache database into safe aggregate fixture shape data.
310+
- `pnpm media:characterize <media-url> [more URLs]` probes live media URL semantics such as `HEAD`, validators, negative responses, and range behavior without storing payload bytes.
311+
299312
### Browser Cache Validation
300313

301314
To validate the browser cache layer in Chrome or Edge:
@@ -317,6 +330,17 @@ Expected browser behavior:
317330

318331
If you do not see browser disk-cache hits or browser-facing `304` responses, first confirm `Disable cache` is off. If it is off, the most likely cause is a certificate error preventing Chrome from caching and reusing images for that local HTTPS origin. In that case, the proxy disk cache is still working and will still avoid upstream media downloads after origin revalidation, but browser-to-proxy transfers will continue and the TUI will overstate end-user network bandwidth saved. Use `pnpm tls:mkcert` or `TLS_CERT_FILE` / `TLS_KEY_FILE` to run with a locally trusted certificate when validating browser cache behavior.
319332

333+
## Exercises Left To The Reader
334+
335+
This reference implementation keeps several production concerns explicit instead of hiding them behind demo code:
336+
337+
- Production deployment: packaging this behind a real CDN, load balancer, container image, process supervisor, or multi-region topology is out of scope.
338+
- Multi-node cache sharing: the demo uses local SQLite plus disk files. A production implementation needs its own answer for shared storage, eviction, backpressure, and node-local hot caches.
339+
- Policy integration: authentication, authorization, rate limiting, tenant isolation, abuse controls, and audit logging are not implemented here.
340+
- Observability: the TUI is useful for local demos, but production use needs metrics, tracing, alerting, and structured logs.
341+
- Standalone harness packaging: the conformance harness is written so another proxy can adapt it, but it is not currently published as a separate npm package or CLI.
342+
- Browser automation: browser-cache validation is documented as a manual Chrome/Edge workflow. A production-quality validation suite could add Playwright coverage for DevTools-visible disk-cache and `304` behavior.
343+
320344
## Terminal UI
321345

322346
The TUI starts with the proxy and shows:

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
22
"name": "giphy-bandwidth-saver",
33
"version": "0.1.0",
4-
"private": true,
4+
"description": "Reference implementation of a revalidating GIPHY media cache proxy.",
5+
"license": "MIT",
6+
"author": "GIPHY",
57
"type": "module",
68
"packageManager": "pnpm@10.33.0",
79
"engines": {

0 commit comments

Comments
 (0)