upstream.test.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import { describe, expect, it, vi } from 'vitest'
  2. import { CookieJar, UpstreamClient } from '../../src/server/upstream.js'
  3. describe('upstream request boundary', () => {
  4. it('rejects a path that URL normalization would escape', async () => {
  5. const fetchImpl = vi.fn<typeof fetch>()
  6. const client = new UpstreamClient(new URL('http://127.0.0.1:9119'), fetchImpl)
  7. await expect(client.request('/api/sessions/..', new CookieJar())).rejects.toThrow(/normalization/i)
  8. expect(fetchImpl).not.toHaveBeenCalled()
  9. })
  10. it('derives proxy scheme from public 15300 TLS and forwards only the trusted peer IP', async () => {
  11. let headers = new Headers()
  12. const fetchImpl = vi.fn<typeof fetch>(async (_input, init) => {
  13. headers = new Headers(init?.headers)
  14. return new Response('{}', {
  15. status: 200,
  16. headers: { 'content-type': 'application/json', 'set-cookie': 'session=test; Path=/; HttpOnly; SameSite=Lax' },
  17. })
  18. })
  19. const jar = new CookieJar()
  20. const client = new UpstreamClient(new URL('http://127.0.0.1:9119'), fetchImpl, true)
  21. await client.request('/api/status', jar, { clientAddress: '::ffff:192.168.1.22' })
  22. expect(headers.get('x-forwarded-proto')).toBe('https')
  23. expect(headers.get('x-forwarded-for')).toBe('192.168.1.22')
  24. expect(jar.browserCookies[0]).toContain('Secure')
  25. expect(jar.browserCookies[0]).not.toMatch(/Domain=/i)
  26. })
  27. })
  28. it('allows the Hermes memory helper to finish within its 90-second budget without changing normal request deadlines',async()=>{
  29. vi.useFakeTimers()
  30. const fetchImpl=vi.fn<typeof fetch>(()=>new Promise(done=>setTimeout(()=>done(new Response('{"text":"memory"}')),40000)))
  31. const client=new UpstreamClient(new URL('http://127.0.0.1:9119'),fetchImpl)
  32. try{
  33. const normal=client.request('/api/status',new CookieJar()),rejected=expect(normal).rejects.toThrow('request timed out')
  34. await vi.advanceTimersByTimeAsync(30001);await rejected
  35. const memory=client.request('/api/plugins/yaoyao-bot-bridge/memory-extract',new CookieJar(),{method:'POST',body:{profile:'default',prompt:'facts'}})
  36. await vi.advanceTimersByTimeAsync(40001)
  37. expect(JSON.parse((await memory).body.toString())).toEqual({text:'memory'})
  38. }finally{client.close();vi.clearAllTimers();vi.useRealTimers()}
  39. })