/// <summary> /// Processes Update requests /// </summary> /// <param name="context">HTTP Context</param> public void ProcessUpdateRequest(HttpServerContext context) { if (this._config.UpdateProcessor == null) { context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; return; } //Try and parse the Form Variables FormVariables form = new FormVariables(context); if (!form.IsValid) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } if (context.Request.HttpMethod.Equals("OPTIONS")) { context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; return; //TODO: Support Service Description? ////OPTIONS requests always result in the Service Description document //IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(context, this._config, UriFactory.Create(context.Request.Url.AbsoluteUri), ServiceDescriptionType.Update); //HandlerHelper.SendToClient(context, svcDescrip, this._config); //return; } //See if there has been an update submitted String updateText = null; if (context.Request.ContentType != null) { if (context.Request.ContentType.Equals(MimeTypesHelper.WWWFormURLEncoded)) { updateText = form["update"]; } else if (context.Request.ContentType.Equals(MimeTypesHelper.SparqlUpdate)) { updateText = new StreamReader(context.Request.InputStream).ReadToEnd(); } } else { updateText = form["update"]; } //If no Update sent either show Update Form or give a HTTP 400 response if (updateText == null || updateText.Equals(String.Empty)) { if (this._config.ShowUpdateForm) { this.ShowUpdateForm(context); return; } else { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } } //Get Other options associated with this update List <String> userDefaultGraphs = new List <String>(); List <String> userNamedGraphs = new List <String>(); //Get the USING URIs (if any) if (context.Request.QueryString["using-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.QueryString.GetValues("using-graph-uri")); } else if (form["using-graph-uri"] != null) { userDefaultGraphs.AddRange(form.GetValues("using-graph-uri")); } //Get the USING NAMED URIs (if any) if (context.Request.QueryString["using-named-graph-uri"] != null) { userNamedGraphs.AddRange(context.Request.QueryString.GetValues("using-named-graph-uri")); } else if (form["using-named-graph-uri"] != null) { userNamedGraphs.AddRange(form.GetValues("using-named-graph-uri")); } try { //Now we're going to parse the Updates SparqlUpdateParser parser = new SparqlUpdateParser(); parser.ExpressionFactories = this._config.ExpressionFactories; SparqlUpdateCommandSet commands = parser.ParseFromString(updateText); //TODO: Support Authentication? ////Check whether we need to use authentication ////If there are no user groups then no authentication is in use so we default to authenticated with no per-action authentication needed //bool isAuth = true, requireActionAuth = false; //if (this._config.UserGroups.Any()) //{ // //If we have user // isAuth = HandlerHelper.IsAuthenticated(context, this._config.UserGroups); // requireActionAuth = true; //} //if (!isAuth) return; //First check actions to see whether they are all permissible and apply USING/USING NAMED paramaters foreach (SparqlUpdateCommand cmd in commands.Commands) { //TODO: Support Authentication? ////Authenticate each action //bool actionAuth = true; //if (requireActionAuth) actionAuth = HandlerHelper.IsAuthenticated(context, this._config.UserGroups, this.GetUpdatePermissionAction(cmd)); //if (!actionAuth) //{ // throw new SparqlUpdatePermissionException("You are not authorised to perform the " + this.GetUpdatePermissionAction(cmd) + " action"); //} //Check whether we need to (and are permitted to) apply USING/USING NAMED parameters if (userDefaultGraphs.Count > 0 || userNamedGraphs.Count > 0) { BaseModificationCommand modify = cmd as BaseModificationCommand; if (modify != null) { if (modify.GraphUri != null || modify.UsingUris.Any() || modify.UsingNamedUris.Any()) { //Invalid if a command already has a WITH/USING/USING NAMED throw new SparqlUpdateMalformedException("A command in your update request contains a WITH/USING/USING NAMED clause but you have also specified one/both of the using-graph-uri or using-named-graph-uri parameters which is not permitted by the SPARQL Protocol"); } else { //Otherwise go ahead and apply userDefaultGraphs.ForEach(u => modify.AddUsingUri(UriFactory.Create(u))); userNamedGraphs.ForEach(u => modify.AddUsingNamedUri(UriFactory.Create(u))); } } } } //Then assuming we got here this means all our actions are permitted so now we can process the updates this._config.UpdateProcessor.ProcessCommandSet(commands); //Flush outstanding changes this._config.UpdateProcessor.Flush(); } catch (RdfParseException parseEx) { HandleUpdateErrors(context, "Parsing Error", updateText, parseEx, (int)HttpStatusCode.BadRequest); } catch (SparqlUpdatePermissionException permEx) { HandleUpdateErrors(context, "Permissions Error", updateText, permEx, (int)HttpStatusCode.Forbidden); } catch (SparqlUpdateMalformedException malEx) { HandleUpdateErrors(context, "Malformed Update Error", updateText, malEx, (int)HttpStatusCode.BadRequest); } catch (SparqlUpdateException updateEx) { HandleUpdateErrors(context, "Update Error", updateText, updateEx); } catch (RdfException rdfEx) { HandleUpdateErrors(context, "RDF Error", updateText, rdfEx); } catch (Exception ex) { HandleUpdateErrors(context, "Error", updateText, ex); } }
/// <summary> /// Processes Query requests /// </summary> /// <param name="context">HTTP Context</param> public void ProcessQueryRequest(HttpServerContext context) { if (this._config.QueryProcessor == null) { context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; return; } //Try and parse the Form Variables FormVariables form = new FormVariables(context); if (!form.IsValid) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } if (context.Request.HttpMethod.Equals("OPTIONS")) { context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; return; //TODO: Support Service Description? ////OPTIONS requests always result in the Service Description document //IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(context, this._config, UriFactory.Create(context.Request.Url.AbsoluteUri), ServiceDescriptionType.Query); //HandlerHelper.SendToClient(context, svcDescrip, this._config); //return; } //See if there has been an query submitted String queryText = context.Request.QueryString["query"]; if (queryText == null || queryText.Equals(String.Empty)) { if (context.Request.ContentType != null) { if (context.Request.ContentType.Equals(MimeTypesHelper.WWWFormURLEncoded)) { queryText = form["query"]; } else if (context.Request.ContentType.Equals(MimeTypesHelper.SparqlQuery)) { queryText = new StreamReader(context.Request.InputStream).ReadToEnd(); } } else { queryText = form["query"]; } } //If no Query sent either show Query Form or give a HTTP 400 response if (queryText == null || queryText.Equals(String.Empty)) { if (this._config.ShowQueryForm) { this.ShowQueryForm(context); return; } else { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } } //Get Other options associated with this query List <String> userDefaultGraphs = new List <String>(); List <String> userNamedGraphs = new List <String>(); long timeout = 0; bool partialResults = this._config.DefaultPartialResults; //Get the Default Graph URIs (if any) if (context.Request.QueryString["default-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.QueryString.GetValues("default-graph-uri")); } else if (form["default-graph-uri"] != null) { userDefaultGraphs.AddRange(form.GetValues("default-graph-uri")); } //Get the Named Graph URIs (if any) if (context.Request.QueryString["named-graph-uri"] != null) { userNamedGraphs.AddRange(context.Request.QueryString.GetValues("named-graph-uri")); } else if (form["named-graph-uri"] != null) { userNamedGraphs.AddRange(form.GetValues("named-graph-uri")); } //Get Timeout setting (if any) if (context.Request.QueryString["timeout"] != null) { if (!Int64.TryParse(context.Request.QueryString["timeout"], out timeout)) { timeout = this._config.DefaultTimeout; } } else if (form["timeout"] != null) { if (!Int64.TryParse(form["timeout"], out timeout)) { timeout = this._config.DefaultTimeout; } } //Get Partial Results Setting (if any); if (context.Request.QueryString["partialResults"] != null) { if (!Boolean.TryParse(context.Request.QueryString["partialResults"], out partialResults)) { partialResults = this._config.DefaultPartialResults; } } else if (form["partialResults"] != null) { if (!Boolean.TryParse(form["partialResults"], out partialResults)) { partialResults = this._config.DefaultPartialResults; } } try { //Now we're going to parse the Query SparqlQueryParser parser = new SparqlQueryParser(this._config.QuerySyntax); parser.ExpressionFactories = this._config.ExpressionFactories; parser.QueryOptimiser = this._config.QueryOptimiser; SparqlQuery query = parser.ParseFromString(queryText); query.AlgebraOptimisers = this._config.AlgebraOptimisers; query.PropertyFunctionFactories = this._config.PropertyFunctionFactories; //TODO: Support Authentication? ////Check whether we need to use authentication ////If there are no user groups then no authentication is in use so we default to authenticated with no per-action authentication needed //bool isAuth = true, requireActionAuth = false; //if (this._config.UserGroups.Any()) //{ // //If we have user // isAuth = HandlerHelper.IsAuthenticated(context, this._config.UserGroups); // requireActionAuth = true; //} //if (!isAuth) return; ////Is this user allowed to make this kind of query? //if (requireActionAuth) HandlerHelper.IsAuthenticated(context, this._config.UserGroups, this.GetQueryPermissionAction(query)); //Set the Default Graph URIs (if any) if (userDefaultGraphs.Count > 0) { //Default Graph Uri specified by default-graph-uri parameter or Web.config settings foreach (String userDefaultGraph in userDefaultGraphs) { if (!userDefaultGraph.Equals(String.Empty)) { query.AddDefaultGraph(UriFactory.Create(userDefaultGraph)); } } } else if (!this._config.DefaultGraphURI.Equals(String.Empty)) { //Only applies if the Query doesn't specify any Default Graph if (!query.DefaultGraphs.Any()) { query.AddDefaultGraph(UriFactory.Create(this._config.DefaultGraphURI)); } } //Set the Named Graph URIs (if any) if (userNamedGraphs.Count > 0) { foreach (String userNamedGraph in userNamedGraphs) { if (!userNamedGraph.Equals(String.Empty)) { query.AddNamedGraph(UriFactory.Create(userNamedGraph)); } } } //Set Timeout setting if (timeout > 0) { query.Timeout = timeout; } else { query.Timeout = this._config.DefaultTimeout; } //Set Partial Results Setting query.PartialResultsOnTimeout = partialResults; //Set Describe Algorithm query.Describer = this._config.DescribeAlgorithm; //Now we can finally make the query and return the results Object result = this._config.QueryProcessor.ProcessQuery(query); this.ProcessQueryResults(context, result); } catch (RdfParseException parseEx) { HandleQueryErrors(context, "Parsing Error", queryText, parseEx, (int)HttpStatusCode.BadRequest); } catch (RdfQueryTimeoutException timeoutEx) { HandleQueryErrors(context, "Query Timeout Error", queryText, timeoutEx); } catch (RdfQueryException queryEx) { HandleQueryErrors(context, "Query Error", queryText, queryEx); } catch (RdfWriterSelectionException writerSelEx) { HandleQueryErrors(context, "Output Selection Error", queryText, writerSelEx, (int)HttpStatusCode.NotAcceptable); } catch (RdfException rdfEx) { HandleQueryErrors(context, "RDF Error", queryText, rdfEx); } catch (Exception ex) { HandleQueryErrors(context, "Error", queryText, ex); } }