/// <summary> /// Processes requests made to the Graph Store HTTP Protocol endpoint and invokes the appropriate methods on the Protocol Processor that is in use /// </summary> /// <param name="context">HTTP Context</param> /// <remarks> /// <para> /// Implementations may override this if necessary - if the implementation is only providing additional logic such as authentication, ACLs etc. then it is recommended that the override applies its logic and then calls the base method since this base method will handle much of the error handling and sending of appropriate HTTP Response Codes. /// </para> /// </remarks> public virtual void ProcessRequest(HttpContext context) { this._config = this.LoadConfig(context, out this._basePath); //Add our Standard Headers HandlerHelper.AddStandardHeaders(context, this._config); if (context.Request.HttpMethod.Equals("OPTIONS")) { //OPTIONS requests always result in the Service Description document IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(context, this._config, new Uri(new Uri(context.Request.Url.AbsoluteUri), this._basePath)); HandlerHelper.SendToClient(context, svcDescrip, this._config); return; } //Check whether we need to use authentication if (!HandlerHelper.IsAuthenticated(context, this._config.UserGroups, context.Request.HttpMethod)) return; try { //Invoke the appropriate method on our protocol processor switch (context.Request.HttpMethod) { case "GET": this._config.Processor.ProcessGet(context); break; case "PUT": this._config.Processor.ProcessPut(context); break; case "POST": Uri serviceUri = new Uri(new Uri(context.Request.Url.AbsoluteUri), this._basePath); if (context.Request.Url.AbsoluteUri.Equals(serviceUri.ToString())) { //If there is a ?graph parameter or ?default parameter then this is a normal Post //Otherwise it is a PostCreate if (context.Request.QueryString["graph"] != null) { this._config.Processor.ProcessPost(context); } else if (context.Request.QueryString.AllKeys.Contains("default") || Regex.IsMatch(context.Request.QueryString.ToString(), BaseProtocolProcessor.DefaultParameterPattern)) { this._config.Processor.ProcessPost(context); } else { this._config.Processor.ProcessPostCreate(context); } } else { this._config.Processor.ProcessPost(context); } break; case "DELETE": this._config.Processor.ProcessDelete(context); break; case "HEAD": this._config.Processor.ProcessHead(context); break; case "PATCH": this._config.Processor.ProcessPatch(context); break; default: //For any other HTTP Verb we send a 405 Method Not Allowed context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; break; } //Update the Cache as the request may have changed the endpoint this.UpdateConfig(context); } catch (SparqlHttpProtocolUriResolutionException) { //If URI Resolution fails we send a 400 Bad Request context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } catch (SparqlHttpProtocolUriInvalidException) { //If URI is invalid we send a 400 Bad Request context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } catch (NotSupportedException) { //If Not Supported we send a 405 Method Not Allowed context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; } catch (NotImplementedException) { //If Not Implemented we send a 501 Not Implemented context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; } catch (RdfWriterSelectionException) { //If we can't select a valid Writer when returning content we send a 406 Not Acceptable context.Response.StatusCode = (int)HttpStatusCode.NotAcceptable; } catch (RdfParserSelectionException) { //If we can't select a valid Parser when receiving content we send a 415 Unsupported Media Type context.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType; } catch (RdfParseException) { //If we can't parse the received content successfully we send a 400 Bad Request context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } catch (Exception) { //For any other error we'll send a 500 Internal Server Error context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; } }
/// <summary> /// Generates a SPARQL Service Description Graph for the given Protocol Handler Configuration or uses the configuration supplied Description Graph /// </summary> /// <param name="context">HTTP Context</param> /// <param name="config">Protocol Handler Configuration</param> /// <param name="descripUri">Base URI of the Description</param> /// <returns></returns> public static IGraph GetServiceDescription(HttpContext context, BaseProtocolHandlerConfiguration config, Uri descripUri) { //Use user specified Service Description if present if (config.ServiceDescription != null) return config.ServiceDescription; IGraph g = SparqlServiceDescriber.GetNewGraph(); //Add the Top Level Node representing the Service IUriNode descrip = g.CreateUriNode(descripUri); IUriNode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType)); IUriNode service = g.CreateUriNode("sd:" + ClassService); g.Assert(descrip, rdfType, service); //Add its sd:url IUriNode url = g.CreateUriNode("sd:" + PropertyUrl); g.Assert(descrip, url, descrip); //Add the Input Formats IUriNode inputFormat = g.CreateUriNode("sd:" + PropertyInputFormat); foreach (MimeTypeDefinition definition in MimeTypesHelper.Definitions) { if (definition.CanParseRdf) { if (definition.FormatUri != null) { g.Assert(descrip, inputFormat, g.CreateUriNode(new Uri(definition.FormatUri))); } } } //Add the Result Formats IUriNode resultFormat = g.CreateUriNode("sd:" + PropertyResultFormat); foreach (MimeTypeDefinition definition in MimeTypesHelper.Definitions) { if (definition.CanWriteRdf) { if (definition.FormatUri != null) { g.Assert(descrip, resultFormat, g.CreateUriNode(new Uri(definition.FormatUri))); } } } config.AddFeatureDescription(g, descrip); return g; }