Makes server SPARQL protocol pass the test suite

pull/71/head
Tpt 4 years ago
parent 00ec99450a
commit 6edd9149ba
  1. 77
      server/src/main.rs

@ -15,7 +15,9 @@ use async_std::io::Read;
use async_std::net::{TcpListener, TcpStream}; use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*; use async_std::prelude::*;
use async_std::task::{block_on, spawn}; use async_std::task::{block_on, spawn};
use http_types::{headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode}; use http_types::{
bail_status, headers, Body, Error, Method, Mime, Request, Response, Result, StatusCode,
};
use oxigraph::io::{DatasetFormat, GraphFormat}; use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::{GraphName, NamedNode, NamedOrBlankNode}; use oxigraph::model::{GraphName, NamedNode, NamedOrBlankNode};
use oxigraph::sparql::algebra::GraphUpdateOperation; use oxigraph::sparql::algebra::GraphUpdateOperation;
@ -99,12 +101,7 @@ async fn handle_request(request: Request, store: Store) -> Result<Response> {
} }
} }
("/query", Method::Get) => { ("/query", Method::Get) => {
evaluate_urlencoded_sparql_query( configure_and_evaluate_sparql_query(store, url_query(&request), None, request)?
store,
request.url().query().unwrap_or("").as_bytes().to_vec(),
request,
)
.await?
} }
("/query", Method::Post) => { ("/query", Method::Post) => {
if let Some(content_type) = request.content_type() { if let Some(content_type) = request.content_type() {
@ -116,7 +113,12 @@ async fn handle_request(request: Request, store: Store) -> Result<Response> {
.take(MAX_SPARQL_BODY_SIZE) .take(MAX_SPARQL_BODY_SIZE)
.read_to_string(&mut buffer) .read_to_string(&mut buffer)
.await?; .await?;
evaluate_sparql_query(store, buffer, Vec::new(), Vec::new(), request).await? configure_and_evaluate_sparql_query(
store,
url_query(&request),
Some(buffer),
request,
)?
} else if content_type.essence() == "application/x-www-form-urlencoded" { } else if content_type.essence() == "application/x-www-form-urlencoded" {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let mut request = request; let mut request = request;
@ -125,7 +127,7 @@ async fn handle_request(request: Request, store: Store) -> Result<Response> {
.take(MAX_SPARQL_BODY_SIZE) .take(MAX_SPARQL_BODY_SIZE)
.read_to_end(&mut buffer) .read_to_end(&mut buffer)
.await?; .await?;
evaluate_urlencoded_sparql_query(store, buffer, request).await? configure_and_evaluate_sparql_query(store, buffer, None, request)?
} else { } else {
simple_response( simple_response(
StatusCode::UnsupportedMediaType, StatusCode::UnsupportedMediaType,
@ -146,7 +148,12 @@ async fn handle_request(request: Request, store: Store) -> Result<Response> {
.take(MAX_SPARQL_BODY_SIZE) .take(MAX_SPARQL_BODY_SIZE)
.read_to_string(&mut buffer) .read_to_string(&mut buffer)
.await?; .await?;
evaluate_sparql_update(store, buffer, Vec::new(), Vec::new()).await? configure_and_evaluate_sparql_update(
store,
url_query(&request),
Some(buffer),
request,
)?
} else if content_type.essence() == "application/x-www-form-urlencoded" { } else if content_type.essence() == "application/x-www-form-urlencoded" {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let mut request = request; let mut request = request;
@ -155,7 +162,7 @@ async fn handle_request(request: Request, store: Store) -> Result<Response> {
.take(MAX_SPARQL_BODY_SIZE) .take(MAX_SPARQL_BODY_SIZE)
.read_to_end(&mut buffer) .read_to_end(&mut buffer)
.await?; .await?;
evaluate_urlencoded_sparql_update(store, buffer).await? configure_and_evaluate_sparql_update(store, buffer, None, request)?
} else { } else {
simple_response( simple_response(
StatusCode::UnsupportedMediaType, StatusCode::UnsupportedMediaType,
@ -178,17 +185,31 @@ fn simple_response(status: StatusCode, body: impl Into<Body>) -> Response {
response response
} }
async fn evaluate_urlencoded_sparql_query( fn base_url(request: &Request) -> &str {
let url = request.url().as_str();
url.split('?').next().unwrap_or(url)
}
fn url_query(request: &Request) -> Vec<u8> {
request.url().query().unwrap_or("").as_bytes().to_vec()
}
fn configure_and_evaluate_sparql_query(
store: Store, store: Store,
encoded: Vec<u8>, encoded: Vec<u8>,
mut query: Option<String>,
request: Request, request: Request,
) -> Result<Response> { ) -> Result<Response> {
let mut query = None;
let mut default_graph_uris = Vec::new(); let mut default_graph_uris = Vec::new();
let mut named_graph_uris = Vec::new(); let mut named_graph_uris = Vec::new();
for (k, v) in form_urlencoded::parse(&encoded) { for (k, v) in form_urlencoded::parse(&encoded) {
match k.as_ref() { match k.as_ref() {
"query" => query = Some(v.into_owned()), "query" => {
if query.is_some() {
bail_status!(400, "Multiple query parameters provided")
}
query = Some(v.into_owned())
}
"default-graph-uri" => default_graph_uris.push(v.into_owned()), "default-graph-uri" => default_graph_uris.push(v.into_owned()),
"named-graph-uri" => named_graph_uris.push(v.into_owned()), "named-graph-uri" => named_graph_uris.push(v.into_owned()),
_ => { _ => {
@ -200,7 +221,7 @@ async fn evaluate_urlencoded_sparql_query(
} }
} }
if let Some(query) = query { if let Some(query) = query {
evaluate_sparql_query(store, query, default_graph_uris, named_graph_uris, request).await evaluate_sparql_query(store, query, default_graph_uris, named_graph_uris, request)
} else { } else {
Ok(simple_response( Ok(simple_response(
StatusCode::BadRequest, StatusCode::BadRequest,
@ -209,14 +230,14 @@ async fn evaluate_urlencoded_sparql_query(
} }
} }
async fn evaluate_sparql_query( fn evaluate_sparql_query(
store: Store, store: Store,
query: String, query: String,
default_graph_uris: Vec<String>, default_graph_uris: Vec<String>,
named_graph_uris: Vec<String>, named_graph_uris: Vec<String>,
request: Request, request: Request,
) -> Result<Response> { ) -> Result<Response> {
let mut query = Query::parse(&query, None).map_err(bad_request)?; let mut query = Query::parse(&query, Some(base_url(&request))).map_err(bad_request)?;
let default_graph_uris = default_graph_uris let default_graph_uris = default_graph_uris
.into_iter() .into_iter()
.map(|e| Ok(NamedNode::new(e)?.into())) .map(|e| Ok(NamedNode::new(e)?.into()))
@ -271,13 +292,22 @@ async fn evaluate_sparql_query(
} }
} }
async fn evaluate_urlencoded_sparql_update(store: Store, encoded: Vec<u8>) -> Result<Response> { fn configure_and_evaluate_sparql_update(
let mut update = None; store: Store,
encoded: Vec<u8>,
mut update: Option<String>,
request: Request,
) -> Result<Response> {
let mut default_graph_uris = Vec::new(); let mut default_graph_uris = Vec::new();
let mut named_graph_uris = Vec::new(); let mut named_graph_uris = Vec::new();
for (k, v) in form_urlencoded::parse(&encoded) { for (k, v) in form_urlencoded::parse(&encoded) {
match k.as_ref() { match k.as_ref() {
"update" => update = Some(v.into_owned()), "update" => {
if update.is_some() {
bail_status!(400, "Multiple update parameters provided")
}
update = Some(v.into_owned())
}
"using-graph-uri" => default_graph_uris.push(v.into_owned()), "using-graph-uri" => default_graph_uris.push(v.into_owned()),
"using-named-graph-uri" => named_graph_uris.push(v.into_owned()), "using-named-graph-uri" => named_graph_uris.push(v.into_owned()),
_ => { _ => {
@ -289,7 +319,7 @@ async fn evaluate_urlencoded_sparql_update(store: Store, encoded: Vec<u8>) -> Re
} }
} }
if let Some(update) = update { if let Some(update) = update {
evaluate_sparql_update(store, update, default_graph_uris, named_graph_uris).await evaluate_sparql_update(store, update, default_graph_uris, named_graph_uris, request)
} else { } else {
Ok(simple_response( Ok(simple_response(
StatusCode::BadRequest, StatusCode::BadRequest,
@ -298,13 +328,14 @@ async fn evaluate_urlencoded_sparql_update(store: Store, encoded: Vec<u8>) -> Re
} }
} }
async fn evaluate_sparql_update( fn evaluate_sparql_update(
store: Store, store: Store,
update: String, update: String,
default_graph_uris: Vec<String>, default_graph_uris: Vec<String>,
named_graph_uris: Vec<String>, named_graph_uris: Vec<String>,
request: Request,
) -> Result<Response> { ) -> Result<Response> {
let mut update = Update::parse(&update, None).map_err(|e| { let mut update = Update::parse(&update, Some(base_url(&request))).map_err(|e| {
let mut e = Error::from(e); let mut e = Error::from(e);
e.set_status(StatusCode::BadRequest); e.set_status(StatusCode::BadRequest);
e e

Loading…
Cancel
Save