From b5f9749d75aba8c00beada3a612bbdd57f8ffc58 Mon Sep 17 00:00:00 2001 From: Ben Menasha Date: Tue, 10 Nov 2015 14:25:26 -0500 Subject: [PATCH] use URI::Template to Level 2 RFC 6570 URI Template parameters. Some API discovery documents (like Cloud Pub/Sub API) use level 2 url parameters like "list": { "id": "pubsub.projects.topics.list", "path": "v1/{+project}/topics", "httpMethod": "GET", ... The {+project} parameter above implies "Reserved Expansion". To support it and other more complex URI parameters use the URI::Template per module. Additionally, was getting an error when a body was not supplied in a request that did not need a body, so check for that case. --- META.json | 4 ++-- cpanfile | 1 + lib/Google/API/Method.pm | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/META.json b/META.json index 29d2598..6c0594e 100644 --- a/META.json +++ b/META.json @@ -42,7 +42,8 @@ "JSON::WebToken" : "0", "LWP::Protocol::https" : "0", "URI" : "0", - "URI::Escape" : "0" + "URI::Escape" : "0", + "URI::Template" : "0" } }, "test" : { @@ -77,4 +78,3 @@ "shigeta " ] } - diff --git a/cpanfile b/cpanfile index dc8d2ba..e6de74a 100644 --- a/cpanfile +++ b/cpanfile @@ -1,5 +1,6 @@ requires 'URI'; requires 'URI::Escape'; +requires 'URI::Template'; requires 'HTTP::Request'; requires 'JSON'; requires 'JSON::WebToken'; diff --git a/lib/Google/API/Method.pm b/lib/Google/API/Method.pm index fba3c9b..44246c0 100644 --- a/lib/Google/API/Method.pm +++ b/lib/Google/API/Method.pm @@ -7,6 +7,7 @@ use Encode; use HTTP::Request; use URI; use URI::Escape qw/uri_escape/; +use URI::Template; sub new { my $class = shift; @@ -28,7 +29,12 @@ sub execute { $required_param{$p} = delete $self->{opt}{body}{$p}; } } - $url =~ s/{([^}]+)}/uri_escape(delete $required_param{$1})/eg; + my $template = URI::Template->new($url); + $url = $template->process( %required_param ); + # remove from required_param all variables in the url template (the path + # variables) + delete @required_param{$template->variables()}; + my $uri = URI->new($url); my $request; if ($http_method eq 'POST' || @@ -39,7 +45,7 @@ sub execute { $request = HTTP::Request->new($http_method => $uri); # Some API's (ie: admin/directoryv1/groups/delete) require requests # with an empty body section to be explicitly zero length. - if (%{$self->{opt}{body}}) { + if ($self->{opt}{body} && %{$self->{opt}{body}}) { $request->content_type('application/json'); $request->content($self->{json_parser}->encode($self->{opt}{body})); } else {