--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/app/Libraries/Sparql/TimeoutSparqlClient.php Thu Nov 03 01:52:26 2016 +0100
@@ -0,0 +1,100 @@
+<?php
+namespace CorpusParole\Libraries\Sparql;
+
+use EasyRdf\Sparql\Client;
+use EasyRdf\Exception;
+use EasyRdf\Format;
+use EasyRdf\Http;
+
+class TimeoutSparqlClient extends Client {
+
+ public function query($query, $timeout=0)
+ {
+ return $this->request('query', $query, $timeout);
+ }
+
+ protected function request($type, $query, $timeout=0)
+ {
+ $processed_query = $this->preprocessQuery($query);
+ $response = $this->executeQuery($processed_query, $type, $timeout);
+ if (!$response->isSuccessful()) {
+ throw new Http\Exception("HTTP request for SPARQL query failed", 0, null, $response->getBody());
+ }
+ if ($response->getStatus() == 204) {
+ // No content
+ return $response;
+ }
+ return $this->parseResponseToQuery($response);
+ }
+
+ /**
+ * Build http-client object, execute request and return a response
+ *
+ * @param string $processed_query
+ * @param string $type Should be either "query" or "update"
+ *
+ * @return Http\Response|\Zend\Http\Response
+ * @throws Exception
+ */
+ protected function executeQuery($processed_query, $type, $timeout=0)
+ {
+ $client = Http::getDefaultHttpClient();
+ $client->resetParameters();
+ // Tell the server which response formats we can parse
+ $sparql_results_types = array(
+ 'application/sparql-results+json' => 1.0,
+ 'application/sparql-results+xml' => 0.8
+ );
+ if ($type == 'update') {
+ // accept anything, as "response body of a […] update request is implementation defined"
+ // @see http://www.w3.org/TR/sparql11-protocol/#update-success
+ $accept = Format::getHttpAcceptHeader($sparql_results_types);
+ $client->setHeaders('Accept', $accept);
+ $client->setMethod('POST');
+ $client->setUri($this->updateUri);
+ $client->setRawData($processed_query);
+ $client->setHeaders('Content-Type', 'application/sparql-update');
+ } elseif ($type == 'query') {
+ $re = '(?:(?:\s*BASE\s*<.*?>\s*)|(?:\s*PREFIX\s+.+:\s*<.*?>\s*))*'.
+ '(CONSTRUCT|SELECT|ASK|DESCRIBE)[\W]';
+ $result = null;
+ $matched = mb_eregi($re, $processed_query, $result);
+ if (false === $matched or count($result) !== 2) {
+ // non-standard query. is this something non-standard?
+ $query_verb = null;
+ } else {
+ $query_verb = strtoupper($result[1]);
+ }
+ if ($query_verb === 'SELECT' or $query_verb === 'ASK') {
+ // only "results"
+ $accept = Format::formatAcceptHeader($sparql_results_types);
+ } elseif ($query_verb === 'CONSTRUCT' or $query_verb === 'DESCRIBE') {
+ // only "graph"
+ $accept = Format::getHttpAcceptHeader();
+ } else {
+ // both
+ $accept = Format::getHttpAcceptHeader($sparql_results_types);
+ }
+ $client->setHeaders('Accept', $accept);
+ $encodedQuery = 'query=' . urlencode($processed_query).(($timeout>0)?"&timeout=$timeout":"");
+ // Use GET if the query is less than 2kB
+ // 2046 = 2kB minus 1 for '?' and 1 for NULL-terminated string on server
+ if (strlen($encodedQuery) + strlen($this->queryUri) <= 2046) {
+ $delimiter = $this->queryUri_has_params ? '&' : '?';
+ $client->setMethod('GET');
+ $client->setUri($this->queryUri . $delimiter . $encodedQuery);
+ } else {
+ // Fall back to POST instead (which is un-cacheable)
+ $client->setMethod('POST');
+ $client->setUri($this->queryUri);
+ $client->setRawData($encodedQuery);
+ $client->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
+ }
+ } else {
+ throw new Exception('unexpected request-type: '.$type);
+ }
+ return $client->request();
+ }
+
+
+}