|
|
|
@ -5,9 +5,6 @@ use boolean qw(true);
|
|
|
|
|
use Data::HAL qw();
|
|
|
|
|
use Data::HAL::Link qw();
|
|
|
|
|
use Data::Record qw();
|
|
|
|
|
use DateTime::Format::HTTP qw();
|
|
|
|
|
use DateTime::Format::RFC3339 qw();
|
|
|
|
|
use Digest::SHA3 qw(sha3_256_base64);
|
|
|
|
|
use HTTP::Headers qw();
|
|
|
|
|
use HTTP::Headers::Util qw(split_header_words);
|
|
|
|
|
use HTTP::Status qw(:constants);
|
|
|
|
@ -15,11 +12,8 @@ use HTTP::Status qw(:constants);
|
|
|
|
|
use MooseX::ClassAttribute qw(class_has);
|
|
|
|
|
use NGCP::Panel::Form::Contact::Admin qw();
|
|
|
|
|
use NGCP::Panel::Form::Contact::Reseller qw();
|
|
|
|
|
use NGCP::Panel::ValidateJSON qw();
|
|
|
|
|
use Path::Tiny qw(path);
|
|
|
|
|
use Regexp::Common qw(delimited); # $RE{delimited}
|
|
|
|
|
use Safe::Isa qw($_isa);
|
|
|
|
|
use Types::Standard qw(InstanceOf);
|
|
|
|
|
BEGIN { extends 'Catalyst::Controller::ActionRole'; }
|
|
|
|
|
require Catalyst::ActionRole::ACL;
|
|
|
|
|
require Catalyst::ActionRole::CheckTrailingSlash;
|
|
|
|
@ -32,7 +26,6 @@ with 'NGCP::Panel::Role::API';
|
|
|
|
|
|
|
|
|
|
class_has('dispatch_path', is => 'ro', default => '/api/contacts/');
|
|
|
|
|
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-contacts');
|
|
|
|
|
has('last_modified', is => 'rw', isa => InstanceOf['DateTime']);
|
|
|
|
|
|
|
|
|
|
__PACKAGE__->config(
|
|
|
|
|
action => {
|
|
|
|
@ -170,42 +163,6 @@ sub allowed_methods : Private {
|
|
|
|
|
return [sort @allow];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub cached : Private {
|
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
|
my $response = $c->cache->get($c->request->uri->canonical->as_string);
|
|
|
|
|
unless ($response) {
|
|
|
|
|
$c->log->info('not cached');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
my $matched_tag = $c->request->header('If-None-Match') && ('*' eq $c->request->header('If-None-Match'))
|
|
|
|
|
|| (grep {$response->header('ETag') eq $_} Data::Record->new({
|
|
|
|
|
split => qr/\s*,\s*/, unless => $RE{delimited}{-delim => q(")},
|
|
|
|
|
})->records($c->request->header('If-None-Match')));
|
|
|
|
|
my $not_modified = $c->request->header('If-Modified-Since')
|
|
|
|
|
&& !($self->last_modified < DateTime::Format::HTTP->parse_datetime($c->request->header('If-Modified-Since')));
|
|
|
|
|
if (
|
|
|
|
|
$matched_tag && $not_modified
|
|
|
|
|
|| $matched_tag
|
|
|
|
|
|| $not_modified
|
|
|
|
|
) {
|
|
|
|
|
$c->response->status(HTTP_NOT_MODIFIED);
|
|
|
|
|
$c->response->headers($response->headers);
|
|
|
|
|
$c->log->info('cached');
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
$c->log->info('stale');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub etag : Private {
|
|
|
|
|
my ($self, $octets) = @_;
|
|
|
|
|
return sprintf '"ni:/sha3-256;%s"', sha3_256_base64($octets);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub expires : Private {
|
|
|
|
|
my ($self) = @_;
|
|
|
|
|
return DateTime->now->clone->add(years => 1); # XXX insert product end-of-life
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub hal_from_contact : Private {
|
|
|
|
|
my ($self, $contact) = @_;
|
|
|
|
|