387
|
1 |
<?php |
|
2 |
namespace CorpusParole\Libraries\Sparql; |
|
3 |
|
|
4 |
use EasyRdf\Sparql\Client; |
|
5 |
use EasyRdf\Exception; |
|
6 |
use EasyRdf\Format; |
|
7 |
use EasyRdf\Http; |
|
8 |
|
|
9 |
class TimeoutSparqlClient extends Client { |
|
10 |
|
|
11 |
public function query($query, $timeout=0) |
|
12 |
{ |
|
13 |
return $this->request('query', $query, $timeout); |
|
14 |
} |
|
15 |
|
|
16 |
protected function request($type, $query, $timeout=0) |
|
17 |
{ |
|
18 |
$processed_query = $this->preprocessQuery($query); |
|
19 |
$response = $this->executeQuery($processed_query, $type, $timeout); |
|
20 |
if (!$response->isSuccessful()) { |
|
21 |
throw new Http\Exception("HTTP request for SPARQL query failed", 0, null, $response->getBody()); |
|
22 |
} |
|
23 |
if ($response->getStatus() == 204) { |
|
24 |
// No content |
|
25 |
return $response; |
|
26 |
} |
|
27 |
return $this->parseResponseToQuery($response); |
|
28 |
} |
|
29 |
|
|
30 |
/** |
|
31 |
* Build http-client object, execute request and return a response |
|
32 |
* |
|
33 |
* @param string $processed_query |
|
34 |
* @param string $type Should be either "query" or "update" |
|
35 |
* |
|
36 |
* @return Http\Response|\Zend\Http\Response |
|
37 |
* @throws Exception |
|
38 |
*/ |
|
39 |
protected function executeQuery($processed_query, $type, $timeout=0) |
|
40 |
{ |
|
41 |
$client = Http::getDefaultHttpClient(); |
|
42 |
$client->resetParameters(); |
|
43 |
// Tell the server which response formats we can parse |
|
44 |
$sparql_results_types = array( |
|
45 |
'application/sparql-results+json' => 1.0, |
|
46 |
'application/sparql-results+xml' => 0.8 |
|
47 |
); |
|
48 |
if ($type == 'update') { |
|
49 |
// accept anything, as "response body of a […] update request is implementation defined" |
|
50 |
// @see http://www.w3.org/TR/sparql11-protocol/#update-success |
|
51 |
$accept = Format::getHttpAcceptHeader($sparql_results_types); |
|
52 |
$client->setHeaders('Accept', $accept); |
|
53 |
$client->setMethod('POST'); |
|
54 |
$client->setUri($this->updateUri); |
|
55 |
$client->setRawData($processed_query); |
|
56 |
$client->setHeaders('Content-Type', 'application/sparql-update'); |
|
57 |
} elseif ($type == 'query') { |
|
58 |
$re = '(?:(?:\s*BASE\s*<.*?>\s*)|(?:\s*PREFIX\s+.+:\s*<.*?>\s*))*'. |
|
59 |
'(CONSTRUCT|SELECT|ASK|DESCRIBE)[\W]'; |
|
60 |
$result = null; |
|
61 |
$matched = mb_eregi($re, $processed_query, $result); |
|
62 |
if (false === $matched or count($result) !== 2) { |
|
63 |
// non-standard query. is this something non-standard? |
|
64 |
$query_verb = null; |
|
65 |
} else { |
|
66 |
$query_verb = strtoupper($result[1]); |
|
67 |
} |
|
68 |
if ($query_verb === 'SELECT' or $query_verb === 'ASK') { |
|
69 |
// only "results" |
|
70 |
$accept = Format::formatAcceptHeader($sparql_results_types); |
|
71 |
} elseif ($query_verb === 'CONSTRUCT' or $query_verb === 'DESCRIBE') { |
|
72 |
// only "graph" |
|
73 |
$accept = Format::getHttpAcceptHeader(); |
|
74 |
} else { |
|
75 |
// both |
|
76 |
$accept = Format::getHttpAcceptHeader($sparql_results_types); |
|
77 |
} |
|
78 |
$client->setHeaders('Accept', $accept); |
|
79 |
$encodedQuery = 'query=' . urlencode($processed_query).(($timeout>0)?"&timeout=$timeout":""); |
|
80 |
// Use GET if the query is less than 2kB |
|
81 |
// 2046 = 2kB minus 1 for '?' and 1 for NULL-terminated string on server |
|
82 |
if (strlen($encodedQuery) + strlen($this->queryUri) <= 2046) { |
|
83 |
$delimiter = $this->queryUri_has_params ? '&' : '?'; |
|
84 |
$client->setMethod('GET'); |
|
85 |
$client->setUri($this->queryUri . $delimiter . $encodedQuery); |
|
86 |
} else { |
|
87 |
// Fall back to POST instead (which is un-cacheable) |
|
88 |
$client->setMethod('POST'); |
|
89 |
$client->setUri($this->queryUri); |
|
90 |
$client->setRawData($encodedQuery); |
|
91 |
$client->setHeaders('Content-Type', 'application/x-www-form-urlencoded'); |
|
92 |
} |
|
93 |
} else { |
|
94 |
throw new Exception('unexpected request-type: '.$type); |
|
95 |
} |
|
96 |
return $client->request(); |
|
97 |
} |
|
98 |
|
|
99 |
|
|
100 |
} |