MCPcopy
hub / github.com/caddyserver/caddy / buildQueryString

Function buildQueryString

modules/caddyhttp/rewrite/rewrite.go:336–396  ·  view source on GitHub ↗

buildQueryString takes an input query string and performs replacements on each component, returning the resulting query string. This function appends duplicate keys rather than replaces.

(qs string, repl *caddy.Replacer)

Source from the content-addressed store, hash-verified

334// the resulting query string. This function appends
335// duplicate keys rather than replaces.
336func buildQueryString(qs string, repl *caddy.Replacer) string {
337 var sb strings.Builder
338
339 // first component must be key, which is the same
340 // as if we just wrote a value in previous iteration
341 wroteVal := true
342
343 for len(qs) > 0 {
344 // determine the end of this component, which will be at
345 // the next equal sign or ampersand, whichever comes first
346 nextEq, nextAmp := strings.Index(qs, "="), strings.Index(qs, "&")
347 ampIsNext := nextAmp >= 0 && (nextAmp < nextEq || nextEq < 0)
348 end := len(qs) // assume no delimiter remains...
349 if ampIsNext {
350 end = nextAmp // ...unless ampersand is first...
351 } else if nextEq >= 0 && (nextEq < nextAmp || nextAmp < 0) {
352 end = nextEq // ...or unless equal is first.
353 }
354
355 // consume the component and write the result
356 comp := qs[:end]
357 comp, _ = repl.ReplaceFunc(comp, func(name string, val any) (any, error) {
358 if name == "http.request.uri.query" && wroteVal {
359 return val, nil // already escaped
360 }
361 var valStr string
362 switch v := val.(type) {
363 case string:
364 valStr = v
365 case fmt.Stringer:
366 valStr = v.String()
367 case int:
368 valStr = strconv.Itoa(v)
369 default:
370 valStr = fmt.Sprintf("%+v", v)
371 }
372 return url.QueryEscape(valStr), nil
373 })
374 if end < len(qs) {
375 end++ // consume delimiter
376 }
377 qs = qs[end:]
378
379 // if previous iteration wrote a value,
380 // that means we are writing a key
381 if wroteVal {
382 if sb.Len() > 0 && len(comp) > 0 {
383 sb.WriteRune('&')
384 }
385 } else {
386 sb.WriteRune('=')
387 }
388 sb.WriteString(comp)
389
390 // remember for the next iteration that we just wrote a value,
391 // which means the next iteration MUST write a key
392 wroteVal = ampIsNext
393 }

Callers 1

RewriteMethod · 0.85

Calls 3

ReplaceFuncMethod · 0.80
StringMethod · 0.45
LenMethod · 0.45

Tested by

no test coverage detected