args.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. package fasthttp
  2. import (
  3. "bytes"
  4. "errors"
  5. "io"
  6. "sort"
  7. "sync"
  8. )
  9. const (
  10. argsNoValue = true
  11. argsHasValue = false
  12. )
  13. // AcquireArgs returns an empty Args object from the pool.
  14. //
  15. // The returned Args may be returned to the pool with ReleaseArgs
  16. // when no longer needed. This allows reducing GC load.
  17. func AcquireArgs() *Args {
  18. return argsPool.Get().(*Args)
  19. }
  20. // ReleaseArgs returns the object acquired via AcquireArgs to the pool.
  21. //
  22. // Do not access the released Args object, otherwise data races may occur.
  23. func ReleaseArgs(a *Args) {
  24. a.Reset()
  25. argsPool.Put(a)
  26. }
  27. var argsPool = &sync.Pool{
  28. New: func() any {
  29. return &Args{}
  30. },
  31. }
  32. // Args represents query arguments.
  33. //
  34. // It is forbidden copying Args instances. Create new instances instead
  35. // and use CopyTo().
  36. //
  37. // Args instance MUST NOT be used from concurrently running goroutines.
  38. type Args struct {
  39. noCopy noCopy
  40. args []argsKV
  41. buf []byte
  42. }
  43. type argsKV struct {
  44. key []byte
  45. value []byte
  46. noValue bool
  47. }
  48. // Reset clears query args.
  49. func (a *Args) Reset() {
  50. a.args = a.args[:0]
  51. }
  52. // CopyTo copies all args to dst.
  53. func (a *Args) CopyTo(dst *Args) {
  54. dst.args = copyArgs(dst.args, a.args)
  55. }
  56. // VisitAll calls f for each existing arg.
  57. //
  58. // f must not retain references to key and value after returning.
  59. // Make key and/or value copies if you need storing them after returning.
  60. func (a *Args) VisitAll(f func(key, value []byte)) {
  61. visitArgs(a.args, f)
  62. }
  63. // Len returns the number of query args.
  64. func (a *Args) Len() int {
  65. return len(a.args)
  66. }
  67. // Parse parses the given string containing query args.
  68. func (a *Args) Parse(s string) {
  69. a.buf = append(a.buf[:0], s...)
  70. a.ParseBytes(a.buf)
  71. }
  72. // ParseBytes parses the given b containing query args.
  73. func (a *Args) ParseBytes(b []byte) {
  74. a.Reset()
  75. var s argsScanner
  76. s.b = b
  77. var kv *argsKV
  78. a.args, kv = allocArg(a.args)
  79. for s.next(kv) {
  80. if len(kv.key) > 0 || len(kv.value) > 0 {
  81. a.args, kv = allocArg(a.args)
  82. }
  83. }
  84. a.args = releaseArg(a.args)
  85. }
  86. // String returns string representation of query args.
  87. func (a *Args) String() string {
  88. return string(a.QueryString())
  89. }
  90. // QueryString returns query string for the args.
  91. //
  92. // The returned value is valid until the Args is reused or released (ReleaseArgs).
  93. // Do not store references to the returned value. Make copies instead.
  94. func (a *Args) QueryString() []byte {
  95. a.buf = a.AppendBytes(a.buf[:0])
  96. return a.buf
  97. }
  98. // Sort sorts Args by key and then value using 'f' as comparison function.
  99. //
  100. // For example args.Sort(bytes.Compare).
  101. func (a *Args) Sort(f func(x, y []byte) int) {
  102. sort.SliceStable(a.args, func(i, j int) bool {
  103. n := f(a.args[i].key, a.args[j].key)
  104. if n == 0 {
  105. return f(a.args[i].value, a.args[j].value) == -1
  106. }
  107. return n == -1
  108. })
  109. }
  110. // AppendBytes appends query string to dst and returns the extended dst.
  111. func (a *Args) AppendBytes(dst []byte) []byte {
  112. for i, n := 0, len(a.args); i < n; i++ {
  113. kv := &a.args[i]
  114. dst = AppendQuotedArg(dst, kv.key)
  115. if !kv.noValue {
  116. dst = append(dst, '=')
  117. if len(kv.value) > 0 {
  118. dst = AppendQuotedArg(dst, kv.value)
  119. }
  120. }
  121. if i+1 < n {
  122. dst = append(dst, '&')
  123. }
  124. }
  125. return dst
  126. }
  127. // WriteTo writes query string to w.
  128. //
  129. // WriteTo implements io.WriterTo interface.
  130. func (a *Args) WriteTo(w io.Writer) (int64, error) {
  131. n, err := w.Write(a.QueryString())
  132. return int64(n), err
  133. }
  134. // Del deletes argument with the given key from query args.
  135. func (a *Args) Del(key string) {
  136. a.args = delAllArgsStable(a.args, key)
  137. }
  138. // DelBytes deletes argument with the given key from query args.
  139. func (a *Args) DelBytes(key []byte) {
  140. a.args = delAllArgsStable(a.args, b2s(key))
  141. }
  142. // Add adds 'key=value' argument.
  143. //
  144. // Multiple values for the same key may be added.
  145. func (a *Args) Add(key, value string) {
  146. a.args = appendArg(a.args, key, value, argsHasValue)
  147. }
  148. // AddBytesK adds 'key=value' argument.
  149. //
  150. // Multiple values for the same key may be added.
  151. func (a *Args) AddBytesK(key []byte, value string) {
  152. a.args = appendArg(a.args, b2s(key), value, argsHasValue)
  153. }
  154. // AddBytesV adds 'key=value' argument.
  155. //
  156. // Multiple values for the same key may be added.
  157. func (a *Args) AddBytesV(key string, value []byte) {
  158. a.args = appendArg(a.args, key, b2s(value), argsHasValue)
  159. }
  160. // AddBytesKV adds 'key=value' argument.
  161. //
  162. // Multiple values for the same key may be added.
  163. func (a *Args) AddBytesKV(key, value []byte) {
  164. a.args = appendArg(a.args, b2s(key), b2s(value), argsHasValue)
  165. }
  166. // AddNoValue adds only 'key' as argument without the '='.
  167. //
  168. // Multiple values for the same key may be added.
  169. func (a *Args) AddNoValue(key string) {
  170. a.args = appendArg(a.args, key, "", argsNoValue)
  171. }
  172. // AddBytesKNoValue adds only 'key' as argument without the '='.
  173. //
  174. // Multiple values for the same key may be added.
  175. func (a *Args) AddBytesKNoValue(key []byte) {
  176. a.args = appendArg(a.args, b2s(key), "", argsNoValue)
  177. }
  178. // Set sets 'key=value' argument.
  179. func (a *Args) Set(key, value string) {
  180. a.args = setArg(a.args, key, value, argsHasValue)
  181. }
  182. // SetBytesK sets 'key=value' argument.
  183. func (a *Args) SetBytesK(key []byte, value string) {
  184. a.args = setArg(a.args, b2s(key), value, argsHasValue)
  185. }
  186. // SetBytesV sets 'key=value' argument.
  187. func (a *Args) SetBytesV(key string, value []byte) {
  188. a.args = setArg(a.args, key, b2s(value), argsHasValue)
  189. }
  190. // SetBytesKV sets 'key=value' argument.
  191. func (a *Args) SetBytesKV(key, value []byte) {
  192. a.args = setArgBytes(a.args, key, value, argsHasValue)
  193. }
  194. // SetNoValue sets only 'key' as argument without the '='.
  195. //
  196. // Only key in argument, like key1&key2.
  197. func (a *Args) SetNoValue(key string) {
  198. a.args = setArg(a.args, key, "", argsNoValue)
  199. }
  200. // SetBytesKNoValue sets 'key' argument.
  201. func (a *Args) SetBytesKNoValue(key []byte) {
  202. a.args = setArg(a.args, b2s(key), "", argsNoValue)
  203. }
  204. // Peek returns query arg value for the given key.
  205. //
  206. // The returned value is valid until the Args is reused or released (ReleaseArgs).
  207. // Do not store references to the returned value. Make copies instead.
  208. func (a *Args) Peek(key string) []byte {
  209. return peekArgStr(a.args, key)
  210. }
  211. // PeekBytes returns query arg value for the given key.
  212. //
  213. // The returned value is valid until the Args is reused or released (ReleaseArgs).
  214. // Do not store references to the returned value. Make copies instead.
  215. func (a *Args) PeekBytes(key []byte) []byte {
  216. return peekArgBytes(a.args, key)
  217. }
  218. // PeekMulti returns all the arg values for the given key.
  219. func (a *Args) PeekMulti(key string) [][]byte {
  220. var values [][]byte
  221. a.VisitAll(func(k, v []byte) {
  222. if string(k) == key {
  223. values = append(values, v)
  224. }
  225. })
  226. return values
  227. }
  228. // PeekMultiBytes returns all the arg values for the given key.
  229. func (a *Args) PeekMultiBytes(key []byte) [][]byte {
  230. return a.PeekMulti(b2s(key))
  231. }
  232. // Has returns true if the given key exists in Args.
  233. func (a *Args) Has(key string) bool {
  234. return hasArg(a.args, key)
  235. }
  236. // HasBytes returns true if the given key exists in Args.
  237. func (a *Args) HasBytes(key []byte) bool {
  238. return hasArg(a.args, b2s(key))
  239. }
  240. // ErrNoArgValue is returned when Args value with the given key is missing.
  241. var ErrNoArgValue = errors.New("no Args value for the given key")
  242. // GetUint returns uint value for the given key.
  243. func (a *Args) GetUint(key string) (int, error) {
  244. value := a.Peek(key)
  245. if len(value) == 0 {
  246. return -1, ErrNoArgValue
  247. }
  248. return ParseUint(value)
  249. }
  250. // SetUint sets uint value for the given key.
  251. func (a *Args) SetUint(key string, value int) {
  252. a.buf = AppendUint(a.buf[:0], value)
  253. a.SetBytesV(key, a.buf)
  254. }
  255. // SetUintBytes sets uint value for the given key.
  256. func (a *Args) SetUintBytes(key []byte, value int) {
  257. a.SetUint(b2s(key), value)
  258. }
  259. // GetUintOrZero returns uint value for the given key.
  260. //
  261. // Zero (0) is returned on error.
  262. func (a *Args) GetUintOrZero(key string) int {
  263. n, err := a.GetUint(key)
  264. if err != nil {
  265. n = 0
  266. }
  267. return n
  268. }
  269. // GetUfloat returns ufloat value for the given key.
  270. func (a *Args) GetUfloat(key string) (float64, error) {
  271. value := a.Peek(key)
  272. if len(value) == 0 {
  273. return -1, ErrNoArgValue
  274. }
  275. return ParseUfloat(value)
  276. }
  277. // GetUfloatOrZero returns ufloat value for the given key.
  278. //
  279. // Zero (0) is returned on error.
  280. func (a *Args) GetUfloatOrZero(key string) float64 {
  281. f, err := a.GetUfloat(key)
  282. if err != nil {
  283. f = 0
  284. }
  285. return f
  286. }
  287. // GetBool returns boolean value for the given key.
  288. //
  289. // true is returned for "1", "t", "T", "true", "TRUE", "True", "y", "yes", "Y", "YES", "Yes",
  290. // otherwise false is returned.
  291. func (a *Args) GetBool(key string) bool {
  292. switch string(a.Peek(key)) {
  293. // Support the same true cases as strconv.ParseBool
  294. // See: https://github.com/golang/go/blob/4e1b11e2c9bdb0ddea1141eed487be1a626ff5be/src/strconv/atob.go#L12
  295. // and Y and Yes versions.
  296. case "1", "t", "T", "true", "TRUE", "True", "y", "yes", "Y", "YES", "Yes":
  297. return true
  298. default:
  299. return false
  300. }
  301. }
  302. func visitArgs(args []argsKV, f func(k, v []byte)) {
  303. for i, n := 0, len(args); i < n; i++ {
  304. kv := &args[i]
  305. f(kv.key, kv.value)
  306. }
  307. }
  308. func copyArgs(dst, src []argsKV) []argsKV {
  309. if cap(dst) < len(src) {
  310. tmp := make([]argsKV, len(src))
  311. dstLen := len(dst)
  312. dst = dst[:cap(dst)] // copy all of dst.
  313. copy(tmp, dst)
  314. for i := dstLen; i < len(tmp); i++ {
  315. // Make sure nothing is nil.
  316. tmp[i].key = []byte{}
  317. tmp[i].value = []byte{}
  318. }
  319. dst = tmp
  320. }
  321. n := len(src)
  322. dst = dst[:n]
  323. for i := 0; i < n; i++ {
  324. dstKV := &dst[i]
  325. srcKV := &src[i]
  326. dstKV.key = append(dstKV.key[:0], srcKV.key...)
  327. if srcKV.noValue {
  328. dstKV.value = dstKV.value[:0]
  329. } else {
  330. dstKV.value = append(dstKV.value[:0], srcKV.value...)
  331. }
  332. dstKV.noValue = srcKV.noValue
  333. }
  334. return dst
  335. }
  336. func delAllArgsStable(args []argsKV, key string) []argsKV {
  337. for i, n := 0, len(args); i < n; i++ {
  338. kv := &args[i]
  339. if key == string(kv.key) {
  340. tmp := *kv
  341. copy(args[i:], args[i+1:])
  342. n--
  343. i--
  344. args[n] = tmp
  345. args = args[:n]
  346. }
  347. }
  348. return args
  349. }
  350. func delAllArgs(args []argsKV, key string) []argsKV {
  351. n := len(args)
  352. for i := 0; i < n; i++ {
  353. if key == string(args[i].key) {
  354. args[i], args[n-1] = args[n-1], args[i]
  355. n--
  356. i--
  357. }
  358. }
  359. return args[:n]
  360. }
  361. func setArgBytes(h []argsKV, key, value []byte, noValue bool) []argsKV {
  362. return setArg(h, b2s(key), b2s(value), noValue)
  363. }
  364. func setArg(h []argsKV, key, value string, noValue bool) []argsKV {
  365. n := len(h)
  366. for i := 0; i < n; i++ {
  367. kv := &h[i]
  368. if key == string(kv.key) {
  369. if noValue {
  370. kv.value = kv.value[:0]
  371. } else {
  372. kv.value = append(kv.value[:0], value...)
  373. }
  374. kv.noValue = noValue
  375. return h
  376. }
  377. }
  378. return appendArg(h, key, value, noValue)
  379. }
  380. func appendArgBytes(h []argsKV, key, value []byte, noValue bool) []argsKV {
  381. return appendArg(h, b2s(key), b2s(value), noValue)
  382. }
  383. func appendArg(args []argsKV, key, value string, noValue bool) []argsKV {
  384. var kv *argsKV
  385. args, kv = allocArg(args)
  386. kv.key = append(kv.key[:0], key...)
  387. if noValue {
  388. kv.value = kv.value[:0]
  389. } else {
  390. kv.value = append(kv.value[:0], value...)
  391. }
  392. kv.noValue = noValue
  393. return args
  394. }
  395. func allocArg(h []argsKV) ([]argsKV, *argsKV) {
  396. n := len(h)
  397. if cap(h) > n {
  398. h = h[:n+1]
  399. } else {
  400. h = append(h, argsKV{
  401. value: []byte{},
  402. })
  403. }
  404. return h, &h[n]
  405. }
  406. func releaseArg(h []argsKV) []argsKV {
  407. return h[:len(h)-1]
  408. }
  409. func hasArg(h []argsKV, key string) bool {
  410. for i, n := 0, len(h); i < n; i++ {
  411. kv := &h[i]
  412. if key == string(kv.key) {
  413. return true
  414. }
  415. }
  416. return false
  417. }
  418. func peekArgBytes(h []argsKV, k []byte) []byte {
  419. for i, n := 0, len(h); i < n; i++ {
  420. kv := &h[i]
  421. if bytes.Equal(kv.key, k) {
  422. return kv.value
  423. }
  424. }
  425. return nil
  426. }
  427. func peekArgStr(h []argsKV, k string) []byte {
  428. for i, n := 0, len(h); i < n; i++ {
  429. kv := &h[i]
  430. if string(kv.key) == k {
  431. return kv.value
  432. }
  433. }
  434. return nil
  435. }
  436. type argsScanner struct {
  437. b []byte
  438. }
  439. func (s *argsScanner) next(kv *argsKV) bool {
  440. if len(s.b) == 0 {
  441. return false
  442. }
  443. kv.noValue = argsHasValue
  444. isKey := true
  445. k := 0
  446. for i, c := range s.b {
  447. switch c {
  448. case '=':
  449. if isKey {
  450. isKey = false
  451. kv.key = decodeArgAppend(kv.key[:0], s.b[:i])
  452. k = i + 1
  453. }
  454. case '&':
  455. if isKey {
  456. kv.key = decodeArgAppend(kv.key[:0], s.b[:i])
  457. kv.value = kv.value[:0]
  458. kv.noValue = argsNoValue
  459. } else {
  460. kv.value = decodeArgAppend(kv.value[:0], s.b[k:i])
  461. }
  462. s.b = s.b[i+1:]
  463. return true
  464. }
  465. }
  466. if isKey {
  467. kv.key = decodeArgAppend(kv.key[:0], s.b)
  468. kv.value = kv.value[:0]
  469. kv.noValue = argsNoValue
  470. } else {
  471. kv.value = decodeArgAppend(kv.value[:0], s.b[k:])
  472. }
  473. s.b = s.b[len(s.b):]
  474. return true
  475. }
  476. func decodeArgAppend(dst, src []byte) []byte {
  477. idxPercent := bytes.IndexByte(src, '%')
  478. idxPlus := bytes.IndexByte(src, '+')
  479. if idxPercent == -1 && idxPlus == -1 {
  480. // fast path: src doesn't contain encoded chars
  481. return append(dst, src...)
  482. }
  483. var idx int
  484. switch {
  485. case idxPercent == -1:
  486. idx = idxPlus
  487. case idxPlus == -1:
  488. idx = idxPercent
  489. case idxPercent > idxPlus:
  490. idx = idxPlus
  491. default:
  492. idx = idxPercent
  493. }
  494. dst = append(dst, src[:idx]...)
  495. // slow path
  496. for i := idx; i < len(src); i++ {
  497. c := src[i]
  498. switch c {
  499. case '%':
  500. if i+2 >= len(src) {
  501. return append(dst, src[i:]...)
  502. }
  503. x2 := hex2intTable[src[i+2]]
  504. x1 := hex2intTable[src[i+1]]
  505. if x1 == 16 || x2 == 16 {
  506. dst = append(dst, '%')
  507. } else {
  508. dst = append(dst, x1<<4|x2)
  509. i += 2
  510. }
  511. case '+':
  512. dst = append(dst, ' ')
  513. default:
  514. dst = append(dst, c)
  515. }
  516. }
  517. return dst
  518. }
  519. // decodeArgAppendNoPlus is almost identical to decodeArgAppend, but it doesn't
  520. // substitute '+' with ' '.
  521. //
  522. // The function is copy-pasted from decodeArgAppend due to the performance
  523. // reasons only.
  524. func decodeArgAppendNoPlus(dst, src []byte) []byte {
  525. idx := bytes.IndexByte(src, '%')
  526. if idx < 0 {
  527. // fast path: src doesn't contain encoded chars
  528. return append(dst, src...)
  529. }
  530. dst = append(dst, src[:idx]...)
  531. // slow path
  532. for i := idx; i < len(src); i++ {
  533. c := src[i]
  534. if c == '%' {
  535. if i+2 >= len(src) {
  536. return append(dst, src[i:]...)
  537. }
  538. x2 := hex2intTable[src[i+2]]
  539. x1 := hex2intTable[src[i+1]]
  540. if x1 == 16 || x2 == 16 {
  541. dst = append(dst, '%')
  542. } else {
  543. dst = append(dst, x1<<4|x2)
  544. i += 2
  545. }
  546. } else {
  547. dst = append(dst, c)
  548. }
  549. }
  550. return dst
  551. }
  552. func peekAllArgBytesToDst(dst [][]byte, h []argsKV, k []byte) [][]byte {
  553. for i, n := 0, len(h); i < n; i++ {
  554. kv := &h[i]
  555. if bytes.Equal(kv.key, k) {
  556. dst = append(dst, kv.value)
  557. }
  558. }
  559. return dst
  560. }
  561. func peekArgsKeys(dst [][]byte, h []argsKV) [][]byte {
  562. for i, n := 0, len(h); i < n; i++ {
  563. kv := &h[i]
  564. dst = append(dst, kv.key)
  565. }
  566. return dst
  567. }