Files

Cloudflare Pages Functions

This directory contains Cloudflare Pages Functions for routing and proxying requests to the KohakuHub backend API.

How It Works

Cloudflare Pages serves the static frontend and uses Functions to proxy API/backend requests to your origin server.

Request Flow:

User → Cloudflare Pages (CDN) → Functions (routing) → Your Server (API)
                               ↓
                        Static files served from CDN

Directory Structure

functions/
├── _middleware.js                        # Middleware applied to all requests
├── _proxy.js                             # Shared proxy handler
├── _utils.js                             # Proxy utilities with Git protocol support
├── api/[[path]].js                       # Catch-all for /api/* routes
├── org/[[path]].js                       # Organization routes
├── [[repo]].git/                         # Git Smart HTTP protocol
│   ├── info/
│   │   ├── refs.js                       # Service advertisement
│   │   └── lfs/[[path]].js               # Git LFS
│   ├── git-upload-pack.js                # Clone/fetch/pull
│   ├── git-receive-pack.js               # Push
│   └── HEAD.js                           # HEAD reference
├── models/[[namespace]]/[[name]]/resolve/[[path]].js  # Model file downloads
├── datasets/.../resolve/[[path]].js      # Dataset file downloads
├── spaces/.../resolve/[[path]].js        # Space file downloads
└── [[namespace]]/[[name]]/resolve/[[path]].js  # Legacy file downloads

Git Protocol Handling

Special Configuration for Git:

Git Smart HTTP requires special handling:

  • No caching - Responses must not be cached
  • Preserve headers - Content-Type must be preserved
  • No CORS - Git clients don't support CORS headers

Implementation in _utils.js:

if (isGitRequest(pathname)) {
  // Prevent caching (critical!)
  headers.set('Cache-Control', 'no-store, no-cache, must-revalidate');
  headers.set('X-Content-Type-Options', 'nosniff');
  headers.set('X-Accel-Buffering', 'no');
  // NO CORS headers (breaks Git clients)
}

Routes Configuration

public/_routes.json specifies which paths should be handled by Functions:

{
  "include": [
    "/api/*",
    "/org/*",
    "/*.git/info/refs",          // Git service advertisement
    "/*.git/git-upload-pack",    // Git clone/fetch/pull
    "/*.git/git-receive-pack",   // Git push
    "/*.git/HEAD",               // Git HEAD reference
    "/*.git/info/lfs/*",         // Git LFS
    "/models/*/*/resolve/*",     // File downloads
    ...
  ]
}

Environment Variables

Set in Cloudflare Pages dashboard:

API_BASE_URL=https://api.your-hub.com  # Your backend API URL

If not set, defaults to http://hub-api:48888 (Docker internal).

Testing Locally

# Install Wrangler
npm install -g wrangler

# Test functions locally
wrangler pages dev dist --compatibility-date=2024-01-01

# Test Git clone
git clone http://localhost:8788/namespace/repo.git

Deployment

Functions are automatically deployed with Cloudflare Pages:

  1. Push to GitHub
  2. Cloudflare Pages builds frontend
  3. Functions deployed from functions/ directory
  4. Environment variables applied

Troubleshooting

Git clone fails:

  • Check _routes.json includes Git paths
  • Verify isGitRequest() detects Git URLs correctly
  • Ensure no caching headers are set
  • Check Cloudflare Page Rules don't interfere

CORS errors:

  • Git protocol should NOT have CORS headers
  • Browser requests should have CORS headers
  • Check isGitRequest() logic

404 errors:

  • Verify path is in _routes.json include list
  • Check function file exists for the route pattern
  • Verify API_BASE_URL environment variable

Last Updated: October 2025