@@ -433,6 +433,14 @@ func CheckResponse(r *http.Response) error {
433433 return err
434434}
435435
436+ // queryParameterReplacements are values in a url, specifically the query
437+ // portion of the url, which should not be escaped before being sent to
438+ // Gerrit. Note, Gerrit itself does not escape these values when using the
439+ // search box so we shouldn't escape them either.
440+ var queryParameterReplacements = map [string ]string {
441+ "+" : "GOGERRIT_URL_PLACEHOLDER_PLUS" ,
442+ ":" : "GOGERRIT_URL_PLACEHOLDER_COLON" }
443+
436444// addOptions adds the parameters in opt as URL query parameters to s.
437445// opt must be a struct whose fields may contain "url" tags.
438446func addOptions (s string , opt interface {}) (string , error ) {
@@ -451,7 +459,37 @@ func addOptions(s string, opt interface{}) (string, error) {
451459 return s , err
452460 }
453461
454- u .RawQuery = qs .Encode ()
462+ // If the url contained one or more query parameters (q) then we need
463+ // to do some escaping on these values before Encode() is called. By
464+ // doing so we're ensuring that : and + don't get encoded which means
465+ // they'll be passed along to Gerrit as raw ascii. Without this Gerrit
466+ // could return 400 Bad Request depending on the query parameters. For
467+ // more complete information see this issue on GitHub:
468+ // https://github.com/andygrunwald/go-gerrit/issues/18
469+ _ , hasQuery := qs ["q" ]
470+ if hasQuery {
471+ values := []string {}
472+ for _ , value := range qs ["q" ] {
473+ for key , replacement := range queryParameterReplacements {
474+ value = strings .Replace (value , key , replacement , - 1 )
475+ }
476+ values = append (values , value )
477+ }
478+
479+ qs .Del ("q" )
480+ for _ , value := range values {
481+ qs .Add ("q" , value )
482+ }
483+ }
484+ encoded := qs .Encode ()
485+
486+ if hasQuery {
487+ for key , replacement := range queryParameterReplacements {
488+ encoded = strings .Replace (encoded , replacement , key , - 1 )
489+ }
490+ }
491+
492+ u .RawQuery = encoded
455493 return u .String (), nil
456494}
457495
0 commit comments