url_is_valid         = (fun _ -> true);
 }
 
-  (** given a list of length 2
-  @return a pair formed by the elements of the list
-  @raise Assert_failure if the list length isn't 2
-  *)
-let pair_of_2_sized_list = function
-  | [a;b] -> (a,b)
-  | _ -> assert false
-
   (** given an HTTP like query string (e.g. "name1=value1&name2=value2&...")
   @return a list of pairs [("name1", "value1"); ("name2", "value2")]
   @raise Malformed_query if the string isn't a valid query string
   *)
 let split_query_params =
   let (bindings_sep, binding_sep) = (Pcre.regexp "&", Pcre.regexp "=") in
+  let http_decode url = Netencoding.Url.decode ~plus:false url in
   fun ~query ->
     let bindings = Pcre.split ~rex:bindings_sep query in
     if List.length bindings < 1 then
         let pieces = Pcre.split ~rex:binding_sep binding in
         if List.length pieces <> 2 then
           raise (Malformed_query_binding (binding, query));
-        pair_of_2_sized_list pieces)
+        (match pieces with
+        | [a; b] -> (http_decode a, http_decode b)
+        | _ -> assert false))
       bindings
 
   (** given an input channel and a separator
           patch_empty_path (String.concat "/" (url_path request_uri))
         in
         let query_params =
-          try split_query_params (url_query request_uri) with Not_found -> []
+          try (* act on HTTP encoded URIs *)
+            split_query_params (url_query ~encoded:true request_uri)
+          with Not_found -> []
         in
         Http_common.debug_print
           (sprintf