Compare commits
2 Commits
4730c577fa
...
7005e0852a
| Author | SHA1 | Date | |
|---|---|---|---|
| 7005e0852a | |||
| af5a924ae3 |
@@ -6,17 +6,18 @@ use Urupam::Utils qw(sanitize_input get_error_status sanitize_error_message);
|
|||||||
sub shorten {
|
sub shorten {
|
||||||
my $c = shift;
|
my $c = shift;
|
||||||
$c->render_later;
|
$c->render_later;
|
||||||
my $responded = 0;
|
|
||||||
my $url_service = $c->url_service;
|
my $url_service = $c->url_service;
|
||||||
my $validator = $c->validator;
|
my $validator = $c->validator;
|
||||||
|
|
||||||
my $json = $c->req->json;
|
my $json = $c->req->json;
|
||||||
unless ( defined $json && ref $json eq 'HASH' ) {
|
unless ( defined $json && ref $json eq 'HASH' ) {
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->render(
|
$c->render(
|
||||||
json => { error => 'Invalid JSON format' },
|
json => { error => 'Invalid JSON format' },
|
||||||
status => 400
|
status => 400
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -24,11 +25,13 @@ sub shorten {
|
|||||||
my $original_url = sanitize_input( $json->{url} || '' );
|
my $original_url = sanitize_input( $json->{url} || '' );
|
||||||
|
|
||||||
unless ($original_url) {
|
unless ($original_url) {
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->render(
|
$c->render(
|
||||||
json => { error => 'URL is required' },
|
json => { error => 'URL is required' },
|
||||||
status => 400
|
status => 400
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -43,29 +46,34 @@ sub shorten {
|
|||||||
)->then(
|
)->then(
|
||||||
sub {
|
sub {
|
||||||
my $short_code = shift;
|
my $short_code = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
my $short_url = $c->url_for("/$short_code")->to_abs;
|
my $short_url = $c->url_for("/$short_code")->to_abs;
|
||||||
$c->render(
|
$c->render(
|
||||||
json => {
|
json => {
|
||||||
success => 1,
|
success => 1,
|
||||||
short_url => $short_url,
|
short_url => $short_url,
|
||||||
short_code => $short_code,
|
short_code => $short_code,
|
||||||
original_url => $normalized_url
|
original_url => $normalized_url
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
sub {
|
sub {
|
||||||
my $err = shift;
|
my $err = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->app->log->error("API URL validation/creation error: $err");
|
$c->app->log->error(
|
||||||
my $status = get_error_status($err);
|
"API URL validation/creation error: $err");
|
||||||
my $sanitized_error = sanitize_error_message($err);
|
my $status = get_error_status($err);
|
||||||
$c->render(
|
my $sanitized_error = sanitize_error_message($err);
|
||||||
json => { error => $sanitized_error },
|
$c->render(
|
||||||
status => $status
|
json => { error => $sanitized_error },
|
||||||
|
status => $status
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -74,17 +82,18 @@ sub shorten {
|
|||||||
sub get_url {
|
sub get_url {
|
||||||
my $c = shift;
|
my $c = shift;
|
||||||
$c->render_later;
|
$c->render_later;
|
||||||
my $responded = 0;
|
|
||||||
my $short_code = $c->param('short_code') // '';
|
my $short_code = $c->param('short_code') // '';
|
||||||
my $url_service = $c->url_service;
|
my $url_service = $c->url_service;
|
||||||
my $validator = $c->validator;
|
my $validator = $c->validator;
|
||||||
|
|
||||||
unless ( $short_code && $validator->validate_short_code($short_code) ) {
|
unless ( $short_code && $validator->validate_short_code($short_code) ) {
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->render(
|
$c->render(
|
||||||
json => { error => 'Invalid short code format' },
|
json => { error => 'Invalid short code format' },
|
||||||
status => 400
|
status => 400
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -92,37 +101,41 @@ sub get_url {
|
|||||||
return $url_service->get_original_url($short_code)->then(
|
return $url_service->get_original_url($short_code)->then(
|
||||||
sub {
|
sub {
|
||||||
my $original_url = shift;
|
my $original_url = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
if ($original_url) {
|
if ($original_url) {
|
||||||
my $short_url = $c->url_for("/$short_code")->to_abs;
|
my $short_url = $c->url_for("/$short_code")->to_abs;
|
||||||
$c->render(
|
$c->render(
|
||||||
json => {
|
json => {
|
||||||
success => 1,
|
success => 1,
|
||||||
short_code => $short_code,
|
short_code => $short_code,
|
||||||
original_url => $original_url,
|
original_url => $original_url,
|
||||||
short_url => $short_url
|
short_url => $short_url
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
else {
|
||||||
}
|
$c->render(
|
||||||
else {
|
json => { error => 'Short code not found' },
|
||||||
$c->render(
|
status => 404
|
||||||
json => { error => 'Short code not found' },
|
);
|
||||||
status => 404
|
}
|
||||||
);
|
}
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
sub {
|
sub {
|
||||||
my $err = shift;
|
my $err = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->app->log->error("API URL retrieval error: $err");
|
$c->app->log->error("API URL retrieval error: $err");
|
||||||
my $status = get_error_status($err);
|
my $status = get_error_status($err);
|
||||||
my $sanitized_error = sanitize_error_message($err);
|
my $sanitized_error = sanitize_error_message($err);
|
||||||
$c->render(
|
$c->render(
|
||||||
json => { error => $sanitized_error },
|
json => { error => $sanitized_error },
|
||||||
status => $status
|
status => $status
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -37,36 +37,48 @@ sub startup {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
respond_once => sub {
|
||||||
|
my $c = shift;
|
||||||
|
my $callback = shift;
|
||||||
|
return if $c->rendered;
|
||||||
|
$callback->($c);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
my $r = $self->routes;
|
my $r = $self->routes;
|
||||||
|
|
||||||
$r->get('/health')->to(
|
$r->get('/health')->to(
|
||||||
cb => sub {
|
cb => sub {
|
||||||
my $c = shift;
|
my $c = shift;
|
||||||
$c->render_later;
|
$c->render_later;
|
||||||
my $responded = 0;
|
|
||||||
$c->db->ping->then(
|
$c->db->ping->then(
|
||||||
sub {
|
sub {
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->render(
|
$c->render(
|
||||||
json => {
|
json => {
|
||||||
status => 'ok',
|
status => 'ok',
|
||||||
version => $c->version
|
version => $c->version
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
sub {
|
sub {
|
||||||
my $err = shift;
|
my $err = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->app->log->error("Health check DB error: $err");
|
$c->app->log->error("Health check DB error: $err");
|
||||||
$c->render(
|
$c->render(
|
||||||
json => {
|
json => {
|
||||||
status => 'error',
|
status => 'error',
|
||||||
error => 'Database connection failed'
|
error => 'Database connection failed'
|
||||||
},
|
},
|
||||||
status => 503
|
status => 503
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -99,7 +111,6 @@ sub startup {
|
|||||||
cb => sub {
|
cb => sub {
|
||||||
my $c = shift;
|
my $c = shift;
|
||||||
$c->render_later;
|
$c->render_later;
|
||||||
my $responded = 0;
|
|
||||||
my $short_code = $c->param('short_code') // '';
|
my $short_code = $c->param('short_code') // '';
|
||||||
my $url_service = $c->url_service;
|
my $url_service = $c->url_service;
|
||||||
my $validator = $c->validator;
|
my $validator = $c->validator;
|
||||||
@@ -107,11 +118,13 @@ sub startup {
|
|||||||
unless ( $short_code
|
unless ( $short_code
|
||||||
&& $validator->validate_short_code($short_code) )
|
&& $validator->validate_short_code($short_code) )
|
||||||
{
|
{
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->render(
|
$c->render(
|
||||||
template => '404',
|
template => '404',
|
||||||
status => 404
|
status => 404
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -119,27 +132,31 @@ sub startup {
|
|||||||
return $url_service->get_original_url($short_code)->then(
|
return $url_service->get_original_url($short_code)->then(
|
||||||
sub {
|
sub {
|
||||||
my $original_url = shift;
|
my $original_url = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
if ($original_url) {
|
if ($original_url) {
|
||||||
$c->redirect_to($original_url);
|
$c->redirect_to($original_url);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$c->render(
|
$c->render(
|
||||||
template => '404',
|
template => '404',
|
||||||
status => 404
|
status => 404
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
sub {
|
sub {
|
||||||
my $err = shift;
|
my $err = shift;
|
||||||
return if $responded;
|
$c->respond_once(
|
||||||
$responded = 1;
|
sub {
|
||||||
$c->app->log->error("Redirect lookup error: $err");
|
$c->app->log->error("Redirect lookup error: $err");
|
||||||
$c->render(
|
$c->render(
|
||||||
template => '500',
|
template => '500',
|
||||||
status => 500
|
status => 500
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user