goscript 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript/cmd_compile_test.go +105 -6
  8. package/compiler/build-flags.go +9 -10
  9. package/compiler/compile-request.go +12 -9
  10. package/compiler/compliance_test.go +0 -1
  11. package/compiler/config.go +2 -0
  12. package/compiler/gotest/request.go +28 -0
  13. package/compiler/gotest/runner.go +353 -27
  14. package/compiler/gotest/runner_test.go +400 -1
  15. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  16. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  17. package/compiler/lowered-program.go +24 -17
  18. package/compiler/lowering.go +988 -263
  19. package/compiler/lowering_bench_test.go +364 -0
  20. package/compiler/override-facts.go +15 -0
  21. package/compiler/override-parity-verifier.go +450 -0
  22. package/compiler/override-parity.go +122 -0
  23. package/compiler/override-registry_test.go +559 -0
  24. package/compiler/package-graph.go +61 -4
  25. package/compiler/package-graph_test.go +30 -0
  26. package/compiler/protobuf-ts-binding.go +514 -0
  27. package/compiler/protobuf-ts-binding_test.go +172 -0
  28. package/compiler/semantic-model-types.go +17 -4
  29. package/compiler/semantic-model.go +709 -72
  30. package/compiler/semantic-model_test.go +219 -0
  31. package/compiler/service.go +20 -1
  32. package/compiler/skeleton_test.go +1008 -20
  33. package/compiler/typescript-emitter.go +147 -15
  34. package/dist/gs/builtin/builtin.d.ts +2 -2
  35. package/dist/gs/builtin/builtin.js +20 -0
  36. package/dist/gs/builtin/builtin.js.map +1 -1
  37. package/dist/gs/builtin/slice.d.ts +2 -1
  38. package/dist/gs/builtin/slice.js +34 -4
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.d.ts +14 -6
  41. package/dist/gs/builtin/type.js +224 -64
  42. package/dist/gs/builtin/type.js.map +1 -1
  43. package/dist/gs/builtin/varRef.d.ts +11 -0
  44. package/dist/gs/builtin/varRef.js +57 -2
  45. package/dist/gs/builtin/varRef.js.map +1 -1
  46. package/dist/gs/bytes/buffer.gs.js +1 -1
  47. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  48. package/dist/gs/bytes/reader.gs.js +1 -1
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/compress/zlib/index.d.ts +13 -6
  51. package/dist/gs/compress/zlib/index.js +131 -35
  52. package/dist/gs/compress/zlib/index.js.map +1 -1
  53. package/dist/gs/crypto/sha1/index.js +2 -5
  54. package/dist/gs/crypto/sha1/index.js.map +1 -1
  55. package/dist/gs/crypto/sha256/index.js +2 -5
  56. package/dist/gs/crypto/sha256/index.js.map +1 -1
  57. package/dist/gs/crypto/sha512/index.js +2 -5
  58. package/dist/gs/crypto/sha512/index.js.map +1 -1
  59. package/dist/gs/embed/index.d.ts +6 -0
  60. package/dist/gs/embed/index.js +210 -5
  61. package/dist/gs/embed/index.js.map +1 -1
  62. package/dist/gs/encoding/json/index.d.ts +114 -0
  63. package/dist/gs/encoding/json/index.js +544 -36
  64. package/dist/gs/encoding/json/index.js.map +1 -1
  65. package/dist/gs/fmt/fmt.d.ts +3 -3
  66. package/dist/gs/fmt/fmt.js +29 -16
  67. package/dist/gs/fmt/fmt.js.map +1 -1
  68. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  69. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  70. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  71. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  72. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  73. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  74. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  75. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  76. package/dist/gs/go/scanner/index.d.ts +2 -0
  77. package/dist/gs/go/scanner/index.js +29 -5
  78. package/dist/gs/go/scanner/index.js.map +1 -1
  79. package/dist/gs/go/token/index.js +22 -6
  80. package/dist/gs/go/token/index.js.map +1 -1
  81. package/dist/gs/hash/index.d.ts +6 -0
  82. package/dist/gs/hash/index.js +20 -0
  83. package/dist/gs/hash/index.js.map +1 -1
  84. package/dist/gs/internal/goarch/index.d.ts +43 -3
  85. package/dist/gs/internal/goarch/index.js +42 -10
  86. package/dist/gs/internal/goarch/index.js.map +1 -1
  87. package/dist/gs/io/fs/fs.js +26 -14
  88. package/dist/gs/io/fs/fs.js.map +1 -1
  89. package/dist/gs/io/fs/readdir.js +8 -4
  90. package/dist/gs/io/fs/readdir.js.map +1 -1
  91. package/dist/gs/io/fs/sub.js +8 -1
  92. package/dist/gs/io/fs/sub.js.map +1 -1
  93. package/dist/gs/io/io.d.ts +12 -6
  94. package/dist/gs/io/io.js +87 -42
  95. package/dist/gs/io/io.js.map +1 -1
  96. package/dist/gs/math/bits/index.d.ts +31 -5
  97. package/dist/gs/math/bits/index.js +29 -28
  98. package/dist/gs/math/bits/index.js.map +1 -1
  99. package/dist/gs/mime/index.d.ts +16 -0
  100. package/dist/gs/mime/index.js +315 -6
  101. package/dist/gs/mime/index.js.map +1 -1
  102. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  103. package/dist/gs/net/http/httptest/index.js +85 -6
  104. package/dist/gs/net/http/httptest/index.js.map +1 -1
  105. package/dist/gs/net/http/index.d.ts +303 -6
  106. package/dist/gs/net/http/index.js +1615 -58
  107. package/dist/gs/net/http/index.js.map +1 -1
  108. package/dist/gs/os/dir_unix.gs.js +1 -1
  109. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  110. package/dist/gs/os/error.gs.js +1 -1
  111. package/dist/gs/os/error.gs.js.map +1 -1
  112. package/dist/gs/os/exec.gs.d.ts +1 -0
  113. package/dist/gs/os/exec.gs.js +4 -8
  114. package/dist/gs/os/exec.gs.js.map +1 -1
  115. package/dist/gs/os/exec_posix.gs.js +1 -1
  116. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  117. package/dist/gs/os/index.d.ts +1 -1
  118. package/dist/gs/os/index.js +1 -1
  119. package/dist/gs/os/index.js.map +1 -1
  120. package/dist/gs/os/proc.gs.d.ts +4 -0
  121. package/dist/gs/os/proc.gs.js +12 -6
  122. package/dist/gs/os/proc.gs.js.map +1 -1
  123. package/dist/gs/os/root_js.gs.js +1 -1
  124. package/dist/gs/os/root_js.gs.js.map +1 -1
  125. package/dist/gs/os/types.gs.js +1 -1
  126. package/dist/gs/os/types.gs.js.map +1 -1
  127. package/dist/gs/os/types_js.gs.d.ts +6 -2
  128. package/dist/gs/os/types_js.gs.js +170 -9
  129. package/dist/gs/os/types_js.gs.js.map +1 -1
  130. package/dist/gs/os/types_unix.gs.js +1 -1
  131. package/dist/gs/os/types_unix.gs.js.map +1 -1
  132. package/dist/gs/path/path.js +11 -7
  133. package/dist/gs/path/path.js.map +1 -1
  134. package/dist/gs/reflect/index.d.ts +5 -4
  135. package/dist/gs/reflect/index.js +4 -3
  136. package/dist/gs/reflect/index.js.map +1 -1
  137. package/dist/gs/reflect/map.js +15 -0
  138. package/dist/gs/reflect/map.js.map +1 -1
  139. package/dist/gs/reflect/type.d.ts +26 -6
  140. package/dist/gs/reflect/type.js +1498 -279
  141. package/dist/gs/reflect/type.js.map +1 -1
  142. package/dist/gs/reflect/types.d.ts +14 -6
  143. package/dist/gs/reflect/types.js +35 -1
  144. package/dist/gs/reflect/types.js.map +1 -1
  145. package/dist/gs/reflect/value.d.ts +1 -0
  146. package/dist/gs/reflect/value.js +83 -41
  147. package/dist/gs/reflect/value.js.map +1 -1
  148. package/dist/gs/reflect/visiblefields.js +4 -140
  149. package/dist/gs/reflect/visiblefields.js.map +1 -1
  150. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  151. package/dist/gs/runtime/pprof/index.js +50 -30
  152. package/dist/gs/runtime/pprof/index.js.map +1 -1
  153. package/dist/gs/runtime/runtime.js +5 -4
  154. package/dist/gs/runtime/runtime.js.map +1 -1
  155. package/dist/gs/runtime/trace/index.js +5 -19
  156. package/dist/gs/runtime/trace/index.js.map +1 -1
  157. package/dist/gs/strconv/atoi.gs.js +1 -1
  158. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  159. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  160. package/dist/gs/strconv/complex.gs.js +148 -0
  161. package/dist/gs/strconv/complex.gs.js.map +1 -0
  162. package/dist/gs/strconv/index.d.ts +1 -0
  163. package/dist/gs/strconv/index.js +1 -0
  164. package/dist/gs/strconv/index.js.map +1 -1
  165. package/dist/gs/strings/builder.js +1 -1
  166. package/dist/gs/strings/reader.d.ts +1 -1
  167. package/dist/gs/strings/reader.js +11 -7
  168. package/dist/gs/strings/reader.js.map +1 -1
  169. package/dist/gs/strings/replace.js +15 -7
  170. package/dist/gs/strings/replace.js.map +1 -1
  171. package/dist/gs/strings/strings.d.ts +5 -0
  172. package/dist/gs/strings/strings.js +57 -5
  173. package/dist/gs/strings/strings.js.map +1 -1
  174. package/dist/gs/sync/atomic/type.gs.js +9 -9
  175. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  176. package/dist/gs/sync/atomic/value.gs.js +2 -2
  177. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  178. package/dist/gs/sync/sync.d.ts +2 -1
  179. package/dist/gs/sync/sync.js +37 -16
  180. package/dist/gs/sync/sync.js.map +1 -1
  181. package/dist/gs/syscall/env.js +22 -14
  182. package/dist/gs/syscall/env.js.map +1 -1
  183. package/dist/gs/syscall/js/index.js +9 -0
  184. package/dist/gs/syscall/js/index.js.map +1 -1
  185. package/dist/gs/testing/testing.js +59 -15
  186. package/dist/gs/testing/testing.js.map +1 -1
  187. package/dist/gs/time/time.d.ts +24 -1
  188. package/dist/gs/time/time.js +43 -3
  189. package/dist/gs/time/time.js.map +1 -1
  190. package/dist/gs/unique/index.js +7 -1
  191. package/dist/gs/unique/index.js.map +1 -1
  192. package/go.mod +3 -3
  193. package/go.sum +16 -0
  194. package/gs/builtin/builtin.ts +25 -2
  195. package/gs/builtin/runtime-contract.test.ts +260 -18
  196. package/gs/builtin/slice.ts +51 -4
  197. package/gs/builtin/type.ts +310 -63
  198. package/gs/builtin/varRef.ts +85 -2
  199. package/gs/bytes/buffer.gs.ts +1 -1
  200. package/gs/bytes/reader.gs.ts +1 -1
  201. package/gs/compress/zlib/index.test.ts +159 -1
  202. package/gs/compress/zlib/index.ts +164 -37
  203. package/gs/compress/zlib/meta.json +4 -1
  204. package/gs/compress/zlib/parity.json +51 -0
  205. package/gs/crypto/sha1/index.test.ts +19 -2
  206. package/gs/crypto/sha1/index.ts +3 -6
  207. package/gs/crypto/sha256/index.test.ts +14 -2
  208. package/gs/crypto/sha256/index.ts +3 -6
  209. package/gs/crypto/sha512/index.test.ts +17 -2
  210. package/gs/crypto/sha512/index.ts +3 -6
  211. package/gs/embed/index.test.ts +87 -0
  212. package/gs/embed/index.ts +229 -5
  213. package/gs/encoding/json/index.test.ts +360 -6
  214. package/gs/encoding/json/index.ts +679 -38
  215. package/gs/encoding/json/parity.json +81 -0
  216. package/gs/fmt/fmt.test.ts +41 -3
  217. package/gs/fmt/fmt.ts +40 -17
  218. package/gs/fmt/meta.json +6 -1
  219. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  220. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  221. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  222. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  223. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  224. package/gs/github.com/pkg/errors/errors.ts +54 -30
  225. package/gs/go/scanner/index.test.ts +39 -56
  226. package/gs/go/scanner/index.ts +33 -5
  227. package/gs/go/scanner/parity.json +27 -0
  228. package/gs/go/token/index.ts +22 -6
  229. package/gs/hash/index.test.ts +20 -33
  230. package/gs/hash/index.ts +28 -0
  231. package/gs/hash/parity.json +21 -0
  232. package/gs/internal/goarch/index.test.ts +32 -0
  233. package/gs/internal/goarch/index.ts +45 -13
  234. package/gs/internal/goarch/parity.json +144 -0
  235. package/gs/io/fs/fs.ts +26 -14
  236. package/gs/io/fs/readdir.test.ts +38 -0
  237. package/gs/io/fs/readdir.ts +8 -4
  238. package/gs/io/fs/sub.ts +8 -1
  239. package/gs/io/io.test.ts +77 -6
  240. package/gs/io/io.ts +115 -52
  241. package/gs/io/meta.json +7 -1
  242. package/gs/io/parity.json +162 -0
  243. package/gs/math/bits/index.test.ts +14 -1
  244. package/gs/math/bits/index.ts +75 -32
  245. package/gs/math/bits/parity.json +156 -0
  246. package/gs/mime/index.test.ts +90 -0
  247. package/gs/mime/index.ts +369 -6
  248. package/gs/mime/parity.json +36 -0
  249. package/gs/net/http/httptest/index.test.ts +98 -2
  250. package/gs/net/http/httptest/index.ts +101 -6
  251. package/gs/net/http/httptest/parity.json +15 -0
  252. package/gs/net/http/index.test.ts +797 -12
  253. package/gs/net/http/index.ts +1874 -136
  254. package/gs/net/http/meta.json +16 -1
  255. package/gs/net/http/parity.json +193 -0
  256. package/gs/os/dir_unix.gs.ts +1 -1
  257. package/gs/os/error.gs.ts +1 -1
  258. package/gs/os/exec.gs.ts +4 -8
  259. package/gs/os/exec_posix.gs.ts +1 -1
  260. package/gs/os/file_unix_js.test.ts +52 -0
  261. package/gs/os/index.test.ts +9 -0
  262. package/gs/os/index.ts +1 -0
  263. package/gs/os/meta.json +4 -0
  264. package/gs/os/parity.json +9 -0
  265. package/gs/os/proc.gs.ts +18 -5
  266. package/gs/os/proc.test.ts +26 -0
  267. package/gs/os/readdir.test.ts +56 -0
  268. package/gs/os/root_js.gs.ts +1 -1
  269. package/gs/os/types.gs.ts +1 -1
  270. package/gs/os/types_js.gs.ts +170 -9
  271. package/gs/os/types_unix.gs.ts +1 -1
  272. package/gs/path/path.ts +11 -7
  273. package/gs/reflect/deepequal.test.ts +10 -1
  274. package/gs/reflect/field.test.ts +37 -15
  275. package/gs/reflect/function-types.test.ts +518 -22
  276. package/gs/reflect/index.ts +8 -6
  277. package/gs/reflect/map.ts +20 -0
  278. package/gs/reflect/meta.json +6 -4
  279. package/gs/reflect/parity.json +234 -0
  280. package/gs/reflect/sliceat.test.ts +156 -0
  281. package/gs/reflect/structof.test.ts +401 -0
  282. package/gs/reflect/type.ts +1980 -365
  283. package/gs/reflect/typefor.test.ts +540 -10
  284. package/gs/reflect/types.ts +43 -18
  285. package/gs/reflect/value.ts +105 -45
  286. package/gs/reflect/visiblefields.ts +5 -168
  287. package/gs/runtime/parity.json +24 -0
  288. package/gs/runtime/pprof/index.test.ts +29 -7
  289. package/gs/runtime/pprof/index.ts +56 -30
  290. package/gs/runtime/pprof/parity.json +27 -0
  291. package/gs/runtime/runtime.test.ts +3 -1
  292. package/gs/runtime/runtime.ts +4 -3
  293. package/gs/runtime/trace/index.test.ts +5 -3
  294. package/gs/runtime/trace/index.ts +8 -20
  295. package/gs/runtime/trace/parity.json +36 -0
  296. package/gs/strconv/atoi.gs.ts +1 -1
  297. package/gs/strconv/complex.gs.ts +174 -0
  298. package/gs/strconv/complex.test.ts +65 -0
  299. package/gs/strconv/index.ts +1 -0
  300. package/gs/strconv/parity.json +120 -0
  301. package/gs/strings/builder.ts +1 -1
  302. package/gs/strings/meta.json +5 -2
  303. package/gs/strings/parity.json +186 -0
  304. package/gs/strings/reader.test.ts +2 -2
  305. package/gs/strings/reader.ts +11 -7
  306. package/gs/strings/replace.ts +15 -7
  307. package/gs/strings/strings.test.ts +22 -2
  308. package/gs/strings/strings.ts +64 -6
  309. package/gs/sync/atomic/type.gs.ts +9 -9
  310. package/gs/sync/atomic/value.gs.ts +2 -2
  311. package/gs/sync/meta.json +1 -0
  312. package/gs/sync/sync.test.ts +41 -1
  313. package/gs/sync/sync.ts +41 -16
  314. package/gs/syscall/env.ts +29 -14
  315. package/gs/syscall/js/index.test.ts +18 -0
  316. package/gs/syscall/js/index.ts +12 -0
  317. package/gs/testing/testing.test.ts +99 -3
  318. package/gs/testing/testing.ts +95 -24
  319. package/gs/time/parity.json +225 -0
  320. package/gs/time/time.test.ts +20 -2
  321. package/gs/time/time.ts +49 -7
  322. package/gs/unique/index.ts +7 -1
  323. package/package.json +4 -2
  324. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  325. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
  326. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  327. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
  328. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
  329. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  330. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -2,68 +2,214 @@ import * as $ from '@goscript/builtin/index.js';
2
2
  import * as bytes from '@goscript/bytes/index.js';
3
3
  import * as context from '@goscript/context/index.js';
4
4
  import * as errors from '@goscript/errors/index.js';
5
+ import * as fs from '@goscript/io/fs/fs.js';
6
+ import * as io from '@goscript/io/index.js';
7
+ import * as strings from '@goscript/strings/index.js';
5
8
  import * as time from '@goscript/time/index.js';
9
+ export const StatusContinue = 100;
10
+ export const StatusSwitchingProtocols = 101;
11
+ export const StatusProcessing = 102;
12
+ export const StatusEarlyHints = 103;
6
13
  export const StatusOK = 200;
7
14
  export const StatusCreated = 201;
15
+ export const StatusAccepted = 202;
16
+ export const StatusNonAuthoritativeInfo = 203;
17
+ export const StatusNoContent = 204;
18
+ export const StatusResetContent = 205;
8
19
  export const StatusPartialContent = 206;
20
+ export const StatusMultiStatus = 207;
21
+ export const StatusAlreadyReported = 208;
22
+ export const StatusIMUsed = 226;
23
+ export const StatusMultipleChoices = 300;
9
24
  export const StatusMovedPermanently = 301;
25
+ export const StatusFound = 302;
26
+ export const StatusSeeOther = 303;
27
+ export const StatusNotModified = 304;
28
+ export const StatusUseProxy = 305;
29
+ export const StatusTemporaryRedirect = 307;
30
+ export const StatusPermanentRedirect = 308;
10
31
  export const StatusBadRequest = 400;
11
32
  export const StatusUnauthorized = 401;
33
+ export const StatusPaymentRequired = 402;
12
34
  export const StatusForbidden = 403;
35
+ export const StatusNotFound = 404;
13
36
  export const StatusMethodNotAllowed = 405;
37
+ export const StatusNotAcceptable = 406;
38
+ export const StatusProxyAuthRequired = 407;
14
39
  export const StatusRequestTimeout = 408;
15
40
  export const StatusConflict = 409;
16
- export const StatusNotFound = 404;
41
+ export const StatusGone = 410;
42
+ export const StatusLengthRequired = 411;
43
+ export const StatusPreconditionFailed = 412;
44
+ export const StatusRequestEntityTooLarge = 413;
45
+ export const StatusRequestURITooLong = 414;
17
46
  export const StatusUnsupportedMediaType = 415;
47
+ export const StatusRequestedRangeNotSatisfiable = 416;
48
+ export const StatusExpectationFailed = 417;
18
49
  export const StatusTeapot = 418;
50
+ export const StatusMisdirectedRequest = 421;
51
+ export const StatusUnprocessableEntity = 422;
52
+ export const StatusLocked = 423;
53
+ export const StatusFailedDependency = 424;
54
+ export const StatusTooEarly = 425;
55
+ export const StatusUpgradeRequired = 426;
56
+ export const StatusPreconditionRequired = 428;
19
57
  export const StatusTooManyRequests = 429;
20
- export const StatusRequestedRangeNotSatisfiable = 416;
58
+ export const StatusRequestHeaderFieldsTooLarge = 431;
59
+ export const StatusUnavailableForLegalReasons = 451;
21
60
  export const StatusInternalServerError = 500;
61
+ export const StatusNotImplemented = 501;
62
+ export const StatusBadGateway = 502;
22
63
  export const StatusServiceUnavailable = 503;
64
+ export const StatusGatewayTimeout = 504;
65
+ export const StatusHTTPVersionNotSupported = 505;
66
+ export const StatusVariantAlsoNegotiates = 506;
67
+ export const StatusInsufficientStorage = 507;
68
+ export const StatusLoopDetected = 508;
69
+ export const StatusNotExtended = 510;
70
+ export const StatusNetworkAuthenticationRequired = 511;
23
71
  export const MethodGet = 'GET';
72
+ export const MethodHead = 'HEAD';
24
73
  export const MethodPost = 'POST';
74
+ export const MethodPut = 'PUT';
75
+ export const MethodPatch = 'PATCH';
25
76
  export const MethodDelete = 'DELETE';
26
- export const ErrNotSupported = errors.New('feature not supported');
77
+ export const MethodConnect = 'CONNECT';
78
+ export const MethodOptions = 'OPTIONS';
79
+ export const MethodTrace = 'TRACE';
80
+ export const DefaultMaxHeaderBytes = 1 << 20;
81
+ export const DefaultMaxIdleConnsPerHost = 2;
82
+ export const TimeFormat = 'Mon, 02 Jan 2006 15:04:05 GMT';
83
+ export const TrailerPrefix = 'Trailer:';
84
+ export class ProtocolError {
85
+ ErrorString;
86
+ constructor(errorString) {
87
+ this.ErrorString = errorString;
88
+ }
89
+ Error() {
90
+ return this.ErrorString;
91
+ }
92
+ }
93
+ export class MaxBytesError {
94
+ Limit;
95
+ constructor(init) {
96
+ this.Limit = init?.Limit ?? 0;
97
+ }
98
+ Error() {
99
+ return 'http: request body too large';
100
+ }
101
+ }
102
+ export const ErrNotSupported = new ProtocolError('feature not supported');
103
+ export const ErrUnexpectedTrailer = new ProtocolError('trailer header without chunked transfer encoding');
104
+ export const ErrMissingBoundary = new ProtocolError('no multipart boundary param in Content-Type');
105
+ export const ErrNotMultipart = new ProtocolError("request Content-Type isn't multipart/form-data");
106
+ export const ErrHeaderTooLong = new ProtocolError('header too long');
107
+ export const ErrShortBody = new ProtocolError('entity body too short');
108
+ export const ErrMissingContentLength = new ProtocolError('missing ContentLength in HEAD response');
109
+ export const ErrBodyNotAllowed = errors.New('http: request method or response status code does not allow body');
110
+ export const ErrBodyReadAfterClose = errors.New('http: invalid Read on closed Body');
111
+ export const ErrContentLength = errors.New('http: wrote more than the declared Content-Length');
112
+ export const ErrHandlerTimeout = errors.New('http: Handler timeout');
113
+ export const ErrHijacked = errors.New('http: connection has been hijacked');
114
+ export const ErrLineTooLong = errors.New('header line too long');
115
+ export const ErrMissingFile = errors.New('http: no such file');
116
+ export const ErrNoCookie = errors.New('http: named cookie not present');
117
+ export const ErrNoLocation = errors.New('http: no Location header in response');
118
+ export const ErrSchemeMismatch = errors.New('http: server gave HTTP response to HTTPS client');
119
+ export const ErrServerClosed = errors.New('http: Server closed');
120
+ export const ErrAbortHandler = errors.New('net/http: abort Handler');
121
+ export const ErrSkipAltProtocol = errors.New('net/http: skip alternate protocol');
122
+ export const ErrUseLastResponse = errors.New('net/http: use last response');
123
+ export const ErrWriteAfterFlush = errors.New('unused');
124
+ const errBlankCookie = errors.New('http: blank cookie');
125
+ const errEqualNotFoundInCookie = errors.New("http: '=' not found in cookie");
126
+ const errInvalidCookieName = errors.New('http: invalid cookie name');
127
+ const errInvalidCookieValue = errors.New('http: invalid cookie value');
128
+ const errCookieNumLimitExceeded = errors.New('http: number of cookies exceeded limit');
129
+ const errCrossOriginRequest = errors.New('cross-origin request detected from Sec-Fetch-Site header');
130
+ const errCrossOriginRequestFromOldBrowser = errors.New('cross-origin request detected, and/or browser is out of date: Sec-Fetch-Site is missing, and Origin does not match Host');
27
131
  export const ServerContextKey = Symbol('net/http ServerContextKey');
132
+ export const LocalAddrContextKey = Symbol('net/http LocalAddrContextKey');
133
+ export const SameSiteDefaultMode = 1;
134
+ export const SameSiteLaxMode = 2;
135
+ export const SameSiteStrictMode = 3;
136
+ export const SameSiteNoneMode = 4;
137
+ export const StateNew = 0;
138
+ export const StateActive = 1;
139
+ export const StateIdle = 2;
140
+ export const StateHijacked = 3;
141
+ export const StateClosed = 4;
142
+ const statusTexts = new Map([
143
+ [StatusContinue, 'Continue'],
144
+ [StatusSwitchingProtocols, 'Switching Protocols'],
145
+ [StatusProcessing, 'Processing'],
146
+ [StatusEarlyHints, 'Early Hints'],
147
+ [StatusOK, 'OK'],
148
+ [StatusCreated, 'Created'],
149
+ [StatusAccepted, 'Accepted'],
150
+ [StatusNonAuthoritativeInfo, 'Non-Authoritative Information'],
151
+ [StatusNoContent, 'No Content'],
152
+ [StatusResetContent, 'Reset Content'],
153
+ [StatusPartialContent, 'Partial Content'],
154
+ [StatusMultiStatus, 'Multi-Status'],
155
+ [StatusAlreadyReported, 'Already Reported'],
156
+ [StatusIMUsed, 'IM Used'],
157
+ [StatusMultipleChoices, 'Multiple Choices'],
158
+ [StatusMovedPermanently, 'Moved Permanently'],
159
+ [StatusFound, 'Found'],
160
+ [StatusSeeOther, 'See Other'],
161
+ [StatusNotModified, 'Not Modified'],
162
+ [StatusUseProxy, 'Use Proxy'],
163
+ [StatusTemporaryRedirect, 'Temporary Redirect'],
164
+ [StatusPermanentRedirect, 'Permanent Redirect'],
165
+ [StatusBadRequest, 'Bad Request'],
166
+ [StatusUnauthorized, 'Unauthorized'],
167
+ [StatusPaymentRequired, 'Payment Required'],
168
+ [StatusForbidden, 'Forbidden'],
169
+ [StatusNotFound, 'Not Found'],
170
+ [StatusMethodNotAllowed, 'Method Not Allowed'],
171
+ [StatusNotAcceptable, 'Not Acceptable'],
172
+ [StatusProxyAuthRequired, 'Proxy Authentication Required'],
173
+ [StatusRequestTimeout, 'Request Timeout'],
174
+ [StatusConflict, 'Conflict'],
175
+ [StatusGone, 'Gone'],
176
+ [StatusLengthRequired, 'Length Required'],
177
+ [StatusPreconditionFailed, 'Precondition Failed'],
178
+ [StatusRequestEntityTooLarge, 'Request Entity Too Large'],
179
+ [StatusRequestURITooLong, 'Request URI Too Long'],
180
+ [StatusUnsupportedMediaType, 'Unsupported Media Type'],
181
+ [StatusRequestedRangeNotSatisfiable, 'Requested Range Not Satisfiable'],
182
+ [StatusExpectationFailed, 'Expectation Failed'],
183
+ [StatusTeapot, "I'm a teapot"],
184
+ [StatusMisdirectedRequest, 'Misdirected Request'],
185
+ [StatusUnprocessableEntity, 'Unprocessable Entity'],
186
+ [StatusLocked, 'Locked'],
187
+ [StatusFailedDependency, 'Failed Dependency'],
188
+ [StatusTooEarly, 'Too Early'],
189
+ [StatusUpgradeRequired, 'Upgrade Required'],
190
+ [StatusPreconditionRequired, 'Precondition Required'],
191
+ [StatusTooManyRequests, 'Too Many Requests'],
192
+ [StatusRequestHeaderFieldsTooLarge, 'Request Header Fields Too Large'],
193
+ [StatusUnavailableForLegalReasons, 'Unavailable For Legal Reasons'],
194
+ [StatusInternalServerError, 'Internal Server Error'],
195
+ [StatusNotImplemented, 'Not Implemented'],
196
+ [StatusBadGateway, 'Bad Gateway'],
197
+ [StatusServiceUnavailable, 'Service Unavailable'],
198
+ [StatusGatewayTimeout, 'Gateway Timeout'],
199
+ [StatusHTTPVersionNotSupported, 'HTTP Version Not Supported'],
200
+ [StatusVariantAlsoNegotiates, 'Variant Also Negotiates'],
201
+ [StatusInsufficientStorage, 'Insufficient Storage'],
202
+ [StatusLoopDetected, 'Loop Detected'],
203
+ [StatusNotExtended, 'Not Extended'],
204
+ [StatusNetworkAuthenticationRequired, 'Network Authentication Required'],
205
+ ]);
28
206
  export function StatusText(code) {
29
- switch (code) {
30
- case StatusOK:
31
- return 'OK';
32
- case StatusMovedPermanently:
33
- return 'Moved Permanently';
34
- case StatusUnauthorized:
35
- return 'Unauthorized';
36
- case StatusForbidden:
37
- return 'Forbidden';
38
- case StatusMethodNotAllowed:
39
- return 'Method Not Allowed';
40
- case StatusBadRequest:
41
- return 'Bad Request';
42
- case StatusRequestTimeout:
43
- return 'Request Timeout';
44
- case StatusConflict:
45
- return 'Conflict';
46
- case StatusNotFound:
47
- return 'Not Found';
48
- case StatusUnsupportedMediaType:
49
- return 'Unsupported Media Type';
50
- case StatusTooManyRequests:
51
- return 'Too Many Requests';
52
- case StatusPartialContent:
53
- return 'Partial Content';
54
- case StatusRequestedRangeNotSatisfiable:
55
- return 'Requested Range Not Satisfiable';
56
- case StatusTeapot:
57
- return "I'm a teapot";
58
- case StatusInternalServerError:
59
- return 'Internal Server Error';
60
- case StatusServiceUnavailable:
61
- return 'Service Unavailable';
62
- default:
63
- return '';
64
- }
207
+ return statusTexts.get(code) ?? '';
65
208
  }
66
209
  export const Header = Map;
210
+ export function CanonicalHeaderKey(s) {
211
+ return canonicalMIMEHeaderKey(s);
212
+ }
67
213
  export function Header_Add(h, key, value) {
68
214
  key = canonicalMIMEHeaderKey(key);
69
215
  const values = Array.from(h.get(key) ?? []);
@@ -80,6 +226,33 @@ export function Header_Get(h, key) {
80
226
  export function Header_Set(h, key, value) {
81
227
  h.set(canonicalMIMEHeaderKey(key), $.arrayToSlice([value]));
82
228
  }
229
+ export function Header_Values(h, key) {
230
+ return h.get(canonicalMIMEHeaderKey(key)) ?? null;
231
+ }
232
+ export function Header_Clone(h) {
233
+ const cloned = new Header();
234
+ for (const [key, values] of h.entries()) {
235
+ cloned.set(key, $.arrayToSlice(Array.from(values ?? [])));
236
+ }
237
+ return cloned;
238
+ }
239
+ export function Header_Write(h, w) {
240
+ return Header_WriteSubset(h, w, null);
241
+ }
242
+ export function Header_WriteSubset(h, w, exclude) {
243
+ for (const [key, values] of h.entries()) {
244
+ if (exclude?.get(key) === true) {
245
+ continue;
246
+ }
247
+ for (const value of Array.from(values ?? [])) {
248
+ const [, err] = w.Write($.stringToBytes(`${key}: ${value}\r\n`));
249
+ if (err != null) {
250
+ return err;
251
+ }
252
+ }
253
+ }
254
+ return null;
255
+ }
83
256
  function canonicalMIMEHeaderKey(key) {
84
257
  let upper = true;
85
258
  let out = '';
@@ -146,12 +319,15 @@ class RequestURL {
146
319
  }
147
320
  function parseRequestURL(rawURL) {
148
321
  try {
322
+ if (/%(?![0-9A-Fa-f]{2})/.test(rawURL)) {
323
+ return [null, errors.New(`parse "${rawURL}": invalid URL escape`)];
324
+ }
149
325
  const parsed = new URL(rawURL, 'http://goscript.invalid');
150
326
  const hasHost = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(rawURL);
151
- return new RequestURL(parsed.pathname, parsed.search.startsWith('?') ? parsed.search.slice(1) : parsed.search, hasHost ? parsed.protocol.replace(/:$/, '') : '', hasHost ? parsed.host : '');
327
+ return [new RequestURL(parsed.pathname, parsed.search.startsWith('?') ? parsed.search.slice(1) : parsed.search, hasHost ? parsed.protocol.replace(/:$/, '') : '', hasHost ? parsed.host : ''), null];
152
328
  }
153
329
  catch {
154
- return new RequestURL('', '');
330
+ return [null, errors.New(`parse "${rawURL}": invalid URL`)];
155
331
  }
156
332
  }
157
333
  class responseBody {
@@ -166,6 +342,124 @@ class responseBody {
166
342
  return null;
167
343
  }
168
344
  }
345
+ class noBody {
346
+ Read(_p) {
347
+ return [0, io.EOF];
348
+ }
349
+ Close() {
350
+ return null;
351
+ }
352
+ clone() {
353
+ return this;
354
+ }
355
+ }
356
+ export const NoBody = new noBody();
357
+ export class Cookie {
358
+ Name;
359
+ Value;
360
+ Quoted;
361
+ Path;
362
+ Domain;
363
+ Expires;
364
+ RawExpires;
365
+ MaxAge;
366
+ Secure;
367
+ HttpOnly;
368
+ SameSite;
369
+ Partitioned;
370
+ Raw;
371
+ Unparsed;
372
+ constructor(init) {
373
+ this.Name = init?.Name ?? '';
374
+ this.Value = init?.Value ?? '';
375
+ this.Quoted = init?.Quoted ?? false;
376
+ this.Path = init?.Path ?? '';
377
+ this.Domain = init?.Domain ?? '';
378
+ this.Expires = init?.Expires ?? new time.Time();
379
+ this.RawExpires = init?.RawExpires ?? '';
380
+ this.MaxAge = init?.MaxAge ?? 0;
381
+ this.Secure = init?.Secure ?? false;
382
+ this.HttpOnly = init?.HttpOnly ?? false;
383
+ this.SameSite = init?.SameSite ?? 0;
384
+ this.Partitioned = init?.Partitioned ?? false;
385
+ this.Raw = init?.Raw ?? '';
386
+ this.Unparsed = init?.Unparsed ?? null;
387
+ }
388
+ String() {
389
+ const parts = [`${this.Name}=${this.Quoted ? quoteCookieValue(this.Value) : this.Value}`];
390
+ if (this.Path !== '') {
391
+ parts.push(`Path=${this.Path}`);
392
+ }
393
+ if (this.Domain !== '') {
394
+ parts.push(`Domain=${this.Domain}`);
395
+ }
396
+ if (this.MaxAge > 0) {
397
+ parts.push(`Max-Age=${this.MaxAge}`);
398
+ }
399
+ else if (this.MaxAge < 0) {
400
+ parts.push('Max-Age=0');
401
+ }
402
+ if (this.HttpOnly) {
403
+ parts.push('HttpOnly');
404
+ }
405
+ if (this.Secure) {
406
+ parts.push('Secure');
407
+ }
408
+ switch (this.SameSite) {
409
+ case SameSiteLaxMode:
410
+ parts.push('SameSite=Lax');
411
+ break;
412
+ case SameSiteStrictMode:
413
+ parts.push('SameSite=Strict');
414
+ break;
415
+ case SameSiteNoneMode:
416
+ parts.push('SameSite=None');
417
+ break;
418
+ }
419
+ if (this.Partitioned) {
420
+ parts.push('Partitioned');
421
+ }
422
+ return parts.join('; ');
423
+ }
424
+ }
425
+ function quoteCookieValue(value) {
426
+ return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
427
+ }
428
+ function isToken(value) {
429
+ return /^[!#$%&'*+\-.^_`{}|~0-9A-Za-z]+$/.test(value);
430
+ }
431
+ function validCookieValueByte(code) {
432
+ return code >= 0x20 && code < 0x7f && code !== 0x22 && code !== 0x3b && code !== 0x5c;
433
+ }
434
+ function parseCookieValue(raw, allowDoubleQuote) {
435
+ let value = raw;
436
+ let quoted = false;
437
+ if (allowDoubleQuote && value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
438
+ value = value.slice(1, -1);
439
+ quoted = true;
440
+ }
441
+ for (let i = 0; i < value.length; i++) {
442
+ if (!validCookieValueByte(value.charCodeAt(i))) {
443
+ return ['', quoted, false];
444
+ }
445
+ }
446
+ return [value, quoted, true];
447
+ }
448
+ function asciiLower(value) {
449
+ for (let i = 0; i < value.length; i++) {
450
+ if (value.charCodeAt(i) > 0x7f) {
451
+ return ['', false];
452
+ }
453
+ }
454
+ return [value.toLowerCase(), true];
455
+ }
456
+ export function SetCookie(w, cookie) {
457
+ const c = $.pointerValue(cookie);
458
+ if (w == null || c == null) {
459
+ return;
460
+ }
461
+ Header_Add(w.Header(), 'Set-Cookie', c.String());
462
+ }
169
463
  class memoryResponseWriter {
170
464
  Code = StatusOK;
171
465
  Body = new bytes.Buffer();
@@ -203,28 +497,69 @@ export function RegisterInProcessServer(handler) {
203
497
  return `http://${host}`;
204
498
  }
205
499
  export function UnregisterInProcessServer(rawURL) {
206
- const parsed = parseRequestURL(rawURL);
207
- if (parsed.Host !== '') {
500
+ const [parsed] = parseRequestURL(rawURL);
501
+ if (parsed != null && parsed.Host !== '') {
208
502
  inProcessServers.delete(parsed.Host);
209
503
  }
210
504
  }
505
+ function inProcessServerRequest(request) {
506
+ const req = Object.assign(Object.create(Object.getPrototypeOf(request)), request);
507
+ const rawQuery = request.URL?.RawQuery ?? '';
508
+ const query = rawQuery === '' ? '' : `?${rawQuery}`;
509
+ req.RequestURI = `${request.URL?.Path ?? '/'}${query}`;
510
+ req.Host = request.Host === '' ? request.URL?.Host ?? '' : request.Host;
511
+ if (req.URL?.clone != null) {
512
+ req.URL = req.URL.clone();
513
+ req.URL.Scheme = '';
514
+ req.URL.Host = '';
515
+ }
516
+ return req;
517
+ }
211
518
  export class Request {
212
519
  Method;
213
520
  URL;
521
+ Proto;
522
+ ProtoMajor;
523
+ ProtoMinor;
214
524
  Body;
215
525
  Header;
216
526
  ContentLength;
527
+ TransferEncoding;
528
+ Close;
529
+ Host;
530
+ Form;
531
+ PostForm;
532
+ MultipartForm;
533
+ Trailer;
217
534
  RequestURI;
218
535
  RemoteAddr;
536
+ TLS;
537
+ Cancel;
538
+ Response;
539
+ Pattern;
219
540
  ctx;
220
541
  constructor(init) {
221
542
  this.Method = init?.Method ?? '';
222
543
  this.URL = init?.URL ?? null;
544
+ this.Proto = init?.Proto ?? 'HTTP/1.1';
545
+ this.ProtoMajor = init?.ProtoMajor ?? 1;
546
+ this.ProtoMinor = init?.ProtoMinor ?? 1;
223
547
  this.Body = init?.Body ?? null;
224
548
  this.Header = init?.Header ?? new Header();
225
549
  this.ContentLength = init?.ContentLength ?? 0;
550
+ this.TransferEncoding = init?.TransferEncoding ?? null;
551
+ this.Close = init?.Close ?? false;
552
+ this.Host = init?.Host ?? '';
553
+ this.Form = init?.Form ?? null;
554
+ this.PostForm = init?.PostForm ?? null;
555
+ this.MultipartForm = init?.MultipartForm ?? null;
556
+ this.Trailer = init?.Trailer ?? new Header();
226
557
  this.RequestURI = init?.RequestURI ?? '';
227
558
  this.RemoteAddr = init?.RemoteAddr ?? '';
559
+ this.TLS = init?.TLS ?? null;
560
+ this.Cancel = init?.Cancel ?? null;
561
+ this.Response = init?.Response ?? null;
562
+ this.Pattern = init?.Pattern ?? '';
228
563
  this.ctx = init?.ctx ?? context.Background();
229
564
  }
230
565
  Context() {
@@ -237,17 +572,75 @@ export class Request {
237
572
  return new Request({
238
573
  Method: this.Method,
239
574
  URL: this.URL?.clone != null ? this.URL.clone() : this.URL == null ? null : { ...this.URL },
575
+ Proto: this.Proto,
576
+ ProtoMajor: this.ProtoMajor,
577
+ ProtoMinor: this.ProtoMinor,
240
578
  Body: this.Body,
241
- Header: this.Header,
579
+ Header: Header_Clone(this.Header),
242
580
  ContentLength: this.ContentLength,
581
+ TransferEncoding: this.TransferEncoding,
582
+ Close: this.Close,
583
+ Host: this.Host,
584
+ Form: this.Form,
585
+ PostForm: this.PostForm,
586
+ MultipartForm: this.MultipartForm,
587
+ Trailer: Header_Clone(this.Trailer),
243
588
  RequestURI: this.RequestURI,
244
589
  RemoteAddr: this.RemoteAddr,
590
+ TLS: this.TLS,
591
+ Cancel: this.Cancel,
592
+ Response: this.Response,
593
+ Pattern: this.Pattern,
245
594
  ctx,
246
595
  });
247
596
  }
248
597
  UserAgent() {
249
598
  return Header_Get(this.Header, 'User-Agent');
250
599
  }
600
+ Referer() {
601
+ return Header_Get(this.Header, 'Referer');
602
+ }
603
+ ProtoAtLeast(major, minor) {
604
+ return this.ProtoMajor > major || (this.ProtoMajor === major && this.ProtoMinor >= minor);
605
+ }
606
+ Cookie(name) {
607
+ for (const cookie of Array.from(this.Cookies() ?? [])) {
608
+ if (cookie?.Name === name) {
609
+ return [cookie, null];
610
+ }
611
+ }
612
+ return [null, ErrNoCookie];
613
+ }
614
+ Cookies() {
615
+ const raw = Header_Get(this.Header, 'Cookie');
616
+ if (raw === '') {
617
+ return null;
618
+ }
619
+ const [cookies] = ParseCookie(raw);
620
+ return cookies;
621
+ }
622
+ AddCookie(cookie) {
623
+ const c = $.pointerValue(cookie);
624
+ if (c != null) {
625
+ Header_Add(this.Header, 'Cookie', c.String());
626
+ }
627
+ }
628
+ SetBasicAuth(username, password) {
629
+ const encoded = globalThis.btoa(`${username}:${password}`);
630
+ Header_Set(this.Header, 'Authorization', `Basic ${encoded}`);
631
+ }
632
+ BasicAuth() {
633
+ const value = Header_Get(this.Header, 'Authorization');
634
+ if (!value.startsWith('Basic ')) {
635
+ return ['', '', false];
636
+ }
637
+ const decoded = globalThis.atob(value.slice('Basic '.length));
638
+ const idx = decoded.indexOf(':');
639
+ if (idx < 0) {
640
+ return ['', '', false];
641
+ }
642
+ return [decoded.slice(0, idx), decoded.slice(idx + 1), true];
643
+ }
251
644
  FormValue(key) {
252
645
  const query = this.URL?.Query;
253
646
  return typeof query === 'function' ? query.call(this.URL).Get(key) : '';
@@ -256,13 +649,33 @@ export class Request {
256
649
  export class Response {
257
650
  Status;
258
651
  StatusCode;
652
+ Proto;
653
+ ProtoMajor;
654
+ ProtoMinor;
259
655
  Body;
260
656
  Header;
657
+ ContentLength;
658
+ TransferEncoding;
659
+ Close;
660
+ Uncompressed;
661
+ Trailer;
662
+ Request;
663
+ TLS;
261
664
  constructor(init) {
262
665
  this.Status = init?.Status ?? '';
263
666
  this.StatusCode = init?.StatusCode ?? 0;
667
+ this.Proto = init?.Proto ?? 'HTTP/1.1';
668
+ this.ProtoMajor = init?.ProtoMajor ?? 1;
669
+ this.ProtoMinor = init?.ProtoMinor ?? 1;
264
670
  this.Body = init?.Body ?? null;
265
671
  this.Header = init?.Header ?? new Header();
672
+ this.ContentLength = init?.ContentLength ?? 0;
673
+ this.TransferEncoding = init?.TransferEncoding ?? null;
674
+ this.Close = init?.Close ?? false;
675
+ this.Uncompressed = init?.Uncompressed ?? false;
676
+ this.Trailer = init?.Trailer ?? new Header();
677
+ this.Request = init?.Request ?? null;
678
+ this.TLS = init?.TLS ?? null;
266
679
  if (this.Status === '' && this.StatusCode !== 0) {
267
680
  const text = StatusText(this.StatusCode);
268
681
  this.Status = text === '' ? String(this.StatusCode) : `${this.StatusCode} ${text}`;
@@ -274,8 +687,87 @@ export class Response {
274
687
  Header: this.Header,
275
688
  Status: this.Status,
276
689
  StatusCode: this.StatusCode,
690
+ Proto: this.Proto,
691
+ ProtoMajor: this.ProtoMajor,
692
+ ProtoMinor: this.ProtoMinor,
693
+ ContentLength: this.ContentLength,
694
+ TransferEncoding: this.TransferEncoding,
695
+ Close: this.Close,
696
+ Uncompressed: this.Uncompressed,
697
+ Trailer: this.Trailer,
698
+ Request: this.Request,
699
+ TLS: this.TLS,
277
700
  });
278
701
  }
702
+ Cookies() {
703
+ const values = Header_Values(this.Header, 'Set-Cookie');
704
+ if (values == null) {
705
+ return null;
706
+ }
707
+ const cookies = [];
708
+ for (const value of Array.from(values)) {
709
+ const [cookie] = ParseSetCookie(String(value));
710
+ if (cookie != null) {
711
+ cookies.push(cookie);
712
+ }
713
+ }
714
+ return $.arrayToSlice(cookies);
715
+ }
716
+ Location() {
717
+ const location = Header_Get(this.Header, 'Location');
718
+ if (location === '') {
719
+ return [null, ErrNoLocation];
720
+ }
721
+ try {
722
+ return [new URL(location), null];
723
+ }
724
+ catch (err) {
725
+ return [null, errors.New(String(err))];
726
+ }
727
+ }
728
+ ProtoAtLeast(major, minor) {
729
+ return this.ProtoMajor > major || (this.ProtoMajor === major && this.ProtoMinor >= minor);
730
+ }
731
+ Write(w) {
732
+ const write = (data) => {
733
+ const [n, err] = w.Write(data);
734
+ if (err != null) {
735
+ return err;
736
+ }
737
+ return n === $.len(data) ? null : io.ErrShortWrite;
738
+ };
739
+ let err = write($.stringToBytes(`${this.Proto} ${this.Status}\r\n`));
740
+ if (err != null) {
741
+ return err;
742
+ }
743
+ err = Header_Write(this.Header, w);
744
+ if (err != null) {
745
+ return err;
746
+ }
747
+ err = write($.stringToBytes('\r\n'));
748
+ if (err != null) {
749
+ return err;
750
+ }
751
+ if (this.Body == null) {
752
+ return null;
753
+ }
754
+ const buf = $.makeSlice(32 * 1024, undefined, 'byte');
755
+ while (true) {
756
+ const [n, readErr] = this.Body.Read(buf);
757
+ if (n > 0) {
758
+ err = write($.goSlice(buf, 0, n));
759
+ if (err != null) {
760
+ return err;
761
+ }
762
+ }
763
+ if (readErr === io.EOF) {
764
+ return null;
765
+ }
766
+ if (readErr != null) {
767
+ return readErr;
768
+ }
769
+ }
770
+ }
279
771
  }
280
772
  export class Client {
281
773
  Transport;
@@ -285,9 +777,166 @@ export class Client {
285
777
  async Do(_req) {
286
778
  return await (this.Transport ?? DefaultTransport).RoundTrip(_req);
287
779
  }
780
+ async Get(url) {
781
+ const [req, err] = NewRequest(MethodGet, url, null);
782
+ if (err != null) {
783
+ return [null, err];
784
+ }
785
+ return await this.Do(req);
786
+ }
787
+ async Head(url) {
788
+ const [req, err] = NewRequest(MethodHead, url, null);
789
+ if (err != null) {
790
+ return [null, err];
791
+ }
792
+ return await this.Do(req);
793
+ }
794
+ async Post(url, contentType, body) {
795
+ const [req, err] = NewRequest(MethodPost, url, body);
796
+ if (err != null || req == null) {
797
+ return [null, err];
798
+ }
799
+ Header_Set(req.Header, 'Content-Type', contentType);
800
+ return await this.Do(req);
801
+ }
802
+ async PostForm(url, data) {
803
+ return await this.Post(url, 'application/x-www-form-urlencoded', bytes.NewReader($.stringToBytes(encodeFormData(data))));
804
+ }
805
+ CloseIdleConnections() {
806
+ const closer = this.Transport;
807
+ closer?.CloseIdleConnections?.();
808
+ }
288
809
  }
289
810
  export const DefaultClient = new Client();
290
- class defaultTransport {
811
+ export class ClientConn {
812
+ }
813
+ function encodeFormData(data) {
814
+ if (data == null) {
815
+ return '';
816
+ }
817
+ if (typeof data.Encode === 'function') {
818
+ return String(data.Encode());
819
+ }
820
+ if (data instanceof URLSearchParams) {
821
+ return data.toString();
822
+ }
823
+ const entries = data instanceof Map ?
824
+ Array.from(data.entries())
825
+ : typeof data === 'object' ?
826
+ Object.entries(data)
827
+ : [];
828
+ entries.sort(([a], [b]) => String(a).localeCompare(String(b)));
829
+ const params = new URLSearchParams();
830
+ for (const [key, value] of entries) {
831
+ appendFormValue(params, String(key), value);
832
+ }
833
+ return params.toString();
834
+ }
835
+ function appendFormValue(params, key, value) {
836
+ const unwrapped = unwrapFormValue(value);
837
+ if (unwrapped == null) {
838
+ return;
839
+ }
840
+ if (Array.isArray(unwrapped)) {
841
+ for (const item of unwrapped) {
842
+ appendFormValue(params, key, item);
843
+ }
844
+ return;
845
+ }
846
+ params.append(key, String(unwrapped));
847
+ }
848
+ function unwrapFormValue(value) {
849
+ if ($.isVarRef(value)) {
850
+ return value.value;
851
+ }
852
+ if (typeof value === 'object' && value !== null && '__goValue' in value) {
853
+ return value.__goValue;
854
+ }
855
+ return value;
856
+ }
857
+ export class Protocols {
858
+ bits = 0;
859
+ HTTP1() {
860
+ return (this.bits & 1) !== 0;
861
+ }
862
+ SetHTTP1(ok) {
863
+ this.setBit(1, ok);
864
+ }
865
+ HTTP2() {
866
+ return (this.bits & 2) !== 0;
867
+ }
868
+ SetHTTP2(ok) {
869
+ this.setBit(2, ok);
870
+ }
871
+ UnencryptedHTTP2() {
872
+ return (this.bits & 4) !== 0;
873
+ }
874
+ SetUnencryptedHTTP2(ok) {
875
+ this.setBit(4, ok);
876
+ }
877
+ String() {
878
+ const names = [];
879
+ if (this.HTTP1()) {
880
+ names.push('HTTP1');
881
+ }
882
+ if (this.HTTP2()) {
883
+ names.push('HTTP2');
884
+ }
885
+ if (this.UnencryptedHTTP2()) {
886
+ names.push('UnencryptedHTTP2');
887
+ }
888
+ return `{${names.join(',')}}`;
889
+ }
890
+ setBit(bit, ok) {
891
+ this.bits = ok ? this.bits | bit : this.bits & ~bit;
892
+ }
893
+ }
894
+ export class HTTP2Config {
895
+ MaxConcurrentStreams = 0;
896
+ StrictMaxConcurrentRequests = false;
897
+ MaxDecoderHeaderTableSize = 0;
898
+ MaxEncoderHeaderTableSize = 0;
899
+ MaxReadFrameSize = 0;
900
+ MaxReceiveBufferPerConnection = 0;
901
+ MaxReceiveBufferPerStream = 0;
902
+ SendPingTimeout = 0;
903
+ PingTimeout = 0;
904
+ WriteByteTimeout = 0;
905
+ PermitProhibitedCipherSuites = false;
906
+ CountError = null;
907
+ constructor(init) {
908
+ Object.assign(this, init);
909
+ }
910
+ }
911
+ export class Transport {
912
+ Proxy = null;
913
+ OnProxyConnectResponse = null;
914
+ DialContext = null;
915
+ Dial = null;
916
+ DialTLSContext = null;
917
+ DialTLS = null;
918
+ TLSClientConfig = null;
919
+ TLSHandshakeTimeout = 0;
920
+ DisableKeepAlives = false;
921
+ DisableCompression = false;
922
+ MaxIdleConns = 0;
923
+ MaxIdleConnsPerHost = 0;
924
+ MaxConnsPerHost = 0;
925
+ IdleConnTimeout = 0;
926
+ ResponseHeaderTimeout = 0;
927
+ ExpectContinueTimeout = 0;
928
+ TLSNextProto = null;
929
+ ProxyConnectHeader = new Header();
930
+ GetProxyConnectHeader = null;
931
+ MaxResponseHeaderBytes = 0;
932
+ WriteBufferSize = 0;
933
+ ReadBufferSize = 0;
934
+ ForceAttemptHTTP2 = false;
935
+ HTTP2 = null;
936
+ Protocols = null;
937
+ constructor(init) {
938
+ Object.assign(this, init);
939
+ }
291
940
  async RoundTrip(req) {
292
941
  const request = $.pointerValue(req);
293
942
  if (request == null) {
@@ -296,32 +945,408 @@ class defaultTransport {
296
945
  const host = request.URL?.Host ?? '';
297
946
  const handler = host === '' ? null : inProcessServers.get(host);
298
947
  if (handler == null) {
299
- return [null, errors.New('net/http: Client.Do is not implemented in GoScript')];
948
+ return await fetchRoundTrip(request);
300
949
  }
301
950
  const recorder = new memoryResponseWriter();
302
- const served = handler.ServeHTTP(recorder, request);
303
- if (served instanceof Promise) {
304
- await served;
951
+ let closeErr;
952
+ try {
953
+ const served = handler.ServeHTTP(recorder, inProcessServerRequest(request));
954
+ if (served instanceof Promise) {
955
+ await served;
956
+ }
957
+ }
958
+ finally {
959
+ closeErr = request.Body?.Close?.() ?? null;
960
+ }
961
+ if (closeErr != null) {
962
+ return [null, closeErr];
963
+ }
964
+ const response = recorder.Result();
965
+ if (request.Method === MethodHead) {
966
+ response.Body = NoBody;
967
+ }
968
+ return [response, null];
969
+ }
970
+ CloseIdleConnections() { }
971
+ CancelRequest(_req) { }
972
+ RegisterProtocol(_scheme, _rt) { }
973
+ NewClientConn(_ctx, _scheme, _address) {
974
+ return [null, ErrNotSupported];
975
+ }
976
+ Clone() {
977
+ return new Transport(this);
978
+ }
979
+ }
980
+ export const DefaultTransport = new Transport();
981
+ class fileTransport {
982
+ root;
983
+ constructor(root) {
984
+ this.root = root;
985
+ }
986
+ async RoundTrip(req) {
987
+ const request = $.pointerValue(req);
988
+ const recorder = new memoryResponseWriter();
989
+ let closeErr;
990
+ try {
991
+ await FileServer(this.root).ServeHTTP(recorder, request);
992
+ }
993
+ finally {
994
+ closeErr = request?.Body?.Close?.() ?? null;
995
+ }
996
+ if (closeErr != null) {
997
+ return [null, closeErr];
305
998
  }
306
999
  return [recorder.Result(), null];
307
1000
  }
308
1001
  }
309
- export const DefaultTransport = new defaultTransport();
1002
+ export function NewFileTransport(root) {
1003
+ return new fileTransport(root);
1004
+ }
1005
+ export function NewFileTransportFS(fsys) {
1006
+ return NewFileTransport(FS(fsys));
1007
+ }
1008
+ async function fetchRoundTrip(request) {
1009
+ const requestBody = request.Body;
1010
+ const closeRequestBody = () => {
1011
+ if (requestBody == null) {
1012
+ return null;
1013
+ }
1014
+ return requestBody.Close();
1015
+ };
1016
+ if (typeof globalThis.fetch !== 'function') {
1017
+ closeRequestBody();
1018
+ return [null, errors.New('net/http: Client.Do is not implemented in GoScript')];
1019
+ }
1020
+ const ctxErr = request.Context()?.Err?.();
1021
+ if (ctxErr != null) {
1022
+ closeRequestBody();
1023
+ return [null, ctxErr];
1024
+ }
1025
+ const headers = new globalThis.Headers();
1026
+ for (const [key, values] of request.Header.entries()) {
1027
+ for (const value of Array.from(values ?? [])) {
1028
+ headers.append(key, String(value));
1029
+ }
1030
+ }
1031
+ let body;
1032
+ if (requestBody != null && request.Method !== MethodGet && request.Method !== MethodHead) {
1033
+ const [data, err] = await io.ReadAll(requestBody);
1034
+ const closeErr = closeRequestBody();
1035
+ if (err != null) {
1036
+ return [null, err];
1037
+ }
1038
+ if (closeErr != null) {
1039
+ return [null, closeErr];
1040
+ }
1041
+ body = Uint8Array.from(data ?? []);
1042
+ }
1043
+ else {
1044
+ const closeErr = closeRequestBody();
1045
+ if (closeErr != null) {
1046
+ return [null, closeErr];
1047
+ }
1048
+ }
1049
+ try {
1050
+ const bodyInit = body == null ? undefined : Uint8Array.from(body).buffer;
1051
+ const fetched = await globalThis.fetch(request.URL?.String?.() ?? '', {
1052
+ method: request.Method || MethodGet,
1053
+ headers,
1054
+ body: bodyInit,
1055
+ });
1056
+ const data = new Uint8Array(await fetched.arrayBuffer());
1057
+ const respHeader = new Header();
1058
+ fetched.headers.forEach((value, key) => Header_Add(respHeader, key, value));
1059
+ return [
1060
+ new Response({
1061
+ Status: `${fetched.status} ${fetched.statusText}`,
1062
+ StatusCode: fetched.status,
1063
+ Body: new responseBody(data),
1064
+ Header: respHeader,
1065
+ ContentLength: Number(fetched.headers.get('content-length') ?? -1),
1066
+ Request: request,
1067
+ }),
1068
+ null,
1069
+ ];
1070
+ }
1071
+ catch (err) {
1072
+ const message = typeof err === 'object' && err != null && 'message' in err
1073
+ ? String(err.message)
1074
+ : String(err);
1075
+ return [null, errors.New(message)];
1076
+ }
1077
+ }
1078
+ export function FS(fsys) {
1079
+ return {
1080
+ Open(name) {
1081
+ const cleaned = cleanFileServerPath(name);
1082
+ const [file, err] = fsys?.Open(cleaned) ?? [null, fs.ErrInvalid];
1083
+ if (err != null || file == null) {
1084
+ return [null, err];
1085
+ }
1086
+ return [httpFileFromFSFile(file), null];
1087
+ },
1088
+ };
1089
+ }
1090
+ function httpFileFromFSFile(file) {
1091
+ const seek = file.Seek;
1092
+ const readdir = file.Readdir;
1093
+ return {
1094
+ Read: (p) => file.Read(p instanceof Uint8Array ? p : Uint8Array.from(p ?? [])),
1095
+ Close: () => file.Close(),
1096
+ Stat: () => file.Stat(),
1097
+ Seek: seek == null ? () => [0, errors.New('net/http: file does not support seek')] : seek.bind(file),
1098
+ Readdir: readdir == null ? () => [null, io.EOF] : readdir.bind(file),
1099
+ };
1100
+ }
1101
+ export function FileServer(root) {
1102
+ return {
1103
+ async ServeHTTP(w, r) {
1104
+ const req = $.pointerValue(r);
1105
+ if (w == null || req == null) {
1106
+ return;
1107
+ }
1108
+ if (req.Method !== MethodGet && req.Method !== MethodHead) {
1109
+ Error(w, 'method not allowed', StatusMethodNotAllowed);
1110
+ return;
1111
+ }
1112
+ const [file, err] = root?.Open(cleanFileServerPath(req.URL?.Path ?? '')) ?? [null, fs.ErrInvalid];
1113
+ if (err != null || file == null) {
1114
+ NotFound(w, req);
1115
+ return;
1116
+ }
1117
+ try {
1118
+ const [info, statErr] = file.Stat();
1119
+ if (statErr != null) {
1120
+ Error(w, statErr.Error(), StatusInternalServerError);
1121
+ return;
1122
+ }
1123
+ if (info?.IsDir?.() === true) {
1124
+ NotFound(w, req);
1125
+ return;
1126
+ }
1127
+ const [data, readErr] = await io.ReadAll(file);
1128
+ if (readErr != null) {
1129
+ Error(w, readErr.Error(), StatusInternalServerError);
1130
+ return;
1131
+ }
1132
+ if (info?.Size != null) {
1133
+ Header_Set(w.Header(), 'Content-Length', String(info.Size()));
1134
+ }
1135
+ w.WriteHeader(StatusOK);
1136
+ if (req.Method !== MethodHead) {
1137
+ w.Write(data);
1138
+ }
1139
+ }
1140
+ finally {
1141
+ file.Close();
1142
+ }
1143
+ },
1144
+ };
1145
+ }
1146
+ export function FileServerFS(fsys) {
1147
+ return FileServer(FS(fsys));
1148
+ }
1149
+ export function ServeFile(w, r, _name) {
1150
+ const req = $.pointerValue(r);
1151
+ if (w == null || req == null) {
1152
+ return;
1153
+ }
1154
+ if (req.Method !== MethodGet && req.Method !== MethodHead) {
1155
+ Error(w, 'method not allowed', StatusMethodNotAllowed);
1156
+ return;
1157
+ }
1158
+ NotFound(w, req);
1159
+ }
1160
+ export function ServeFileFS(w, r, _fsys, name) {
1161
+ ServeFile(w, r, name);
1162
+ }
1163
+ function cleanFileServerPath(name) {
1164
+ const parts = [];
1165
+ for (const part of name.split('?')[0].split('/')) {
1166
+ if (part === '' || part === '.') {
1167
+ continue;
1168
+ }
1169
+ if (part === '..') {
1170
+ parts.pop();
1171
+ continue;
1172
+ }
1173
+ parts.push(part);
1174
+ }
1175
+ return parts.length === 0 ? '.' : parts.join('/');
1176
+ }
310
1177
  export function HandlerFunc_ServeHTTP(h, w, r) {
311
1178
  return h(w, r);
312
1179
  }
1180
+ export class CrossOriginProtection {
1181
+ denyHandler = null;
1182
+ trustedOrigins = new Set();
1183
+ bypassPatterns = [];
1184
+ AddInsecureBypassPattern(pattern) {
1185
+ this.bypassPatterns.push(pattern);
1186
+ }
1187
+ AddTrustedOrigin(origin) {
1188
+ if (!/^[A-Za-z][A-Za-z0-9+.-]*:\/\/[^/?#]+$/.test(origin)) {
1189
+ return $.newError(`invalid origin "${origin}"`);
1190
+ }
1191
+ try {
1192
+ const parsed = new URL(origin);
1193
+ if (parsed.protocol === '' || parsed.host === '') {
1194
+ return $.newError(`invalid origin "${origin}"`);
1195
+ }
1196
+ }
1197
+ catch (err) {
1198
+ return $.newError(`invalid origin "${origin}": ${String(err)}`);
1199
+ }
1200
+ this.trustedOrigins.add(origin);
1201
+ return null;
1202
+ }
1203
+ Check(r) {
1204
+ const req = $.pointerValue(r);
1205
+ if (req == null) {
1206
+ return errCrossOriginRequest;
1207
+ }
1208
+ switch (req.Method) {
1209
+ case MethodGet:
1210
+ case MethodHead:
1211
+ case MethodOptions:
1212
+ return null;
1213
+ }
1214
+ switch (Header_Get(req.Header, 'Sec-Fetch-Site')) {
1215
+ case '':
1216
+ break;
1217
+ case 'same-origin':
1218
+ case 'none':
1219
+ return null;
1220
+ default:
1221
+ if (this.isRequestExempt(req)) {
1222
+ return null;
1223
+ }
1224
+ return errCrossOriginRequest;
1225
+ }
1226
+ const origin = Header_Get(req.Header, 'Origin');
1227
+ if (origin === '') {
1228
+ return null;
1229
+ }
1230
+ if (originHost(origin) === req.Host) {
1231
+ return null;
1232
+ }
1233
+ if (this.isRequestExempt(req)) {
1234
+ return null;
1235
+ }
1236
+ return errCrossOriginRequestFromOldBrowser;
1237
+ }
1238
+ Handler(handler) {
1239
+ return {
1240
+ ServeHTTP: (w, r) => {
1241
+ const err = this.Check(r);
1242
+ if (err != null) {
1243
+ const deny = this.denyHandler;
1244
+ if (deny != null) {
1245
+ return deny.ServeHTTP(w, r);
1246
+ }
1247
+ Error(w, err.Error(), StatusForbidden);
1248
+ return;
1249
+ }
1250
+ return handler?.ServeHTTP(w, r);
1251
+ },
1252
+ };
1253
+ }
1254
+ SetDenyHandler(handler) {
1255
+ this.denyHandler = handler;
1256
+ }
1257
+ isRequestExempt(req) {
1258
+ for (const pattern of this.bypassPatterns) {
1259
+ if (bypassPatternMatches(pattern, req)) {
1260
+ return true;
1261
+ }
1262
+ }
1263
+ const origin = Header_Get(req.Header, 'Origin');
1264
+ return origin !== '' && this.trustedOrigins.has(origin);
1265
+ }
1266
+ }
1267
+ export function NewCrossOriginProtection() {
1268
+ return new CrossOriginProtection();
1269
+ }
1270
+ function originHost(origin) {
1271
+ try {
1272
+ return new URL(origin).host;
1273
+ }
1274
+ catch {
1275
+ return '';
1276
+ }
1277
+ }
1278
+ function bypassPatternMatches(pattern, req) {
1279
+ let method = '';
1280
+ let pathPattern = pattern;
1281
+ const space = pattern.indexOf(' ');
1282
+ if (space > 0) {
1283
+ method = pattern.slice(0, space);
1284
+ pathPattern = pattern.slice(space + 1);
1285
+ }
1286
+ if (method !== '' && method !== req.Method) {
1287
+ return false;
1288
+ }
1289
+ const path = req.URL?.Path ?? '';
1290
+ if (pathPattern.includes('{')) {
1291
+ return wildcardPatternMatches(pathPattern, path);
1292
+ }
1293
+ if (pathPattern.endsWith('/')) {
1294
+ return path === pathPattern || path.startsWith(pathPattern);
1295
+ }
1296
+ return path === pathPattern;
1297
+ }
1298
+ function wildcardPatternMatches(pattern, path) {
1299
+ const patternParts = pattern.split('/').filter((part) => part !== '');
1300
+ const pathParts = path.split('/').filter((part) => part !== '');
1301
+ if (patternParts.length !== pathParts.length) {
1302
+ return false;
1303
+ }
1304
+ for (let i = 0; i < patternParts.length; i++) {
1305
+ if (/^\{[^}]+\}$/.test(patternParts[i])) {
1306
+ continue;
1307
+ }
1308
+ if (patternParts[i] !== pathParts[i]) {
1309
+ return false;
1310
+ }
1311
+ }
1312
+ return true;
1313
+ }
313
1314
  export class Server {
314
1315
  Addr;
315
1316
  BaseContext;
1317
+ ConnContext;
316
1318
  Handler;
1319
+ DisableGeneralOptionsHandler;
1320
+ TLSConfig;
1321
+ ReadTimeout;
1322
+ ReadTimeoutHandler;
317
1323
  ReadHeaderTimeout;
318
1324
  WriteTimeout;
1325
+ IdleTimeout;
1326
+ MaxHeaderBytes;
1327
+ TLSNextProto;
1328
+ ConnState;
1329
+ ErrorLog;
1330
+ HTTP2;
1331
+ Protocols;
319
1332
  constructor(init) {
320
1333
  this.Addr = init?.Addr ?? '';
321
1334
  this.BaseContext = init?.BaseContext ?? null;
1335
+ this.ConnContext = init?.ConnContext ?? null;
322
1336
  this.Handler = init?.Handler ?? null;
1337
+ this.DisableGeneralOptionsHandler = init?.DisableGeneralOptionsHandler ?? false;
1338
+ this.TLSConfig = init?.TLSConfig ?? null;
1339
+ this.ReadTimeout = init?.ReadTimeout ?? 0;
1340
+ this.ReadTimeoutHandler = init?.ReadTimeoutHandler ?? null;
323
1341
  this.ReadHeaderTimeout = init?.ReadHeaderTimeout ?? 0;
324
1342
  this.WriteTimeout = init?.WriteTimeout ?? 0;
1343
+ this.IdleTimeout = init?.IdleTimeout ?? 0;
1344
+ this.MaxHeaderBytes = init?.MaxHeaderBytes ?? 0;
1345
+ this.TLSNextProto = init?.TLSNextProto ?? null;
1346
+ this.ConnState = init?.ConnState ?? null;
1347
+ this.ErrorLog = init?.ErrorLog ?? null;
1348
+ this.HTTP2 = init?.HTTP2 ?? null;
1349
+ this.Protocols = init?.Protocols ?? null;
325
1350
  }
326
1351
  ListenAndServe() {
327
1352
  return errors.New('net/http: Server.ListenAndServe is not implemented in GoScript');
@@ -335,6 +1360,29 @@ export class Server {
335
1360
  Shutdown(_ctx) {
336
1361
  return null;
337
1362
  }
1363
+ Serve(_listener) {
1364
+ return ErrNotSupported;
1365
+ }
1366
+ ServeTLS(_listener, _certFile, _keyFile) {
1367
+ return ErrNotSupported;
1368
+ }
1369
+ ServeHTTP(w, r) {
1370
+ return (this.Handler ?? DefaultServeMux).ServeHTTP(w, r);
1371
+ }
1372
+ RegisterOnShutdown(_f) { }
1373
+ SetKeepAlivesEnabled(_v) { }
1374
+ }
1375
+ export function ListenAndServe(_addr, _handler) {
1376
+ return ErrNotSupported;
1377
+ }
1378
+ export function ListenAndServeTLS(_addr, _certFile, _keyFile, _handler) {
1379
+ return ErrNotSupported;
1380
+ }
1381
+ export function Serve(_listener, _handler) {
1382
+ return ErrNotSupported;
1383
+ }
1384
+ export function ServeTLS(_listener, _handler, _certFile, _keyFile) {
1385
+ return ErrNotSupported;
338
1386
  }
339
1387
  export class PushOptions {
340
1388
  Header;
@@ -352,10 +1400,59 @@ export class ResponseController {
352
1400
  flusher?.Flush?.();
353
1401
  return null;
354
1402
  }
1403
+ Hijack() {
1404
+ return [null, null, ErrNotSupported];
1405
+ }
1406
+ SetReadDeadline(_deadline) {
1407
+ return ErrNotSupported;
1408
+ }
1409
+ SetWriteDeadline(_deadline) {
1410
+ return ErrNotSupported;
1411
+ }
1412
+ EnableFullDuplex() {
1413
+ return ErrNotSupported;
1414
+ }
355
1415
  }
356
1416
  export function NewResponseController(rw) {
357
1417
  return new ResponseController(rw);
358
1418
  }
1419
+ class maxBytesReader {
1420
+ reader;
1421
+ initialLimit;
1422
+ remaining;
1423
+ err = null;
1424
+ constructor(reader, limit) {
1425
+ this.reader = reader;
1426
+ this.initialLimit = Math.max(0, limit);
1427
+ this.remaining = this.initialLimit;
1428
+ }
1429
+ Read(p) {
1430
+ if (this.err != null) {
1431
+ return [0, this.err];
1432
+ }
1433
+ if ($.len(p) === 0) {
1434
+ return [0, null];
1435
+ }
1436
+ const readLen = $.len(p) - 1 > this.remaining ? this.remaining + 1 : $.len(p);
1437
+ const target = $.goSlice(p, 0, readLen);
1438
+ const [n, err] = this.reader.Read(target);
1439
+ if (n <= this.remaining) {
1440
+ this.remaining -= n;
1441
+ this.err = err;
1442
+ return [n, err];
1443
+ }
1444
+ const accepted = this.remaining;
1445
+ this.remaining = 0;
1446
+ this.err = new MaxBytesError({ Limit: this.initialLimit });
1447
+ return [accepted, this.err];
1448
+ }
1449
+ Close() {
1450
+ return this.reader.Close();
1451
+ }
1452
+ }
1453
+ export function MaxBytesReader(_w, r, n) {
1454
+ return new maxBytesReader(r ?? NoBody, n);
1455
+ }
359
1456
  export class ServeMux {
360
1457
  handlers = new Map();
361
1458
  Handle(pattern, handler) {
@@ -381,12 +1478,15 @@ export class ServeMux {
381
1478
  return handler.ServeHTTP(w, r);
382
1479
  }
383
1480
  }
384
- const defaultServeMux = new ServeMux();
1481
+ export const DefaultServeMux = new ServeMux();
385
1482
  export function NewServeMux() {
386
1483
  return new ServeMux();
387
1484
  }
1485
+ export function Handle(pattern, handler) {
1486
+ DefaultServeMux.Handle(pattern, handler);
1487
+ }
388
1488
  export function HandleFunc(pattern, handler) {
389
- defaultServeMux.HandleFunc(pattern, handler);
1489
+ DefaultServeMux.HandleFunc(pattern, handler);
390
1490
  }
391
1491
  export function StripPrefix(prefix, handler) {
392
1492
  return {
@@ -399,6 +1499,44 @@ export function StripPrefix(prefix, handler) {
399
1499
  },
400
1500
  };
401
1501
  }
1502
+ export function AllowQuerySemicolons(handler) {
1503
+ return handler ?? NotFoundHandler();
1504
+ }
1505
+ export function MaxBytesHandler(handler, n) {
1506
+ return {
1507
+ ServeHTTP(w, r) {
1508
+ const req = $.pointerValue(r);
1509
+ let wrappedReq = req;
1510
+ if (req != null && req.Body != null) {
1511
+ const reqCopy = Object.assign(Object.create(Object.getPrototypeOf(req)), req);
1512
+ reqCopy.Body = MaxBytesReader(w, req.Body, n);
1513
+ wrappedReq = reqCopy;
1514
+ }
1515
+ return handler?.ServeHTTP(w, wrappedReq);
1516
+ },
1517
+ };
1518
+ }
1519
+ export function NotFoundHandler() {
1520
+ return { ServeHTTP: NotFound };
1521
+ }
1522
+ export function RedirectHandler(url, code) {
1523
+ return {
1524
+ ServeHTTP(w, r) {
1525
+ Redirect(w, r, url, code);
1526
+ },
1527
+ };
1528
+ }
1529
+ export function TimeoutHandler(handler, _dt, msg) {
1530
+ return {
1531
+ ServeHTTP(w, r) {
1532
+ if (handler == null) {
1533
+ Error(w, msg, StatusServiceUnavailable);
1534
+ return;
1535
+ }
1536
+ return handler.ServeHTTP(w, r);
1537
+ },
1538
+ };
1539
+ }
402
1540
  export function Error(w, error, code) {
403
1541
  w?.WriteHeader(code);
404
1542
  w?.Write($.stringToBytes(error + '\n'));
@@ -420,17 +1558,436 @@ export function ParseTime(text) {
420
1558
  }
421
1559
  return [time.UnixMilli(date.getTime()), null];
422
1560
  }
1561
+ export function DetectContentType(data) {
1562
+ const bytes = Uint8Array.from(data ?? []).subarray(0, 512);
1563
+ const firstNonWS = firstNonWhitespace(bytes);
1564
+ const afterWS = bytes.subarray(firstNonWS);
1565
+ if (htmlSig(afterWS, '<!DOCTYPE HTML') ||
1566
+ htmlSig(afterWS, '<HTML') ||
1567
+ htmlSig(afterWS, '<HEAD') ||
1568
+ htmlSig(afterWS, '<SCRIPT') ||
1569
+ htmlSig(afterWS, '<IFRAME') ||
1570
+ htmlSig(afterWS, '<H1') ||
1571
+ htmlSig(afterWS, '<DIV') ||
1572
+ htmlSig(afterWS, '<FONT') ||
1573
+ htmlSig(afterWS, '<TABLE') ||
1574
+ htmlSig(afterWS, '<A') ||
1575
+ htmlSig(afterWS, '<STYLE') ||
1576
+ htmlSig(afterWS, '<TITLE') ||
1577
+ htmlSig(afterWS, '<B') ||
1578
+ htmlSig(afterWS, '<BODY') ||
1579
+ htmlSig(afterWS, '<BR') ||
1580
+ htmlSig(afterWS, '<P') ||
1581
+ startsWithASCII(afterWS, '<!--')) {
1582
+ return 'text/html; charset=utf-8';
1583
+ }
1584
+ if (startsWithASCII(afterWS, '<?xml')) {
1585
+ return 'text/xml; charset=utf-8';
1586
+ }
1587
+ if (startsWithASCII(bytes, '%PDF-')) {
1588
+ return 'application/pdf';
1589
+ }
1590
+ if (startsWithASCII(bytes, '%!PS-Adobe-')) {
1591
+ return 'application/postscript';
1592
+ }
1593
+ if (startsWithBytes(bytes, new Uint8Array([0xfe, 0xff]))) {
1594
+ return 'text/plain; charset=utf-16be';
1595
+ }
1596
+ if (startsWithBytes(bytes, new Uint8Array([0xff, 0xfe]))) {
1597
+ return 'text/plain; charset=utf-16le';
1598
+ }
1599
+ if (startsWithBytes(bytes, new Uint8Array([0xef, 0xbb, 0xbf]))) {
1600
+ return 'text/plain; charset=utf-8';
1601
+ }
1602
+ if (startsWithBytes(bytes, new Uint8Array([0x00, 0x00, 0x01, 0x00])) || startsWithBytes(bytes, new Uint8Array([0x00, 0x00, 0x02, 0x00]))) {
1603
+ return 'image/x-icon';
1604
+ }
1605
+ if (startsWithASCII(bytes, 'BM')) {
1606
+ return 'image/bmp';
1607
+ }
1608
+ if (startsWithASCII(bytes, 'GIF87a') || startsWithASCII(bytes, 'GIF89a')) {
1609
+ return 'image/gif';
1610
+ }
1611
+ if (isRIFFSignature(bytes, 'WEBPVP')) {
1612
+ return 'image/webp';
1613
+ }
1614
+ if (startsWithBytes(bytes, new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {
1615
+ return 'image/png';
1616
+ }
1617
+ if (startsWithBytes(bytes, new Uint8Array([0xff, 0xd8, 0xff]))) {
1618
+ return 'image/jpeg';
1619
+ }
1620
+ if (isFORMSignature(bytes, 'AIFF')) {
1621
+ return 'audio/aiff';
1622
+ }
1623
+ if (startsWithASCII(bytes, 'ID3')) {
1624
+ return 'audio/mpeg';
1625
+ }
1626
+ if (startsWithBytes(bytes, new Uint8Array([0x4f, 0x67, 0x67, 0x53, 0x00]))) {
1627
+ return 'application/ogg';
1628
+ }
1629
+ if (startsWithBytes(bytes, new Uint8Array([0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06]))) {
1630
+ return 'audio/midi';
1631
+ }
1632
+ if (isRIFFSignature(bytes, 'AVI ')) {
1633
+ return 'video/avi';
1634
+ }
1635
+ if (isRIFFSignature(bytes, 'WAVE')) {
1636
+ return 'audio/wave';
1637
+ }
1638
+ if (isMP4Signature(bytes)) {
1639
+ return 'video/mp4';
1640
+ }
1641
+ if (startsWithBytes(bytes, new Uint8Array([0x1a, 0x45, 0xdf, 0xa3]))) {
1642
+ return 'video/webm';
1643
+ }
1644
+ if (isEOTSignature(bytes)) {
1645
+ return 'application/vnd.ms-fontobject';
1646
+ }
1647
+ if (startsWithBytes(bytes, new Uint8Array([0x00, 0x01, 0x00, 0x00]))) {
1648
+ return 'font/ttf';
1649
+ }
1650
+ if (startsWithASCII(bytes, 'OTTO')) {
1651
+ return 'font/otf';
1652
+ }
1653
+ if (startsWithASCII(bytes, 'ttcf')) {
1654
+ return 'font/collection';
1655
+ }
1656
+ if (startsWithASCII(bytes, 'wOFF')) {
1657
+ return 'font/woff';
1658
+ }
1659
+ if (startsWithASCII(bytes, 'wOF2')) {
1660
+ return 'font/woff2';
1661
+ }
1662
+ if (startsWithBytes(bytes, new Uint8Array([0x1f, 0x8b, 0x08]))) {
1663
+ return 'application/x-gzip';
1664
+ }
1665
+ if (startsWithBytes(bytes, new Uint8Array([0x50, 0x4b, 0x03, 0x04]))) {
1666
+ return 'application/zip';
1667
+ }
1668
+ if (startsWithBytes(bytes, new Uint8Array([0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00]))) {
1669
+ return 'application/x-rar-compressed';
1670
+ }
1671
+ if (startsWithBytes(bytes, new Uint8Array([0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00]))) {
1672
+ return 'application/x-rar-compressed';
1673
+ }
1674
+ if (startsWithBytes(bytes, new Uint8Array([0x00, 0x61, 0x73, 0x6d]))) {
1675
+ return 'application/wasm';
1676
+ }
1677
+ for (const byte of afterWS) {
1678
+ if (byte <= 0x08 || byte === 0x0b || (byte >= 0x0e && byte <= 0x1a) || (byte >= 0x1c && byte <= 0x1f)) {
1679
+ return 'application/octet-stream';
1680
+ }
1681
+ }
1682
+ return 'text/plain; charset=utf-8';
1683
+ }
1684
+ function firstNonWhitespace(data) {
1685
+ for (let i = 0; i < data.length; i++) {
1686
+ const byte = data[i];
1687
+ if (byte !== 0x09 && byte !== 0x0a && byte !== 0x0c && byte !== 0x0d && byte !== 0x20) {
1688
+ return i;
1689
+ }
1690
+ }
1691
+ return data.length;
1692
+ }
1693
+ function startsWithBytes(data, prefix) {
1694
+ if (data.length < prefix.length) {
1695
+ return false;
1696
+ }
1697
+ for (let i = 0; i < prefix.length; i++) {
1698
+ if (data[i] !== prefix[i]) {
1699
+ return false;
1700
+ }
1701
+ }
1702
+ return true;
1703
+ }
1704
+ function startsWithASCII(data, prefix) {
1705
+ return asciiMatchesAt(data, 0, prefix);
1706
+ }
1707
+ function asciiMatchesAt(data, offset, text) {
1708
+ if (data.length < offset + text.length) {
1709
+ return false;
1710
+ }
1711
+ for (let i = 0; i < text.length; i++) {
1712
+ if (data[offset + i] !== text.charCodeAt(i)) {
1713
+ return false;
1714
+ }
1715
+ }
1716
+ return true;
1717
+ }
1718
+ function isRIFFSignature(data, form) {
1719
+ return asciiMatchesAt(data, 0, 'RIFF') && asciiMatchesAt(data, 8, form);
1720
+ }
1721
+ function isFORMSignature(data, form) {
1722
+ return asciiMatchesAt(data, 0, 'FORM') && asciiMatchesAt(data, 8, form);
1723
+ }
1724
+ function isMP4Signature(data) {
1725
+ if (data.length < 12 || !asciiMatchesAt(data, 4, 'ftyp')) {
1726
+ return false;
1727
+ }
1728
+ const boxSize = data[0] * 0x1000000 + data[1] * 0x10000 + data[2] * 0x100 + data[3];
1729
+ if (boxSize < 12 || data.length < boxSize || boxSize % 4 !== 0) {
1730
+ return false;
1731
+ }
1732
+ for (let offset = 8; offset + 3 <= boxSize; offset += 4) {
1733
+ if (offset === 12) {
1734
+ continue;
1735
+ }
1736
+ if (asciiMatchesAt(data, offset, 'mp4')) {
1737
+ return true;
1738
+ }
1739
+ }
1740
+ return false;
1741
+ }
1742
+ function isEOTSignature(data) {
1743
+ return data.length >= 36 && data[34] === 0x4c && data[35] === 0x50;
1744
+ }
1745
+ function htmlSig(data, sig) {
1746
+ if (data.length < sig.length + 1) {
1747
+ return false;
1748
+ }
1749
+ for (let i = 0; i < sig.length; i++) {
1750
+ const got = data[i] >= 0x61 && data[i] <= 0x7a ? data[i] & 0xdf : data[i];
1751
+ if (got !== sig.charCodeAt(i)) {
1752
+ return false;
1753
+ }
1754
+ }
1755
+ const term = data[sig.length];
1756
+ return term === 0x20 || term === 0x3e;
1757
+ }
1758
+ export function ParseHTTPVersion(vers) {
1759
+ const match = /^HTTP\/(\d+)\.(\d+)$/.exec(vers);
1760
+ if (match == null) {
1761
+ return [0, 0, false];
1762
+ }
1763
+ return [Number(match[1]), Number(match[2]), true];
1764
+ }
1765
+ export function ParseCookie(line) {
1766
+ const parts = line.trim().split(';');
1767
+ if (parts.length > 3000) {
1768
+ return [null, errCookieNumLimitExceeded];
1769
+ }
1770
+ if (parts.length === 1 && parts[0] === '') {
1771
+ return [null, errBlankCookie];
1772
+ }
1773
+ const cookies = [];
1774
+ for (const raw of parts) {
1775
+ const part = raw.trim();
1776
+ const eq = part.indexOf('=');
1777
+ if (eq < 0) {
1778
+ return [null, errEqualNotFoundInCookie];
1779
+ }
1780
+ const name = part.slice(0, eq);
1781
+ if (!isToken(name)) {
1782
+ return [null, errInvalidCookieName];
1783
+ }
1784
+ const [value, quoted, ok] = parseCookieValue(part.slice(eq + 1), true);
1785
+ if (!ok) {
1786
+ return [null, errInvalidCookieValue];
1787
+ }
1788
+ cookies.push(new Cookie({ Name: name, Value: value, Quoted: quoted }));
1789
+ }
1790
+ return [$.arrayToSlice(cookies), null];
1791
+ }
1792
+ export function ParseSetCookie(line) {
1793
+ const parts = line.trim().split(';');
1794
+ if (parts.length === 1 && parts[0] === '') {
1795
+ return [null, errBlankCookie];
1796
+ }
1797
+ const first = parts[0].trim();
1798
+ const eq = first.indexOf('=');
1799
+ if (eq < 0) {
1800
+ return [null, errEqualNotFoundInCookie];
1801
+ }
1802
+ const name = first.slice(0, eq).trim();
1803
+ if (!isToken(name)) {
1804
+ return [null, errInvalidCookieName];
1805
+ }
1806
+ const [value, quoted, ok] = parseCookieValue(first.slice(eq + 1), true);
1807
+ if (!ok) {
1808
+ return [null, errInvalidCookieValue];
1809
+ }
1810
+ const cookie = new Cookie({ Name: name, Value: value, Quoted: quoted, Raw: line });
1811
+ const unparsed = [];
1812
+ for (const raw of parts.slice(1)) {
1813
+ const part = raw.trim();
1814
+ if (part === '') {
1815
+ continue;
1816
+ }
1817
+ const attrEq = part.indexOf('=');
1818
+ const attr = attrEq < 0 ? part : part.slice(0, attrEq);
1819
+ const rawValue = attrEq < 0 ? '' : part.slice(attrEq + 1);
1820
+ const [lowerAttr, ascii] = asciiLower(attr);
1821
+ if (!ascii) {
1822
+ continue;
1823
+ }
1824
+ const [attrValue, , attrOK] = parseCookieValue(rawValue, false);
1825
+ if (!attrOK) {
1826
+ unparsed.push(part);
1827
+ continue;
1828
+ }
1829
+ switch (lowerAttr) {
1830
+ case 'samesite': {
1831
+ const [lowerValue, valueASCII] = asciiLower(attrValue);
1832
+ if (!valueASCII) {
1833
+ cookie.SameSite = SameSiteDefaultMode;
1834
+ continue;
1835
+ }
1836
+ switch (lowerValue) {
1837
+ case 'lax':
1838
+ cookie.SameSite = SameSiteLaxMode;
1839
+ break;
1840
+ case 'strict':
1841
+ cookie.SameSite = SameSiteStrictMode;
1842
+ break;
1843
+ case 'none':
1844
+ cookie.SameSite = SameSiteNoneMode;
1845
+ break;
1846
+ default:
1847
+ cookie.SameSite = SameSiteDefaultMode;
1848
+ break;
1849
+ }
1850
+ continue;
1851
+ }
1852
+ case 'secure':
1853
+ cookie.Secure = true;
1854
+ continue;
1855
+ case 'httponly':
1856
+ cookie.HttpOnly = true;
1857
+ continue;
1858
+ case 'domain':
1859
+ cookie.Domain = attrValue;
1860
+ continue;
1861
+ case 'max-age': {
1862
+ if (!/^[+-]?\d+$/.test(attrValue)) {
1863
+ break;
1864
+ }
1865
+ let secs = Number.parseInt(attrValue, 10);
1866
+ if ((secs !== 0 && attrValue[0] === '0') || !Number.isSafeInteger(secs)) {
1867
+ break;
1868
+ }
1869
+ if (secs <= 0) {
1870
+ secs = -1;
1871
+ }
1872
+ cookie.MaxAge = secs;
1873
+ continue;
1874
+ }
1875
+ case 'expires': {
1876
+ cookie.RawExpires = attrValue;
1877
+ const parsed = new globalThis.Date(attrValue);
1878
+ if (Number.isNaN(parsed.getTime())) {
1879
+ break;
1880
+ }
1881
+ cookie.Expires = time.UnixMilli(parsed.getTime());
1882
+ continue;
1883
+ }
1884
+ case 'path':
1885
+ cookie.Path = attrValue;
1886
+ continue;
1887
+ case 'partitioned':
1888
+ cookie.Partitioned = true;
1889
+ continue;
1890
+ }
1891
+ unparsed.push(part);
1892
+ }
1893
+ cookie.Unparsed = unparsed.length === 0 ? null : $.arrayToSlice(unparsed);
1894
+ return [cookie, null];
1895
+ }
423
1896
  export function NewRequest(method, url, body) {
424
- return NewRequestWithContext(null, method, url, body);
1897
+ return NewRequestWithContext(context.Background(), method, url, body);
425
1898
  }
426
- export function NewRequestWithContext(_ctx, method, url, body) {
1899
+ export function NewRequestWithContext(ctx, method, url, body) {
427
1900
  if (method === '') {
428
1901
  method = MethodGet;
429
1902
  }
430
- const parsedURL = parseRequestURL(url);
431
- return [new Request({ Method: method, URL: parsedURL, Body: body, RequestURI: parsedURL.Path, ctx: _ctx }), null];
1903
+ if (!isToken(method)) {
1904
+ return [null, errors.New(`net/http: invalid method ${JSON.stringify(method)}`)];
1905
+ }
1906
+ if (ctx == null) {
1907
+ return [null, errors.New('net/http: nil Context')];
1908
+ }
1909
+ const [parsedURL, err] = parseRequestURL(url);
1910
+ if (err != null || parsedURL == null) {
1911
+ return [null, err];
1912
+ }
1913
+ const bodyInfo = requestBodyInfo(body, 0);
1914
+ return [new Request({ Method: method, URL: parsedURL, Body: bodyInfo.Body, ContentLength: bodyInfo.ContentLength, Host: parsedURL.Host, ctx }), null];
1915
+ }
1916
+ export async function Get(_url) {
1917
+ const [req, err] = NewRequest(MethodGet, _url, null);
1918
+ if (err != null) {
1919
+ return [null, err];
1920
+ }
1921
+ return await DefaultClient.Do(req);
1922
+ }
1923
+ export async function Head(_url) {
1924
+ const [req, err] = NewRequest(MethodHead, _url, null);
1925
+ if (err != null) {
1926
+ return [null, err];
1927
+ }
1928
+ return await DefaultClient.Do(req);
1929
+ }
1930
+ export async function Post(_url, contentType, body) {
1931
+ const [req, err] = NewRequest(MethodPost, _url, body);
1932
+ if (err != null || req == null) {
1933
+ return [null, err];
1934
+ }
1935
+ Header_Set(req.Header, 'Content-Type', contentType);
1936
+ return await DefaultClient.Do(req);
1937
+ }
1938
+ export async function PostForm(_url, data) {
1939
+ return await DefaultClient.PostForm(_url, data);
1940
+ }
1941
+ export function ProxyFromEnvironment(_req) {
1942
+ return [null, null];
1943
+ }
1944
+ export function ProxyURL(fixedURL) {
1945
+ return () => [fixedURL, null];
1946
+ }
1947
+ export function ReadRequest(_reader) {
1948
+ return [null, ErrNotSupported];
432
1949
  }
433
- export function Get(_url) {
434
- return [null, errors.New('net/http: Get is not implemented in GoScript')];
1950
+ export function ReadResponse(_reader, _req) {
1951
+ return [null, ErrNotSupported];
1952
+ }
1953
+ export async function ServeContent(w, req, _name, _modtime, content) {
1954
+ if (content == null) {
1955
+ NotFound(w, req);
1956
+ return;
1957
+ }
1958
+ const [data, err] = await io.ReadAll(content);
1959
+ if (err != null) {
1960
+ Error(w, err.Error(), StatusInternalServerError);
1961
+ return;
1962
+ }
1963
+ w?.WriteHeader(StatusOK);
1964
+ const request = $.pointerValueOrNil(req);
1965
+ if (request?.Method !== MethodHead) {
1966
+ w?.Write(data);
1967
+ }
1968
+ }
1969
+ function readCloserForBody(body) {
1970
+ if (body == null) {
1971
+ return null;
1972
+ }
1973
+ const closer = body;
1974
+ if (typeof closer.Close === 'function') {
1975
+ return closer;
1976
+ }
1977
+ return io.NopCloser(body);
1978
+ }
1979
+ function requestBodyInfo(body, unknownLength) {
1980
+ if (body == null) {
1981
+ return { Body: null, ContentLength: 0 };
1982
+ }
1983
+ const value = $.pointerValueOrNil(body);
1984
+ if (value === NoBody) {
1985
+ return { Body: NoBody, ContentLength: 0 };
1986
+ }
1987
+ if (value instanceof bytes.Buffer || value instanceof bytes.Reader || value instanceof strings.Reader) {
1988
+ const length = value.Len();
1989
+ return { Body: length === 0 ? NoBody : readCloserForBody(body), ContentLength: length };
1990
+ }
1991
+ return { Body: readCloserForBody(body), ContentLength: unknownLength };
435
1992
  }
436
1993
  //# sourceMappingURL=index.js.map