From ae3093fa0de16ffd653f8c4c55e4311e9264ab08 Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Thu, 13 Nov 2014 18:08:08 +0000 Subject: Bug 1096565: backport bug 1088253 to bmo/4.2 to allow arbitrary URL params to be passed to REST API calls --- Bugzilla/WebService/Server/REST.pm | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'Bugzilla/WebService') diff --git a/Bugzilla/WebService/Server/REST.pm b/Bugzilla/WebService/Server/REST.pm index 69f97ef08..cee1e7a03 100644 --- a/Bugzilla/WebService/Server/REST.pm +++ b/Bugzilla/WebService/Server/REST.pm @@ -29,6 +29,7 @@ use Bugzilla::WebService::Server::REST::Resources::Product; use Bugzilla::WebService::Server::REST::Resources::User; use Bugzilla::WebService::Server::REST::Resources::BugUserLastVisit; +use List::MoreUtils qw(uniq); use Scalar::Util qw(blessed reftype); use MIME::Base64 qw(decode_base64); @@ -347,14 +348,34 @@ sub _retrieve_json_params { my $params = {}; %{$params} = %{ Bugzilla->input_params }; - # First add any params we were able to pull out of the path - # based on the resource regexp - %{$params} = (%{$params}, %{$self->bz_rest_params}) if $self->bz_rest_params; + # First add any parameters we were able to pull out of the path + # based on the resource regexp and combine with the normal URL + # parameters. + if (my $rest_params = $self->bz_rest_params) { + foreach my $param (keys %$rest_params) { + # If the param does not already exist or if the + # rest param is a single value, add it to the + # global params. + if (!exists $params->{$param} || !ref $rest_params->{$param}) { + $params->{$param} = $rest_params->{$param}; + } + # If rest_param is a list then add any extra values to the list + elsif (ref $rest_params->{$param}) { + my @extra_values = ref $params->{$param} + ? @{ $params->{$param} } + : ($params->{$param}); + $params->{$param} + = [ uniq (@{ $rest_params->{$param} }, @extra_values) ]; + } + } + } - # Merge any additional query key/values with $obj->{params} if not a GET request - # We do this manually cause CGI.pm doesn't understand JSON strings. + # Any parameters passed in in the body of a non-GET request will override + # any parameters pull from the url path. Otherwise non-unique keys are + # combined. if ($self->request->method ne 'GET') { my $extra_params = {}; + # We do this manually because CGI.pm doesn't understand JSON strings. my $json = delete $params->{'POSTDATA'} || delete $params->{'PUTDATA'}; if ($json) { eval { $extra_params = $self->json->utf8(0)->decode($json); }; @@ -363,9 +384,9 @@ sub _retrieve_json_params { } } - # Allow parameters in the query string if request was not GET. - # Note: query string parameters will override any matching params - # also specified in the request body. + # Allow parameters in the query string if request was non-GET. + # Note: parameters in query string body override any matching + # parameters in the request body. foreach my $param ($self->cgi->url_param()) { $extra_params->{$param} = $self->cgi->url_param($param); } -- cgit v1.2.3-24-g4f1b