headers.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package jsc
  2. import (
  3. "net/http"
  4. "reflect"
  5. "github.com/sagernet/sing/common"
  6. F "github.com/sagernet/sing/common/format"
  7. "github.com/dop251/goja"
  8. )
  9. func HeadersToValue(runtime *goja.Runtime, headers http.Header) goja.Value {
  10. object := runtime.NewObject()
  11. for key, value := range headers {
  12. if len(value) == 1 {
  13. object.Set(key, value[0])
  14. } else {
  15. object.Set(key, ArrayToValue(runtime, value))
  16. }
  17. }
  18. return object
  19. }
  20. func ArrayToValue[T any](runtime *goja.Runtime, values []T) goja.Value {
  21. return runtime.NewArray(common.Map(values, func(it T) any { return it })...)
  22. }
  23. func ObjectToHeaders(vm *goja.Runtime, object *goja.Object, name string) http.Header {
  24. headers := make(http.Header)
  25. for _, key := range object.Keys() {
  26. valueObject := object.Get(key)
  27. switch headerValue := valueObject.(type) {
  28. case goja.String:
  29. headers.Set(key, headerValue.String())
  30. case *goja.Object:
  31. values := headerValue.Export()
  32. valueArray, isArray := values.([]any)
  33. if !isArray {
  34. panic(vm.NewTypeError(F.ToString("invalid value: ", name, ".", key, "expected string or string array, got ", valueObject.String())))
  35. }
  36. newValues := make([]string, 0, len(valueArray))
  37. for _, value := range valueArray {
  38. stringValue, isString := value.(string)
  39. if !isString {
  40. panic(vm.NewTypeError(F.ToString("invalid value: ", name, ".", key, " expected string or string array, got array item type: ", reflect.TypeOf(value))))
  41. }
  42. newValues = append(newValues, stringValue)
  43. }
  44. headers[key] = newValues
  45. default:
  46. panic(vm.NewTypeError(F.ToString("invalid value: ", name, ".", key, " expected string or string array, got ", valueObject.String())))
  47. }
  48. }
  49. return headers
  50. }