/// <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); WebContext webContext = new WebContext(context); // Add our Standard Headers HandlerHelper.AddStandardHeaders(webContext, this._config); if (context.Request.HttpMethod.Equals("OPTIONS")) { // OPTIONS requests always result in the Service Description document IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(this._config, new Uri(UriFactory.Create(context.Request.Url.AbsoluteUri), this._basePath)); HandlerHelper.SendToClient(webContext, svcDescrip, this._config); return; } // Check whether we need to use authentication if (!HandlerHelper.IsAuthenticated(webContext, 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(webContext); break; case "PUT": this._config.Processor.ProcessPut(webContext); break; case "POST": Uri serviceUri = new Uri(UriFactory.Create(context.Request.Url.AbsoluteUri), this._basePath); if (context.Request.Url.AbsoluteUri.Equals(serviceUri.AbsoluteUri)) { // 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(webContext); } else if (context.Request.QueryString.AllKeys.Contains("default") || Regex.IsMatch(context.Request.QueryString.ToString(), BaseProtocolProcessor.DefaultParameterPattern)) { this._config.Processor.ProcessPost(webContext); } else { this._config.Processor.ProcessPostCreate(webContext); } } else { this._config.Processor.ProcessPost(webContext); } break; case "DELETE": this._config.Processor.ProcessDelete(webContext); break; case "HEAD": this._config.Processor.ProcessHead(webContext); break; case "PATCH": this._config.Processor.ProcessPatch(webContext); 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> /// Processes the request by loading the Configuration in order to obtain the Graph to be served and then serving it to the client /// </summary> /// <param name="context">HTTP Context</param> public void ProcessRequest(HttpContext context) { this._config = this.LoadConfig(context); WebContext webContext = new WebContext(context); // Add our Standard Headers HandlerHelper.AddStandardHeaders(webContext, this._config); // 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; if (this._config.UserGroups.Any()) { // If we have user isAuth = HandlerHelper.IsAuthenticated(webContext, this._config.UserGroups); } if (!isAuth) { return; } // Check whether we can just send a 304 Not Modified if (HandlerHelper.CheckCachingHeaders(webContext, this._config.ETag, null)) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; HandlerHelper.AddCachingHeaders(webContext, this._config.ETag, null); return; } try { String[] acceptTypes = webContext.GetAcceptTypes(); // Retrieve an appropriate MIME Type Definition which can be used to get a Writer MimeTypeDefinition definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteRdf); if (definition == null) { throw new RdfWriterSelectionException("No MIME Type Definitions have a registered RDF Writer for the MIME Types specified in the HTTP Accept Header"); } IRdfWriter writer = this.SelectWriter(definition); HandlerHelper.ApplyWriterOptions(writer, this._config); IGraph g = this.ProcessGraph(this._config.Graph); if (this._config.ETag == null) { this._config.ETag = this.ComputeETag(g); } // Serve the Graph to the User context.Response.ContentType = definition.CanonicalMimeType; HandlerHelper.AddCachingHeaders(webContext, this._config.ETag, null); if (writer is IHtmlWriter) { if (!this._config.Stylesheet.Equals(String.Empty)) { ((IHtmlWriter)writer).Stylesheet = this._config.Stylesheet; } } context.Response.ContentEncoding = definition.Encoding; HandlerHelper.ApplyWriterOptions(writer, this._config); writer.Save(g, new StreamWriter(context.Response.OutputStream, definition.Encoding)); this.UpdateConfig(context); } catch (RdfWriterSelectionException) { context.Response.StatusCode = (int)HttpStatusCode.NotAcceptable; } catch { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; } }
/// <summary> /// Processes SPARQL Update requests /// </summary> /// <param name="context">HTTP Context</param> public void ProcessRequest(HttpContext context) { this._config = this.LoadConfig(context); WebContext webContext = new WebContext(context); // Add our Standard Headers HandlerHelper.AddStandardHeaders(webContext, this._config); // Options we need to determine based on the HTTP Method used String[] updates; String updateText = null; List <String> userDefaultGraphs = new List <String>(); List <String> userNamedGraphs = new List <String>(); try { // Decide what to do based on the HTTP Method switch (context.Request.HttpMethod.ToUpper()) { case "OPTIONS": // OPTIONS requests always result in the Service Description document IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(this._config, UriFactory.Create(context.Request.Url.AbsoluteUri)); HandlerHelper.SendToClient(webContext, svcDescrip, this._config); return; case "HEAD": // Just return from a HEAD request return; case "GET": // A GET with an update parameter is a Bad Request updates = context.Request.QueryString.GetValues("update"); if (updates != null && updates.Length > 0) { throw new ArgumentException("Updates cannot be submitted as GET requests"); } // Otherwise GET either results in the Service Description if appropriately conneg'd or // the update form if enabled try { // If we might show the Update Form only show the Description if the selected writer is // not a HTML writer MimeTypeDefinition definition = MimeTypesHelper.GetDefinitions(webContext.GetAcceptTypes()).FirstOrDefault(d => d.CanWriteRdf); if (definition != null) { IRdfWriter writer = definition.GetRdfWriter(); if (!(writer is IHtmlWriter)) { // If not a HTML Writer selected then show the Service Description Graph // unless an error occurs creating it IGraph serviceDescrip = SparqlServiceDescriber.GetServiceDescription(this._config, UriFactory.Create(context.Request.Url.AbsoluteUri)); context.Response.ContentType = definition.CanonicalMimeType; context.Response.ContentEncoding = definition.Encoding; writer.Save(serviceDescrip, new StreamWriter(context.Response.OutputStream, definition.Encoding)); return; } } } catch { // Ignore Exceptions - we'll just show the Query Form or return a 400 Bad Request instead } // If a Writer can't be selected then we'll either show the Update Form or return a 400 Bad Request if (this._config.ShowUpdateForm) { this.ShowUpdateForm(context); } else { throw new ArgumentException("Updates cannot be submitted as GET requests"); } return; case "POST": if (context.Request.ContentType != null) { MimeTypeSelector contentType = MimeTypeSelector.Create(context.Request.ContentType, 0); if (contentType.Type.Equals(MimeTypesHelper.WWWFormURLEncoded)) { // Form URL Encoded was declared type so expect an update parameter in the Form parameters updates = context.Request.Form.GetValues("update"); if (updates == null) { throw new ArgumentException("Required update parameter in POST body was missing"); } if (updates.Length == 0) { throw new ArgumentException("Required update parameter in POST body was missing"); } if (updates.Length > 1) { throw new ArgumentException("The update parameter was specified multiple times in the POST body"); } updateText = updates[0]; // For Form URL Encoded the Using/Using Named Graphs may be specified by Form parameters // Get the USING URIs (if any) if (context.Request.Form["using-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.Form.GetValues("using-graph-uri")); } // Get the USING NAMED URIs (if any) if (context.Request.Form["using-named-graph-uri"] != null) { userNamedGraphs.AddRange(context.Request.Form.GetValues("using-named-graph-uri")); } break; } else if (contentType.Type.Equals(MimeTypesHelper.SparqlUpdate)) { // application/sparql-update was declared type so expect utf-8 charset (if present) if (contentType.Charset != null && !contentType.Charset.ToLower().Equals(MimeTypesHelper.CharsetUtf8)) { throw new ArgumentException("HTTP POST request was received with a " + MimeTypesHelper.SparqlUpdate + " Content-Type but a non UTF-8 charset parameter"); } using (StreamReader reader = new StreamReader(context.Request.InputStream)) { updateText = reader.ReadToEnd(); reader.Close(); } // For application/sparql-update the Using/Using Named Graphs may be specified by querystring parameters // Get the USING URIs (if any) if (context.Request.QueryString["using-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.QueryString.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")); } break; } else { throw new ArgumentException("HTTP POST made to SPARQL update endpoint had an invalid Content-Type header, only " + MimeTypesHelper.WWWFormURLEncoded + " and " + MimeTypesHelper.SparqlUpdate + " are acceptable"); } } throw new ArgumentException("HTTP POST made to SPARQL Query endpoint was missing the required Content-Type header"); default: throw new NotSupportedException("HTTP " + context.Request.HttpMethod.ToUpper() + " is not supported by a SPARQL Update endpoint"); } // Clean up protocol provided dataset userDefaultGraphs.RemoveAll(g => String.IsNullOrEmpty(g)); userNamedGraphs.RemoveAll(g => String.IsNullOrEmpty(g)); // Now we're going to parse the Updates SparqlUpdateParser parser = new SparqlUpdateParser(); parser.DefaultBaseUri = context.Request.Url; parser.ExpressionFactories = this._config.ExpressionFactories; SparqlUpdateCommandSet commands = parser.ParseFromString(updateText); // 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(webContext, this._config.UserGroups); requireActionAuth = true; } if (!isAuth) { return; } // First check actions to see whether they are all permissible and apply USING/USING NAMED parameters foreach (SparqlUpdateCommand cmd in commands.Commands) { // Authenticate each action bool actionAuth = true; if (requireActionAuth) { actionAuth = HandlerHelper.IsAuthenticated(webContext, this._config.UserGroups, this.GetPermissionAction(cmd)); } if (!actionAuth) { throw new SparqlUpdatePermissionException("You are not authorised to perform the " + this.GetPermissionAction(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.ProcessUpdates(commands); // Flush outstanding changes this._config.Processor.Flush(); // Update the Cache as the request may have changed the endpoint this.UpdateConfig(context); } catch (RdfParseException parseEx) { HandleErrors(context, "Parsing Error", updateText, parseEx, (int)HttpStatusCode.BadRequest); } catch (SparqlUpdatePermissionException permEx) { HandleErrors(context, "Permissions Error", updateText, permEx, (int)HttpStatusCode.Forbidden); } catch (SparqlUpdateMalformedException malEx) { HandleErrors(context, "Malformed Update Error", updateText, malEx, (int)HttpStatusCode.BadRequest); } catch (SparqlUpdateException updateEx) { HandleErrors(context, "Update Error", updateText, updateEx); } catch (RdfException rdfEx) { HandleErrors(context, "RDF Error", updateText, rdfEx); } catch (NotSupportedException notSupEx) { HandleErrors(context, "HTTP Request Error", null, notSupEx, (int)HttpStatusCode.MethodNotAllowed); } catch (ArgumentException argEx) { HandleErrors(context, "HTTP Request Error", null, argEx, (int)HttpStatusCode.BadRequest); } catch (Exception ex) { HandleErrors(context, "Error", updateText, ex); } }
/// <summary> /// Processes a SPARQL Query Request /// </summary> /// <param name="context">HTTP Context</param> public void ProcessRequest(HttpContext context) { this._config = this.LoadConfig(context); WebContext webContext = new WebContext(context); //Add our Standard Headers HandlerHelper.AddStandardHeaders(webContext, this._config); //Options we need to determine based on the HTTP Method used String[] queries; String queryText = null; List <String> userDefaultGraphs = new List <String>(); List <String> userNamedGraphs = new List <String>(); try { //Decide what to do based on the HTTP Method switch (context.Request.HttpMethod.ToUpper()) { case "OPTIONS": //OPTIONS requests always result in the Service Description document IGraph svcDescrip = SparqlServiceDescriber.GetServiceDescription(this._config, UriFactory.Create(context.Request.Url.AbsoluteUri)); HandlerHelper.SendToClient(webContext, svcDescrip, this._config); return; case "HEAD": //Just return from a HEAD request return; case "GET": //GET expects a query parameter in the querystring queries = context.Request.QueryString.GetValues("query"); if (queries != null) { if (queries.Length > 1) { throw new ArgumentException("The query parameter was specified multiple times in the querystring"); } queryText = queries.Length == 1 ? queries[0] : null; } //If no Query sent either show Query Form or give a HTTP 400 response if (String.IsNullOrEmpty(queryText)) { //If there is no Query we may return the SPARQL Service Description where appropriate try { //If we might show the Query Form only show the Description if the selected writer is //not a HTML writer MimeTypeDefinition definition = MimeTypesHelper.GetDefinitions(HandlerHelper.GetAcceptTypes(webContext)).FirstOrDefault(d => d.CanWriteRdf); if (definition != null) { IRdfWriter writer = definition.GetRdfWriter(); if (!this._config.ShowQueryForm || !(writer is IHtmlWriter)) { //If not a HTML Writer selected OR not showing Query Form then show the Service Description Graph //unless an error occurs creating it IGraph serviceDescrip = SparqlServiceDescriber.GetServiceDescription(this._config, UriFactory.Create(context.Request.Url.AbsoluteUri)); context.Response.ContentType = definition.CanonicalMimeType; context.Response.ContentEncoding = definition.Encoding; writer.Save(serviceDescrip, new StreamWriter(context.Response.OutputStream, definition.Encoding)); return; } } } catch { //Ignore Exceptions - we'll just show the Query Form or return a 400 Bad Request instead } //Otherwise we'll either show the Query Form or return a 400 Bad Request if (this._config.ShowQueryForm) { this.ShowQueryForm(context); } else { throw new ArgumentException("Missing required query parameter"); } return; } //Get the Default Graph URIs (if any) if (context.Request.QueryString["default-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.QueryString.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")); } break; case "POST": //POST requires a valid content type if (context.Request.ContentType != null) { MimeTypeSelector contentType = MimeTypeSelector.Create(context.Request.ContentType, 0); if (contentType.Type.Equals(MimeTypesHelper.WWWFormURLEncoded)) { //Form URL Encoded was declared type so expect a query parameter in the Form parameters queries = context.Request.Form.GetValues("query"); if (queries == null) { throw new ArgumentException("Required query parameter in POST body was missing"); } if (queries.Length == 0) { throw new ArgumentException("Required query parameter in POST body was missing"); } if (queries.Length > 1) { throw new ArgumentException("The query parameter was specified multiple times in the POST body"); } queryText = queries[0]; //For Form URL Encoded the Default/Named Graphs may be specified by Form parameters //Get the Default Graph URIs (if any) if (context.Request.Form["default-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.Form.GetValues("default-graph-uri")); } //Get the Named Graph URIs (if any) if (context.Request.Form["named-graph-uri"] != null) { userNamedGraphs.AddRange(context.Request.Form.GetValues("named-graph-uri")); } break; } else if (contentType.Type.Equals(MimeTypesHelper.SparqlQuery)) { //application/sparql-query was declared type so expect utf-8 charset (if present) if (contentType.Charset != null && !contentType.Charset.ToLower().Equals(MimeTypesHelper.CharsetUtf8)) { throw new ArgumentException("HTTP POST request was received with a " + MimeTypesHelper.SparqlQuery + " Content-Type but a non UTF-8 charset parameter"); } //Read the query from the request body using (StreamReader reader = new StreamReader(context.Request.InputStream)) { queryText = reader.ReadToEnd(); reader.Close(); } //For application/sparql-query the Default/Named Graphs may be specified by querystring parameters //Get the Default Graph URIs (if any) if (context.Request.QueryString["default-graph-uri"] != null) { userDefaultGraphs.AddRange(context.Request.QueryString.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")); } break; } else { throw new ArgumentException("HTTP POST made to SPARQL query endpoint had an invalid Content-Type header, only " + MimeTypesHelper.WWWFormURLEncoded + " and " + MimeTypesHelper.SparqlQuery + " are acceptable"); } } throw new ArgumentException("HTTP POST made to SPARQL Query endpoint was missing the required Content-Type header"); default: throw new NotSupportedException("HTTP " + context.Request.HttpMethod.ToUpper() + " is not supported by a SPARQL Query endpoint"); } //Get non-standard options associated with the query long timeout = 0; bool partialResults = this._config.DefaultPartialResults; //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 (context.Request.Form["timeout"] != null) { if (!Int64.TryParse(context.Request.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 (context.Request.Form["partialResults"] != null) { if (!Boolean.TryParse(context.Request.Form["partialResults"], out partialResults)) { partialResults = this._config.DefaultPartialResults; } } //Now we're going to parse the Query SparqlQueryParser parser = new SparqlQueryParser(this._config.Syntax); parser.DefaultBaseUri = context.Request.Url; 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; //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(webContext, this._config.UserGroups); requireActionAuth = true; } if (!isAuth) { return; } //Is this user allowed to make this kind of query? if (requireActionAuth) { HandlerHelper.IsAuthenticated(webContext, this._config.UserGroups, this.GetPermissionAction(query)); } //Clear query dataset if there is a protocol defined one userDefaultGraphs.RemoveAll(g => String.IsNullOrEmpty(g)); userNamedGraphs.RemoveAll(g => String.IsNullOrEmpty(g)); bool isProtocolDataset = false; if (userDefaultGraphs.Count > 0 || userNamedGraphs.Count > 0) { query.ClearDefaultGraphs(); query.ClearNamedGraphs(); isProtocolDataset = true; } //Set the Default Graph URIs (if any) if (isProtocolDataset) { foreach (String userDefaultGraph in userDefaultGraphs) { query.AddDefaultGraph(UriFactory.Create(userDefaultGraph)); } } else if (!this._config.DefaultGraphURI.Equals(String.Empty)) { //Only applies if the Query doesn't specify any Default Graph and there wasn't a protocol defined //dataset present if (!query.DefaultGraphs.Any()) { query.AddDefaultGraph(UriFactory.Create(this._config.DefaultGraphURI)); } } //Set the Named Graph URIs (if any) if (isProtocolDataset) { query.ClearNamedGraphs(); foreach (String userNamedGraph in userNamedGraphs) { 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.ProcessQuery(query); this.ProcessResults(context, result); //Update the Cache as the request may have changed the endpoint this.UpdateConfig(context); } catch (RdfParseException parseEx) { HandleErrors(context, "Parsing Error", queryText, parseEx, (int)HttpStatusCode.BadRequest); } catch (RdfQueryTimeoutException timeoutEx) { HandleErrors(context, "Query Timeout Error", queryText, timeoutEx); } catch (RdfQueryException queryEx) { HandleErrors(context, "Update Error", queryText, queryEx); } catch (RdfWriterSelectionException writerSelEx) { HandleErrors(context, "Output Selection Error", queryText, writerSelEx, (int)HttpStatusCode.NotAcceptable); } catch (RdfException rdfEx) { HandleErrors(context, "RDF Error", queryText, rdfEx); } catch (NotSupportedException notSupEx) { HandleErrors(context, "HTTP Request Error", null, notSupEx, (int)HttpStatusCode.MethodNotAllowed); } catch (ArgumentException argEx) { HandleErrors(context, "HTTP Request Error", null, argEx, (int)HttpStatusCode.BadRequest); } catch (Exception ex) { HandleErrors(context, "Error", queryText, ex); } }