AtteanX-Endpoint

 view release on metacpan or  search on metacpan

lib/AtteanX/Endpoint.pm  view on Meta::CPAN

			my $status	= $e->message;
			my $error	= {
				title		=> $status,
				describedby	=> $e->uri,
			};
			if (my $d = $e->details) {
				$error->{details}		= $d;
			}
			my @variants	= (
				['text/plain', 0.98, 'text/plain'],
				['application/json-problem', 0.99, 'application/json-problem'],
			);
			my $headers	= $req->headers;
			my $stype	= choose( \@variants, $headers ) || 'text/plain';
			if ($stype eq 'application/json-problem') {
				$resp->headers->content_type( 'application/json-problem' );
				$resp->status($code);
				my $content	= encode_json($error);
				$resp->body($content);
			} else {
				$resp->headers->content_type( 'text/plain' );
				$resp->status($code);
				my @messages	= grep { defined($_) } @{ $error }{ qw(title detail) };
				my $content		= join("\n\n", $status, @messages);
				$resp->body($content);
			}
			return $resp;
		}
	}
	
	sub _run {
		my $self	= shift;
		my $req		= shift;
		
		my $config	= $self->{conf};
		my $endpoint_path = $config->{endpoint}{endpoint_path} || '/sparql';
		my $gsp_path = $config->{endpoint}{gsp_path} || '/gsp';
		
		my $response	= Plack::Response->new;

		our $VERSION;
		my $server = "AtteanX::Endpoint/$VERSION";
		$server .= " " . $response->headers->header('Server') if defined($response->headers->header('Server'));
		$response->headers->header('Server' => $server);

		if ($req->path eq $endpoint_path or $req->path eq $gsp_path) {
			# no-op
		} else {
			my $content;
			my $path	= $req->path_info;
			$path		=~ s#^/##;
			my $dir		= $ENV{ATTEAN_ENDPOINT_SHAREDIR} || File::Spec->catdir((eval { dist_dir('AtteanX-Endpoint') } || 'share'), 'endpoint');
			my $abs		= File::Spec->rel2abs($dir);
			my $file	= File::Spec->catfile($abs, 'www', $path);
			if (-r $file) {
				open( my $fh, '<', $file ) or croak $!;
				$response->status(200);
				$content	= $fh;
			} else {
				my $path	= $req->path;
				$response->status(404);
				$content	= <<"END";
	<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n
	<h1>Not Found</h1>\n<p>The requested URL $path was not found on this server.</p>\n</body></html>
END
			}
			$response->body($content);
			return $response;
		}
	
		if ($req->path eq $endpoint_path) {
			$self->_run_protocol($req, $response);
		} else {
			$self->_run_gsp($req, $response);
		}
	}

	sub get_gsp_graph {
		my $self	= shift;
		my $req		= shift;
		my $query     = $req->parameters;
		if ($req->query_string eq 'default') {
			my $default	= $self->graph;
			return $default;
		} elsif (my $g = $req->param('graph')) {
			return iri($g);
		}
		return;
	}
	
	sub _run_gsp {
		my $self	= shift;
		my $req		= shift;
		my $response	= shift;

		my $config	= $self->{conf};
		my $model	= $self->{model};
		my $headers	= $req->headers;
		my $type	= $headers->header('Accept') || 'application/sparql-results+xml';
		if (my $t = $req->param('media-type')) {
			$type	= $t;
			$headers->header('Accept' => $type);
		}

		my $ae		= $req->headers->header('Accept-Encoding') || '';
		my $graph	= $self->get_gsp_graph($req); # TODO
		unless ($graph) {
			die AtteanX::Endpoint::ClientError->new(
				code => 400,
				message => 'No graph specified', uri => 'http://id.kasei.us/rdf-endpoint/error/gsp_no_graph'
			);
		}
		my $base	= $req->base;
		my $parser	= Attean->get_parser('SPARQL')->new(base => $base);
		my $algebra;
		my $content;
		if ($req->method eq 'GET' or $req->method eq 'HEAD') {
			my $sparql		= 'CONSTRUCT WHERE { ?s ?p ?o }';
			($algebra)	= eval { $parser->parse($sparql, base => $base) };
			$self->log_gsp_request( $req );
			if ($@ or not($algebra)) {
				my $error	= $@ || 'Internal error';
				$self->log_error( $req, $error );



( run in 0.795 second using v1.01-cache-2.11-cpan-788537b7465 )