App-DuckPAN
view release on metacpan or search on metacpan
lib/App/DuckPAN/Web.pm view on Meta::CPAN
my $response = $self->request($app, $request);
return $response->finalize;
}
my $has_common_js = 0;
sub request {
my ( $self, $app, $request ) = @_;
my $hostname = $self->server_hostname;
my @path_parts = split(/\/+/,$request->request_uri);
shift @path_parts;
my $response = Plack::Response->new(200);
my $body;
if ($request->request_uri eq "/"){
$response->content_type("text/html");
$body = $self->page_root;
}
elsif (@path_parts && $path_parts[0] eq 'share') {
my $share_dir;
for (keys %{$self->_share_dir_hash}) {
if ($request->path =~ m|^/$_/|g) {
$share_dir = $_;
# Get filename from path and url unescape
my $filename = uri_unescape( pop @path_parts );
# Trim path from left to right to find parent dir of filename
# e.g /share/goodie/foo/foo_imgs/image.png -> "foo_imgs"
my $remainder = $request->path_info;
$remainder =~ s|$share_dir||;
$remainder =~ s|$filename||;
$remainder =~ s|//|/|;
$remainder =~ s|^/\d{3,4}||;
# if valid remainder exists, prepend to filename
$filename = "$remainder$filename" if $remainder ne $filename;
if (my $filename_path = $self->_share_dir_hash->{$share_dir}->can('share')->($filename)) {
my $content_type = Plack::MIME->mime_type($filename);
$response->content_type($content_type);
if ($filename =~ /\.js$/ && $has_common_js &&
$request->path =~ /(share\/spice\/([^\/]+)\/?)(.*)/){
my $parent_dir = $1;
my $parent_name = $2;
my $common_js = $parent_dir."$parent_name.js";
$body = path($common_js)->slurp;
print "\nAppended $common_js to $filename\n\n";
}
$body .= path($filename_path)->slurp;
}
else {
$share_dir = undef;
}
}
}
unless ($share_dir){
$response->status(404);
my $path = join "/", @path_parts;
my $errormsg = "ERROR: File not found - $path";
print "\n" . $errormsg . "\n";
$body = $errormsg;
}
}
elsif (@path_parts && $path_parts[0] eq 'js' && $path_parts[1] eq 'spice') {
my $rewrite;
for (keys %{$self->_path_hash}) {
if ($request->request_uri =~ m/^$_/g) {
my $path_remainder = $request->request_uri;
$path_remainder =~ s/^$_//;
$path_remainder =~ s/\/+/\//g;
$path_remainder =~ s/^\///;
my $spice_class = $self->_path_hash->{$_};
$rewrite = $self->_rewrite_hash->{$spice_class};
die "Spice tested here must have a rewrite..." unless $rewrite;
my $from = $rewrite->from;
my $re = $rewrite->has_from ? qr{$from} : qr{(.*)};
if (my @captures = $path_remainder =~ m/$re/) {
my $to = $rewrite->parsed_to;
my $post_body = $rewrite->post_body;
for (1..@captures) {
my $index = $_-1;
my $cap_from = '\$'.$_;
my $cap_to = $captures[$index];
if (defined $cap_to) {
$to =~ s/$cap_from/$cap_to/g;
$post_body =~ s/$cap_from/$cap_to/g if $post_body;
}
else {
$to =~ s/$cap_from//g;
$post_body =~ s/$cap_from//g;
}
}
# Make sure we replace "${dollar}" with "$".
$to =~ s/\$\{dollar\}/\$/g;
my ($wrap_jsonp_callback, $callback, $wrap_string_callback, $missing_envs, $headers) =
($rewrite->wrap_jsonp_callback, $rewrite->callback, $rewrite->wrap_string_callback, defined($rewrite->missing_envs), $rewrite->headers);
# Check if environment variables (most likely the API key) is missing.
# If it is missing, switch to the DDG endpoint.
my ($use_ddh, $request_uri);
if ($missing_envs) {
++$use_ddh;
$request_uri = $request->request_uri;
# Display the URL that we used.
print "\nAPI key not found. Using DuckDuckGo's endpoint:\n";
}
$to = "https://beta.duckduckgo.com$request_uri" if $use_ddh;
my $h = HTTP::Headers->new( %$headers );
my $res;
my $req;
if ( $post_body && !$use_ddh ) {
$req = HTTP::Request->new(
POST => $to,
$h,
$post_body
);
}
else {
$req = HTTP::Request->new(
GET => $to,
$h
);
}
p($req->as_string);
$res = $self->ua->request($req);
if ($res->is_success) {
$body = $res->decoded_content;
# Encode utf8 api_responses to bytestream for Plack.
utf8::encode $body if utf8::is_utf8 $body;
warn "Cannot use wrap_jsonp_callback and wrap_string callback at the same time!" if $wrap_jsonp_callback && $wrap_string_callback;
if ($wrap_jsonp_callback && $callback) {
$body = $callback.'('.$body.');' unless $missing_envs;
}
elsif ($wrap_string_callback && $callback) {
$body =~ s/"/\\"/g;
$body =~ s/\n/\\n/g;
$body =~ s/\R//g;
$body = qq{$callback("'.$body.'");} unless $missing_envs;
}
$response->code($res->code);
$response->content_type($res->content_type);
}
else {
p($res->status_line, color => { string => 'red' });
my $errormsg = (pop @{[split'::', $spice_class]}). ": ".$res->status_line;
$body = '$("#message").removeClass("is-hidden").append("<div class=\"msg msg--warning\">'. $errormsg .'</div>");';
}
}
}
}
unless ($rewrite){
$response->status(404);
my $path = join "/", @path_parts;
my $errormsg = "ERROR: Rewrite not found - $path";
print "\n" . $errormsg . "\n";
$body = $errormsg;
}
}
elsif ($request->param('duckduckhack_ignore')) {
$response->status(204);
$body = "";
}
elsif ($request->param('duckduckhack_css')) {
$response->content_type('text/css');
$body = $self->page_css;
}
elsif ($request->param('duckduckhack_js')) {
$response->content_type('text/javascript');
$body = $self->page_js;
}
elsif ($request->param('duckduckhack_locales')) {
$response->content_type('text/javascript');
$body = $self->page_locales;
}
elsif ($request->param('duckduckhack_templates')) {
$response->content_type('text/javascript');
$body = $self->page_templates;
}
elsif ($request->param('q') && $request->path_info eq '/') {
my $query = $request->param('q');
$query =~ s/^\s+|\s+$//g; # strip leading & trailing whitespace
Encode::_utf8_on($query);
my $ddg_request = DDG::Request->new(
query_raw => $query,
location => test_location_by_env(),
language => test_language_by_env(),
);
my @results = ();
my @calls_nrj = ();
my @calls_nrc = ();
my @calls_script = ();
my %calls_template = ();
my @calls_goodie;
my @calls_fathead;
my @ids;
my $page = $self->page_spice;
my $uri_encoded_query = uri_escape_utf8($query, "^A-Za-z");
my $html_encoded_query = encode_entities($query);
my $uri_encoded_ddh = quotemeta(uri_escape('duckduckhack-template-for-spice2', "^A-Za-z0-9"));
$page =~ s/duckduckhack-template-for-spice2/$html_encoded_query/g;
$page =~ s/$uri_encoded_ddh/$uri_encoded_query/g;
# For debugging query replacement.
#p($uri_encoded_ddh);
#p($page);
my $root = HTML::TreeBuilder->new;
$root->parse($page);
( run in 1.772 second using v1.01-cache-2.11-cpan-39bf76dae61 )