File size: 2,756 Bytes
5dfbe50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import * as https from 'https';
import * as fs from 'fs';
import { config } from '../config';

interface VespaRequestOptions {
  method?: string;
  headers?: Record<string, string>;
  body?: string;
}

export async function vespaRequest(url: string, options: VespaRequestOptions = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    const urlObj = new URL(url);
    
    const httpsOptions: https.RequestOptions = {
      hostname: urlObj.hostname,
      port: 443,
      path: urlObj.pathname + urlObj.search,
      method: options.method || 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        ...options.headers
      }
    };

    // Add certificate authentication if available
    if (config.vespaCertPath && config.vespaKeyPath) {
      try {
        httpsOptions.cert = fs.readFileSync(config.vespaCertPath);
        httpsOptions.key = fs.readFileSync(config.vespaKeyPath);
        httpsOptions.rejectUnauthorized = false;
      } catch (error) {
        console.error('Failed to load certificates:', error);
      }
    }

    const req = https.request(httpsOptions, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
          try {
            resolve({
              ok: true,
              status: res.statusCode,
              json: async () => JSON.parse(data),
              text: async () => data
            });
          } catch (error) {
            reject(error);
          }
        } else if (res.statusCode === 504) {
          // Handle timeout as success if we got data
          try {
            const parsed = JSON.parse(data);
            if (parsed.root && parsed.root.children) {
              resolve({
                ok: false,  // Keep ok: false for proper handling
                status: res.statusCode,
                json: async () => parsed,
                text: async () => data
              });
            } else {
              resolve({
                ok: false,
                status: res.statusCode,
                text: async () => data
              });
            }
          } catch (error) {
            resolve({
              ok: false,
              status: res.statusCode,
              text: async () => data
            });
          }
        } else {
          resolve({
            ok: false,
            status: res.statusCode,
            text: async () => data
          });
        }
      });
    });

    req.on('error', (error) => {
      reject(error);
    });

    if (options.body) {
      req.write(options.body);
    }

    req.end();
  });
}