File size: 1,586 Bytes
74f2af5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * Reverse Proxy for Codette HF Space
 * Strips X-Frame-Options header to allow embedding
 * Deploy to Railway.app or Fly.io for free
 */

const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json({ limit: '10mb' }));

const HF_SPACE_URL = 'https://huggingface.co/spaces/Raiff1982/codette-ai';

// Proxy all requests to HF Space, strip X-Frame-Options
app.all('*', async (req, res) => {
  try {
    const targetUrl = HF_SPACE_URL + req.originalUrl;

    const response = await axios({
      method: req.method,
      url: targetUrl,
      headers: {
        ...req.headers,
        host: 'huggingface.co',
      },
      data: req.body,
      validateStatus: () => true, // Accept all status codes
      responseType: 'stream',
      maxRedirects: 5,
    });

    // Copy response headers, but remove X-Frame-Options
    Object.entries(response.headers).forEach(([key, value]) => {
      if (key.toLowerCase() !== 'x-frame-options') {
        res.setHeader(key, value);
      }
    });

    // Add CORS headers for safety
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

    res.status(response.status);
    response.data.pipe(res);
  } catch (err) {
    console.error('Proxy error:', err.message);
    res.status(500).json({ error: err.message });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Proxy running on port ${PORT}`));