Пример #1
0
        private void EnsureTestData(String file)
        {
            if (this._original == null)
            {
                Graph g = new Graph();
                g.Assert(g.CreateBlankNode(), g.CreateUriNode(UriFactory.Create("http://example.org/predicate")), g.CreateLiteralNode("literal", "en-123"));
                g.Assert(g.CreateBlankNode(), g.CreateUriNode(UriFactory.Create("http://example.org/predicate")), g.CreateLiteralNode("literal", "en-gb-us"));
                g.Assert(g.CreateBlankNode(), g.CreateUriNode(UriFactory.Create("http://example.org/predicate")), g.CreateLiteralNode("literal", "en-123-abc"));
                this._original = g;

                this._store = new TripleStore();
                this._store.Add(this._original);
            }

            if (!File.Exists(file))
            {
                MimeTypeDefinition def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(Path.GetExtension(file))).FirstOrDefault();
                Assert.NotNull(def);
                if (def != null)
                {
                    Assert.True(def.CanWriteRdf || def.CanWriteRdfDatasets, "Unable to ensure test data");
                    if (def.CanWriteRdf)
                    {
                        this._original.SaveToFile(file);
                    }
                    else if (def.CanWriteRdfDatasets)
                    {
                        this._store.SaveToFile(file);
                    }
                }
            }
            Assert.True(File.Exists(file), "Unable to ensure test data:" + Path.GetFullPath(file));
        }
Пример #2
0
        public void TestLangSpecParsing(String file)
        {
            this.EnsureTestData(file);

            MimeTypeDefinition def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(Path.GetExtension(file))).FirstOrDefault();

            if (def != null)
            {
                if (def.CanParseRdf)
                {
                    Graph g = new Graph();
                    g.LoadFromFile(file);

                    Assert.AreEqual(this._original, g);
                }
                else if (def.CanParseRdfDatasets)
                {
                    TripleStore store = new TripleStore();
                    store.LoadFromFile(file);

                    Assert.AreEqual(this._original, store.Graphs.First());
                }
            }
            else
            {
                Assert.Fail("Unsupported file type");
            }
        }
Пример #3
0
        public static FusekiConnector GetConnection(string uploadMimeType = null)
        {
            Skip.IfNot(TestConfigManager.GetSettingAsBoolean(TestConfigManager.UseFuseki),
                       "Test Configuration marks Fuseki as unavailable, test cannot be run");
            var mimeTypeDescription =
                uploadMimeType == null ? null : MimeTypesHelper.GetDefinitions(uploadMimeType).First();

            return(new FusekiConnector(TestConfigManager.GetSetting(TestConfigManager.FusekiServer), mimeTypeDescription));
        }
Пример #4
0
 /// <summary>
 /// Internal Helper method which does the actual loading of the Triple Store from the Resource
 /// </summary>
 /// <param name="handler">RDF Handler to use</param>
 /// <param name="asm">Assembly to get the resource stream from</param>
 /// <param name="resource">Full name of the Resource (without the Assembly Name)</param>
 /// <param name="parser">Parser to use (if null will be auto-selected)</param>
 private static void LoadDatasetInternal(IRdfHandler handler, Assembly asm, String resource, IStoreReader parser)
 {
     //Resource is in the given assembly
     using (Stream s = asm.GetManifestResourceStream(resource))
     {
         if (s == null)
         {
             //Resource did not exist in this assembly
             throw new RdfParseException("The Embedded Resource '" + resource + "' does not exist inside of " + asm.GetName().Name);
         }
         else
         {
             //Resource exists
             //Do we have a predefined Parser?
             if (parser != null)
             {
                 parser.Load(handler, new StreamParams(s));
             }
             else
             {
                 //Need to select a Parser or use StringParser
                 String             ext = resource.Substring(resource.LastIndexOf("."));
                 MimeTypeDefinition def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(ext)).FirstOrDefault(d => d.CanParseRdfDatasets);
                 if (def != null)
                 {
                     //Resource has an appropriate file extension and we've found a candidate parser for it
                     parser = def.GetRdfDatasetParser();
                     parser.Load(handler, new StreamParams(s));
                 }
                 else
                 {
                     //See if the format was actually an RDF graph instead
                     def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(ext)).FirstOrDefault(d => d.CanParseRdf);
                     if (def != null)
                     {
                         IRdfReader rdfParser = def.GetRdfParser();
                         rdfParser.Load(handler, new StreamReader(s));
                     }
                     else
                     {
                         //Resource did not have a file extension or we didn't have a parser associated with the extension
                         //Try using StringParser instead
                         String data;
                         using (StreamReader reader = new StreamReader(s))
                         {
                             data = reader.ReadToEnd();
                             reader.Close();
                         }
                         parser = StringParser.GetDatasetParser(data);
                         parser.Load(handler, new TextReaderParams(new StringReader(data)));
                     }
                 }
             }
         }
     }
 }
Пример #5
0
        public void AutoDetectSyntax()
        {
            if (this._filename != null && !this._filename.Equals(String.Empty))
            {
                try
                {
                    //Try filename based syntax detection
                    MimeTypeDefinition def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(Path.GetExtension(this._filename))).FirstOrDefault();
                    if (def != null)
                    {
                        this.Syntax = def.SyntaxName.GetSyntaxName();
                        return;
                    }
                }
                catch (RdfParserSelectionException)
                {
                    //Ignore and use string based detection instead
                }
            }

            //Otherwise try and use string based detection
            //First take a guess at it being a SPARQL Results format
            String text = this.Text;

            try
            {
                ISparqlResultsReader resultsReader = StringParser.GetResultSetParser(text);
                this.Syntax = resultsReader.GetSyntaxName();
            }
            catch (RdfParserSelectionException)
            {
                //Then see whether it may be a SPARQL query
                if (text.Contains("SELECT") || text.Contains("CONSTRUCT") || text.Contains("DESCRIBE") || text.Contains("ASK"))
                {
                    //Likely a SPARQL Query
                    this.Syntax = "SparqlQuery11";
                }
                else
                {
                    //Then take a guess at it being a RDF format
                    try
                    {
                        IRdfReader rdfReader = StringParser.GetParser(text);
                        this.Syntax = rdfReader.GetSyntaxName();
                    }
                    catch (RdfParserSelectionException)
                    {
                        //Finally take a guess at it being a RDF Dataset format
                        IStoreReader datasetReader = StringParser.GetDatasetParser(text);
                        this.Syntax = datasetReader.GetSyntaxName();
                    }
                }
            }
        }
Пример #6
0
 public static bool IsValidMimeType(String mimeType)
 {
     if (MimeTypesHelper.GetDefinitions(mimeType).Any())
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
 /// <summary>
 /// Creates a new SPARQL Graph Store HTTP Protocol Connector
 /// </summary>
 /// <param name="serviceUri">URI of the Protocol Server</param>
 /// <param name="writerMimeTypeDefinition">The MIME type specifying the syntax to use when sending RDF data to the server. Defaults to "application/rdf+xml"</param>
 public SparqlHttpProtocolConnector(string serviceUri, MimeTypeDefinition writerMimeTypeDefinition = null)
 {
     if (serviceUri == null)
     {
         throw new ArgumentNullException(nameof(serviceUri),
                                         "Cannot create a connection to a Graph Store HTTP Protocol store if the Service URI is null");
     }
     if (serviceUri.Equals(string.Empty))
     {
         throw new ArgumentException(
                   "Cannot create a connection to a Graph Store HTTP Protocol store if the Service URI is null/empty",
                   nameof(serviceUri));
     }
     _writerMimeTypeDefinition = writerMimeTypeDefinition ??
                                 MimeTypesHelper.GetDefinitions("application/rdf+xml").First();
     _serviceUri = serviceUri;
 }
Пример #8
0
        /// <summary>
        /// Sends the given Graph to the Client via the HTTP Response.
        /// </summary>
        /// <param name="context">HTTP Context.</param>
        /// <param name="g">Graph to send.</param>
        protected void SendResultsToClient(IHttpContext context, IGraph g)
        {
            IRdfWriter writer;
            String     ctype;

            // Look up the MIME Type Definition - if none use GetWriter instead
            MimeTypeDefinition definition = MimeTypesHelper.GetDefinitions(context.GetAcceptTypes()).FirstOrDefault(d => d.CanWriteRdf);

            if (definition != null)
            {
                writer = definition.GetRdfWriter();
                ctype  = definition.CanonicalMimeType;
            }
            else
            {
                writer = MimeTypesHelper.GetWriter(context.GetAcceptTypes(), out ctype);
            }

            // Set up the Writer
            if (writer is ICompressingWriter)
            {
                ((ICompressingWriter)writer).CompressionLevel = Options.DefaultCompressionLevel;
            }

            // Send Content to Client
            context.Response.ContentType = ctype;
            if (definition != null)
            {
                context.Response.ContentEncoding = definition.Encoding;
                writer.Save(g, new StreamWriter(context.Response.OutputStream, definition.Encoding));
            }
            else
            {
                writer.Save(g, new StreamWriter(context.Response.OutputStream));
            }
        }
Пример #9
0
        public void RunConvert(String[] args)
        {
            //Set the Options
            if (!this.SetOptions(args))
            {
                //If SetOptions returns false then some options were invalid and errors have been output to the error stream
                return;
            }

            //First grab the MIME Type Definitions for the conversion
            List <MimeTypeDefinition> defs = MimeTypesHelper.GetDefinitions(this._outFormats).ToList();

            //Process each input to determine the Conversion Handler to use
            foreach (IConversionInput input in this._inputs)
            {
                String outFile;
                String ext = this._outExt;

                //First determine the writer we'll use
                MimeTypeDefinition graphDef = defs.FirstOrDefault(d => d.CanWriteRdf);
                if (graphDef != null)
                {
                    //Then generate the output filename
                    if (ext.Equals(String.Empty))
                    {
                        ext = "." + graphDef.CanonicalFileExtension;
                    }
                    if (this._inputs.Count == 1 && !this._outputFilename.Equals(String.Empty))
                    {
                        outFile = this._outputFilename;
                    }
                    else
                    {
                        outFile = input.GetFilename(this._outputFilename, ext);
                    }

                    //Check it doesn't already exist or overwrite is enabled
                    if (File.Exists(outFile) && !this._overwrite)
                    {
                        Console.Error.WriteLine("rdfConvert: Warning: Skipping Conversion of Input " + input.ToString() + " as this would generate the Output File '" + outFile + "' which already exists and the -overwrite option was not specified");
                        continue;
                    }

                    //Get the Writer and apply Conversion Options
                    IRdfWriter writer = graphDef.GetRdfWriter();
                    foreach (IConversionOption option in this._options)
                    {
                        option.Apply(writer);
                    }

                    //If -best always use SaveOnCompletionHandler
                    if (this._best)
                    {
                        if (this._verbose)
                        {
                            Console.WriteLine("rdfConvert: Using Best Quality data conversion subject to user specified compression options");
                        }
                        input.ConversionHandler = new SaveOnCompletionHandler(writer, new StreamWriter(outFile, false, graphDef.Encoding));
                    }
                    else
                    {
                        //Use the fast WriteThroughHandler where possible
                        if (writer is IFormatterBasedWriter)
                        {
                            if (this._verbose)
                            {
                                Console.WriteLine("rdfConvert: Using Streaming Conversion with formatter " + ((IFormatterBasedWriter)writer).TripleFormatterType.Name);
                            }
                            input.ConversionHandler = new WriteToFileHandler(outFile, graphDef.Encoding, ((IFormatterBasedWriter)writer).TripleFormatterType);
                        }
                        else
                        {
                            //Can't use it in this case
                            if (this._verbose)
                            {
                                Console.WriteLine("rdfConvert: Warning: Target Format not suitable for streaming conversion, input data will be loaded into memory prior to conversion");
                            }
                            input.ConversionHandler = new SaveOnCompletionHandler(writer, new StreamWriter(outFile, false, graphDef.Encoding));
                        }
                    }
                }
                else
                {
                    MimeTypeDefinition storeDef = defs.FirstOrDefault(d => d.CanWriteRdfDatasets);
                    if (storeDef != null)
                    {
                        //Then generate the output filename
                        if (ext.Equals(String.Empty))
                        {
                            ext = "." + storeDef.CanonicalFileExtension;
                        }
                        outFile = input.GetFilename(this._outputFilename, ext);

                        //Get the Writer and apply conversion options
                        IStoreWriter writer = storeDef.GetRdfDatasetWriter();
                        foreach (IConversionOption option in this._options)
                        {
                            option.Apply(writer);
                        }

                        //If -best always use SaveOnCompletionHandler
                        if (this._best)
                        {
                            if (this._verbose)
                            {
                                Console.WriteLine("rdfConvert: Using Best Quality  data conversion subject to user specified compression options");
                            }
                            input.ConversionHandler = new SaveStoreOnCompletionHandler(writer, new StreamWriter(outFile, false, storeDef.Encoding));
                        }
                        else
                        {
                            //Use the fast WriteThroughHandler where possible
                            if (writer is IFormatterBasedWriter)
                            {
                                if (this._verbose)
                                {
                                    Console.WriteLine("rdfConvert: Using Streaming Conversion with formatter " + ((IFormatterBasedWriter)writer).TripleFormatterType.Name);
                                }
                                input.ConversionHandler = new WriteToFileHandler(outFile, graphDef.Encoding, ((IFormatterBasedWriter)writer).TripleFormatterType);
                            }
                            else
                            {
                                if (this._verbose)
                                {
                                    Console.WriteLine("rdfConvert: Warning: Target Format not suitable for streaming conversion, input data will be loaded into memory prior to conversion");
                                }
                                input.ConversionHandler = new SaveStoreOnCompletionHandler(writer, new StreamWriter(outFile, false, storeDef.Encoding));
                            }
                        }
                    }
                    else
                    {
                        Console.Error.WriteLine("rdfConvert: Warning: Skipping Conversion of Input " + input.ToString() + " as unable to determine how to convert it");
                        continue;
                    }
                }

                //Then do the Conversion
                Console.WriteLine("rdfConvert: Converting Input " + input.ToString() + " to '" + outFile + "'...");
                try
                {
                    if (this._verbose)
                    {
                        input.ConversionHandler = new ConversionProgressHandler(input.ConversionHandler);
                        Console.WriteLine("rdfConvert: Debug: Conversion Handler is " + input.ConversionHandler.GetType().FullName);
                    }
                    input.Convert();
                    Console.WriteLine("rdfConvert: Converted Input " + input.ToString() + " to '" + outFile + "' OK");
                }
                catch (RdfParseException parseEx)
                {
                    Console.Error.WriteLine("rdfConvert: Error: Error Converting Input " + input.ToString() + " due to a RDF Parse Exception");
                    Console.Error.WriteLine(parseEx.Message);
                    if (this._debug)
                    {
                        this.DebugErrors(parseEx);
                    }
                }
                catch (RdfException rdfEx)
                {
                    Console.Error.WriteLine("rdfConvert: Error: Error Converting Input " + input.ToString() + " due to a RDF Exception");
                    Console.Error.WriteLine(rdfEx.Message);
                    if (this._debug)
                    {
                        this.DebugErrors(rdfEx);
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("rdfConvert: Error: Error Converting Input " + input.ToString() + " due to a Unexpected Exception");
                    Console.Error.WriteLine(ex.Message);
                    if (this._debug)
                    {
                        this.DebugErrors(ex);
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Processes SPARQL Update requests
        /// </summary>
        /// <param name="context">HTTP Context</param>
        public void ProcessRequest(HttpContext context)
        {
            this._config = this.LoadConfig(context);

            //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, UriFactory.Create(context.Request.Url.AbsoluteUri));
                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 = context.Request.Form["update"];
                }
                else if (context.Request.ContentType.Equals(MimeTypesHelper.SparqlUpdate))
                {
                    updateText = new StreamReader(context.Request.InputStream).ReadToEnd();
                }
            }
            else
            {
                updateText = context.Request.Form["update"];
            }

            //If no Update sent either show Update Form or give a HTTP 400 response
            if (updateText == null || updateText.Equals(String.Empty))
            {
                //If there is no Update we may return the SPARQL Service Description where appropriate
                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(HandlerHelper.GetAcceptTypes(context)).FirstOrDefault(d => d.CanWriteRdf);
                    if (definition != null)
                    {
                        IRdfWriter writer = definition.GetRdfWriter();
                        if (!this._config.ShowUpdateForm || !(writer is IHtmlWriter))
                        {
                            //If not a HTML Writer selected OR not showing Update Form then show the Service Description Graph
                            //unless an error occurs creating it
                            IGraph serviceDescrip = SparqlServiceDescriber.GetServiceDescription(context, 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
                {
                    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 (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.QueryString["using-named-graph-uri"] != null)
            {
                userNamedGraphs.AddRange(context.Request.QueryString.GetValues("using-named-graph-uri"));
            }
            else if (context.Request.Form["using-named-graph-uri"] != null)
            {
                userNamedGraphs.AddRange(context.Request.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);

                //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 parameters
                foreach (SparqlUpdateCommand cmd in commands.Commands)
                {
                    //Authenticate each action
                    bool actionAuth = true;
                    if (requireActionAuth)
                    {
                        actionAuth = HandlerHelper.IsAuthenticated(context, 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 (Exception ex)
            {
                HandleErrors(context, "Error", updateText, ex);
            }
        }
Пример #11
0
        /// <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);
            }
        }
Пример #12
0
        static void DoQuery(Dictionary <String, String> arguments)
        {
            SparqlRemoteEndpoint endpoint;
            bool verbose = arguments.ContainsKey("verbose") || arguments.ContainsKey("v");

            if (verbose)
            {
                Options.HttpDebugging = true;
            }

            //First get the Server to which we are going to connect
            try
            {
                if (arguments.ContainsKey("server") && !arguments["server"].Equals(String.Empty))
                {
                    endpoint = new SparqlRemoteEndpoint(new Uri(arguments["server"]));
                }
                else if (arguments.ContainsKey("service") && !arguments["service"].Equals(String.Empty))
                {
                    endpoint = new SparqlRemoteEndpoint(new Uri(arguments["service"]));
                }
                else
                {
                    Console.Error.WriteLine("soh: Error: Required --server/--service argument not present");
                    Environment.Exit(-1);
                    return;
                }
            }
            catch (UriFormatException uriEx)
            {
                Console.Error.WriteLine("soh: Error: Malformed SPARQL Endpoint URI");
                Console.Error.WriteLine(uriEx.Message);
                Environment.Exit(-1);
                return;
            }
            if (verbose)
            {
                Console.Error.WriteLine("soh: SPARQL Endpoint for URI " + endpoint.Uri + " created OK");
            }

            //Then decide where to get the query to execute from
            SparqlQueryParser parser = new SparqlQueryParser();
            SparqlQuery       query;

            try
            {
                if (arguments.ContainsKey("query") && !arguments["query"].Equals(String.Empty))
                {
                    query = parser.ParseFromFile(arguments["query"]);
                }
                else if (arguments.ContainsKey("file") && !arguments["file"].Equals(String.Empty))
                {
                    query = parser.ParseFromFile(arguments["file"]);
                }
                else if (arguments.ContainsKey("$1") && !arguments["$1"].Equals(String.Empty))
                {
                    query = parser.ParseFromString(arguments["$1"]);
                }
                else
                {
                    Console.Error.WriteLine("soh: Error: Required SPARQL Query not found - may be specified as --file/--query FILE or as final argument");
                    Environment.Exit(-1);
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("soh: Error: Error Parsing SPARQL Query");
                Console.Error.WriteLine(ex.Message);
                Environment.Exit(-1);
                return;
            }

            if (verbose)
            {
                Console.Error.WriteLine("soh: Parsed Query OK");
                Console.Error.WriteLine("soh: dotNetRDF's interpretation of the Query:");
                SparqlFormatter formatter = new SparqlFormatter();
                Console.Error.WriteLine(formatter.Format(query));
                Console.Error.WriteLine("soh: Submitting Query");
            }

            try
            {
                using (HttpWebResponse response = endpoint.QueryRaw(query.ToString()))
                {
                    MimeTypeDefinition definition = MimeTypesHelper.GetDefinitions(response.ContentType).FirstOrDefault();
                    Encoding           enc;
                    if (definition != null)
                    {
                        enc = definition.Encoding;
                    }
                    else if (!response.ContentEncoding.Equals(String.Empty))
                    {
                        enc = Encoding.GetEncoding(response.ContentEncoding);
                    }
                    else if (response.ContentType.Contains("charset="))
                    {
                        enc = Encoding.GetEncoding(response.ContentType.Substring(response.ContentType.IndexOf('=') + 1));
                    }
                    else
                    {
                        enc = Console.OutputEncoding;
                    }

                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Got Response from SPARQL Endpoint OK");
                        Console.Error.WriteLine("soh: Content-Type: " + response.ContentType);
                        Console.Error.WriteLine("soh: Content-Encoding: " + enc.WebName);
                    }

                    String requestedType = arguments.ContainsKey("accept") ? arguments["accept"] : null;

                    if (requestedType == null || response.ContentType.StartsWith(requestedType, StringComparison.OrdinalIgnoreCase))
                    {
                        //If no --accept (OR matches servers content type) then just return whatever the server has given us
                        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                        {
                            using (StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(), enc))
                            {
                                while (!reader.EndOfStream)
                                {
                                    writer.WriteLine(reader.ReadLine());
                                }
                                writer.Close();
                            }
                            reader.Close();
                        }
                    }
                    else
                    {
                        if (verbose)
                        {
                            Console.Error.WriteLine("soh: Warning: Retrieved Content Type '" + response.ContentType + "' does not match your desired Content Type '" + requestedType + "' so dotNetRDF will not attempt to transcode the response into your desired format");
                        }

                        //Requested Type Doesn't match servers returned type so parse then serialize
                        MimeTypeDefinition outputDefinition;
                        try
                        {
                            ISparqlResultsReader sparqlParser = MimeTypesHelper.GetSparqlParser(response.ContentType);
                            SparqlResultSet      results      = new SparqlResultSet();
                            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                            {
                                sparqlParser.Load(results, reader);
                                reader.Close();
                            }

                            outputDefinition = MimeTypesHelper.GetDefinitions(requestedType).FirstOrDefault(d => d.CanWriteSparqlResults || d.CanWriteRdf);
                            if (outputDefinition == null)
                            {
                                throw new RdfWriterSelectionException("No MIME Type Definition for the MIME Type '" + requestedType + "' was found that can write SPARQL Results/RDF");
                            }
                            ISparqlResultsWriter writer = outputDefinition.GetSparqlResultsWriter();
                            Console.OutputEncoding = outputDefinition.Encoding;
                            writer.Save(results, new StreamWriter(Console.OpenStandardOutput(), outputDefinition.Encoding));
                        }
                        catch (RdfParserSelectionException)
                        {
                            try
                            {
                                IRdfReader rdfParser = MimeTypesHelper.GetParser(response.ContentType);
                                Graph      g         = new Graph();
                                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                                {
                                    rdfParser.Load(g, reader);
                                    reader.Close();
                                }

                                outputDefinition = MimeTypesHelper.GetDefinitions(requestedType).FirstOrDefault(d => d.CanWriteRdf);
                                if (outputDefinition == null)
                                {
                                    throw new RdfWriterSelectionException("No MIME Type Definition for the MIME Type '" + requestedType + "' was found that can write RDF");
                                }
                                IRdfWriter writer = outputDefinition.GetRdfWriter();
                                Console.OutputEncoding = outputDefinition.Encoding;
                                writer.Save(g, new StreamWriter(Console.OpenStandardOutput(), outputDefinition.Encoding));
                            }
                            catch (Exception ex)
                            {
                                //For any other exception show a warning
                                Console.Error.WriteLine("soh: Warning: You wanted results in the format '" + requestedType + "' but the server returned '" + response.ContentType + "' and dotNetRDF was unable to translate the response into your desired format.");
                                Console.Error.WriteLine(ex.Message);
                            }
                        }
                        catch (Exception ex)
                        {
                            //For any other exception show a warning
                            Console.Error.WriteLine("soh: Warning: You wanted results in the format '" + requestedType + "' but the server returned '" + response.ContentType + "' and dotNetRDF was unable to translate the response into your desired format.");
                            Console.Error.WriteLine(ex.Message);
                        }
                    }


                    response.Close();
                }

                if (verbose)
                {
                    Console.Error.WriteLine("soh: Query Completed OK");
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("soh: Error: Error while making the SPARQL Query");
                Console.Error.WriteLine(ex.Message);
                Environment.Exit(-1);
                return;
            }
        }
Пример #13
0
        /// <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);

            //Add our Standard Headers
            HandlerHelper.AddStandardHeaders(context, 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(context, this._config.UserGroups);
            }
            if (!isAuth)
            {
                return;
            }

            //Check whether we can just send a 304 Not Modified
            if (HandlerHelper.CheckCachingHeaders(context, this._config.ETag, null))
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                HandlerHelper.AddCachingHeaders(context, this._config.ETag, null);
                return;
            }

            try
            {
                String[] acceptTypes = HandlerHelper.GetAcceptTypes(context);

                //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(context, 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);
            }
        }
Пример #15
0
        /// <summary>
        /// Handles the start of requests by doing conneg wherever applicable
        /// </summary>
        /// <param name="sender">Sender of the Event</param>
        /// <param name="e">Event Arguments</param>
        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;

            if (app == null)
            {
                return;
            }
            HttpContext context = app.Context;

            if (context == null)
            {
                return;
            }

            if (context.Request.Url.AbsolutePath.Contains("."))
            {
                String actualPath = context.Request.MapPath(context.Request.Path);
                if (!File.Exists(actualPath))
                {
                    //Get the File Extension and see if it is for an RDF format
                    String ext = context.Request.Url.AbsolutePath.Substring(context.Request.Url.AbsolutePath.LastIndexOf("."));
                    switch (ext)
                    {
                    case ".aspx":
                    case ".asmx":
                    case ".ashx":
                    case ".axd":
                        //The above file extensions are special to ASP.Net and so may not actually exist as files
                        //so we need to ignore them for the purposes of negotiating by file extension
                        return;
                    }

                    try
                    {
                        List <MimeTypeDefinition> defs = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeTypes(ext)).ToList();
                        if (defs.Count == 0)
                        {
                            return;
                        }

                        context.Request.Headers["Accept"] = String.Join(",", defs.Select(d => d.CanonicalMimeType).ToArray());
                        String filePath = Path.GetFileNameWithoutExtension(actualPath);
                        if (filePath == null || filePath.Equals(String.Empty))
                        {
                            if (context.Request.Url.AbsolutePath.EndsWith(ext))
                            {
                                filePath = context.Request.Url.AbsolutePath.Substring(0, context.Request.Url.AbsolutePath.Length - ext.Length);
                            }
                        }
                        String query = context.Request.Url.Query;
                        if (query.StartsWith("?"))
                        {
                            query = query.Substring(1);
                        }
                        context.RewritePath(filePath, String.Empty, query, true);
                    }
                    catch (RdfParserSelectionException)
                    {
                        //If we get a RdfParserSelectionException we shouldn't do anything, this fixes bug CORE-94
                    }
                }
            }
        }
Пример #16
0
        protected override TaskResult RunTaskInternal()
        {
            MimeTypeDefinition def = MimeTypesHelper.GetDefinitions(MimeTypesHelper.GetMimeType(Path.GetExtension(this._file))).FirstOrDefault(d => d.CanWriteRdfDatasets);

            if (def == null)
            {
                throw new RdfOutputException("Cannot Export the Store to the selected File since dotNetRDF was unable to select a writer to use based on the File Extension");
            }

            IStoreWriter writer = def.GetRdfDatasetWriter();

            if (writer is IMultiThreadedWriter)
            {
                ((IMultiThreadedWriter)writer).UseMultiThreadedWriting = false;
            }

            TripleStore store = new TripleStore();

            if (writer is TriXWriter)
            {
                //For TriX must load all into memory and then write out all at once
                foreach (Uri u in this.ListGraphs())
                {
                    Graph g = new Graph();
                    this._manager.LoadGraph(g, u);
                    g.BaseUri = u;
                    store.Add(g);
                    this.Information = "Loading into memory prior to export, loaded " + store.Graphs.Sum(x => x.Triples.Count) + " Triple(s) in " + store.Graphs.Count + " Graph(s) so far...";
                    if (this.HasBeenCancelled)
                    {
                        this.Information = "Export Cancelled";
                        return(new TaskResult(true));
                    }
                }
                this.Information = "Exporting Data all at once, have " + store.Graphs.Sum(x => x.Triples.Count) + " Triple(s) in " + store.Graphs.Count + " Graph(s) to export...";
                writer.Save(store, new StreamParams(this._file));
                this.Information = "Exported " + store.Graphs.Sum(x => x.Triples.Count) + " Triple(s) in " + store.Graphs.Count + " Graph(s)";
            }
            else
            {
                if (File.Exists(this._file))
                {
                    File.Delete(this._file);
                }

                //For non-TriX formats assume it is safe to append one Graph at a time to the file
                int graphCount = 0, tripleCount = 0;
                foreach (Uri u in this.ListGraphs())
                {
                    FileStream stream = new FileStream(this._file, FileMode.Append);

                    //Load Graph into memory
                    Graph g = new Graph();
                    g.BaseUri        = u;
                    this.Information = "Loading Graph " + (u != null ? u.ToString() : "Default");
                    this._manager.LoadGraph(g, u);
                    g.BaseUri = u;

                    if (this.HasBeenCancelled)
                    {
                        stream.Close();
                        this.Information = "Export Cancelled, exported " + tripleCount + " Triple(s) in " + graphCount + " Graph(s)";
                        return(new TaskResult(true));
                    }

                    graphCount++;
                    tripleCount += g.Triples.Count;

                    //Save it
                    store.Add(g);
                    writer.Save(store, new StreamParams(stream, def.Encoding));
                    store.Remove(u);

                    this.Information = "Exporting Data graph by graph, exported " + tripleCount + " Triple(s) in " + graphCount + " Graph(s) so far...";
                }
                this.Information = "Exported " + tripleCount + " Triple(s) in " + graphCount + " Graph(s)";
            }

            return(new TaskResult(true));
        }
Пример #17
0
        /// <summary>
        /// Processes SPARQL Update requests
        /// </summary>
        /// <param name="context">HTTP Context</param>
        public void ProcessRequest(HttpContext context)
        {
            this._config = this.LoadConfig(context);

            //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(context.Request.Url.AbsoluteUri));
                HandlerHelper.SendToClient(context, svcDescrip, this._config);
                return;
            }

            //See if there has been an update submitted
            String updateText = context.Request.QueryString["update"];

            if (updateText == null || updateText.Equals(String.Empty))
            {
                updateText = context.Request.Form["update"];
            }

            //If no Update sent either show Update Form or give a HTTP 400 response
            if (updateText == null || updateText.Equals(String.Empty))
            {
                //If there is no Update we may return the SPARQL Service Description where appropriate
                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(HandlerHelper.GetAcceptTypes(context)).FirstOrDefault(d => d.CanWriteRdf);
                    if (definition != null)
                    {
                        IRdfWriter writer = definition.GetRdfWriter();
                        if (!this._config.ShowUpdateForm || !(writer is IHtmlWriter))
                        {
                            //If not a HTML Writer selected OR not showing Update Form then show the Service Description Graph
                            //unless an error occurs creating it
                            IGraph serviceDescrip = SparqlServiceDescriber.GetServiceDescription(context, this._config, new Uri(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
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                }
                return;
            }

            try
            {
                //Now we're going to parse the Updates
                SparqlUpdateParser parser = new SparqlUpdateParser();
                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(context, this._config.UserGroups);
                    requireActionAuth = true;
                }
                if (!isAuth)
                {
                    return;
                }

                //First check actions to see whether they are all permissible
                foreach (SparqlUpdateCommand cmd in commands.Commands)
                {
                    //Authenticate each action
                    bool actionAuth = true;
                    if (requireActionAuth)
                    {
                        actionAuth = HandlerHelper.IsAuthenticated(context, this._config.UserGroups, this.GetPermissionAction(cmd));
                    }
                    if (!actionAuth)
                    {
                        throw new SparqlUpdateException("You are not authorised to perform the " + this.GetPermissionAction(cmd) + " action");
                    }
                }

                //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);
            }
            catch (SparqlUpdateException updateEx)
            {
                HandleErrors(context, "Update Error", updateText, updateEx);
            }
            catch (RdfException rdfEx)
            {
                HandleErrors(context, "RDF Error", updateText, rdfEx);
            }
            catch (Exception ex)
            {
                HandleErrors(context, "Error", updateText, ex);
            }
        }
Пример #18
0
        /// <summary>
        /// Helper function which returns the Results (Graph/Triple Store/SPARQL Results) back to the Client in one of their accepted formats
        /// </summary>
        /// <param name="context">Context of the HTTP Request</param>
        /// <param name="result">Results of the Sparql Query</param>
        /// <param name="config">Handler Configuration</param>
        public static void SendToClient(HttpContext context, Object result, BaseHandlerConfiguration config)
        {
            MimeTypeDefinition definition = null;
            String             ctype      = "text/plain";

            String[] acceptTypes = HandlerHelper.GetAcceptTypes(context);

            //Return the Results
            if (result is SparqlResultSet)
            {
                ISparqlResultsWriter sparqlWriter = null;

                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteSparqlResults);
                }
                //Try and get the registered Definition for SPARQL Results XML
                if (definition == null)
                {
                    definition = MimeTypesHelper.GetDefinitions(MimeTypesHelper.SparqlXml[0]).FirstOrDefault();
                }
                //If Definition is still null create a temporary definition
                if (definition == null)
                {
                    definition = new MimeTypeDefinition("SPARQL Results XML", MimeTypesHelper.SparqlXml, Enumerable.Empty <String>());
                    definition.SparqlResultsWriterType = typeof(VDS.RDF.Writing.SparqlXmlWriter);
                }

                //Set up the Writer appropriately
                sparqlWriter = definition.GetSparqlResultsWriter();
                context.Response.ContentType = definition.CanonicalMimeType;
                HandlerHelper.ApplyWriterOptions(sparqlWriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Result Set to Client
                context.Response.ContentEncoding = definition.Encoding;
                sparqlWriter.Save((SparqlResultSet)result, new StreamWriter(context.Response.OutputStream, definition.Encoding));
            }
            else if (result is IGraph)
            {
                IRdfWriter rdfWriter = null;

                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteRdf);
                }
                if (definition == null)
                {
                    //If no appropriate definition then use the GetWriter method instead
                    rdfWriter = MimeTypesHelper.GetWriter(acceptTypes, out ctype);
                }
                else
                {
                    rdfWriter = definition.GetRdfWriter();
                }

                //Setup the writer
                if (definition != null)
                {
                    ctype = definition.CanonicalMimeType;
                }
                context.Response.ContentType = ctype;
                HandlerHelper.ApplyWriterOptions(rdfWriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Graph to Client
                if (definition != null)
                {
                    context.Response.ContentEncoding = definition.Encoding;
                    rdfWriter.Save((IGraph)result, new StreamWriter(context.Response.OutputStream, definition.Encoding));
                }
                else
                {
                    rdfWriter.Save((IGraph)result, new StreamWriter(context.Response.OutputStream));
                }
            }
            else if (result is ITripleStore)
            {
                IStoreWriter storeWriter = null;

                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteRdfDatasets);
                }
                if (definition == null)
                {
                    //If no appropriate definition then use the GetStoreWriter method instead
                    storeWriter = MimeTypesHelper.GetStoreWriter(acceptTypes, out ctype);
                }
                else
                {
                    storeWriter = definition.GetRdfDatasetWriter();
                }

                //Setup the writer
                if (definition != null)
                {
                    ctype = definition.CanonicalMimeType;
                }
                context.Response.ContentType = ctype;
                HandlerHelper.ApplyWriterOptions(storeWriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Triple Store to Client
                if (definition != null)
                {
                    context.Response.ContentEncoding = definition.Encoding;
                    storeWriter.Save((ITripleStore)result, new VDS.RDF.Storage.Params.StreamParams(context.Response.OutputStream, definition.Encoding));
                }
                else
                {
                    storeWriter.Save((ITripleStore)result, new VDS.RDF.Storage.Params.StreamParams(context.Response.OutputStream));
                }
            }
            else if (result is ISparqlDataset)
            {
                //Wrap in a Triple Store and then call self so the Triple Store writing branch of this if gets called instead
                TripleStore store = new TripleStore(new DatasetGraphCollection((ISparqlDataset)result));
                HandlerHelper.SendToClient(context, store, config);
            }
            else
            {
                throw new RdfOutputException("Unexpected Result Object of Type '" + result.GetType().ToString() + "' returned - unable to write Objects of this Type to the HTTP Response");
            }
        }
Пример #19
0
        static void DoProtocol(Dictionary <String, String> arguments)
        {
            String method;
            SparqlHttpProtocolConnector endpoint;
            bool verbose = arguments.ContainsKey("verbose") || arguments.ContainsKey("v");

            if (verbose)
            {
                Options.HttpDebugging = true;
            }
            Options.UriLoaderCaching = !arguments.ContainsKey("nocache");
            String dataFile;

            //First Argument must be HTTP Method
            if (arguments.ContainsKey("$1") && !arguments["$1"].Equals(String.Empty))
            {
                method = arguments["$1"].ToUpper();
            }
            else
            {
                Console.Error.WriteLine("soh: Error: First argument must be one of head, get, put or post - type soh --help for details");
                Environment.Exit(-1);
                return;
            }

            try
            {
                if (arguments.ContainsKey("$2") && !arguments["$2"].Equals(String.Empty))
                {
                    endpoint = new SparqlHttpProtocolConnector(new Uri(arguments["$2"]));
                }
                else
                {
                    Console.Error.WriteLine("soh: Error: Second argument is required and must be the Dataset URI");
                    Environment.Exit(-1);
                    return;
                }
            }
            catch (UriFormatException uriEx)
            {
                Console.Error.WriteLine("soh: Error: Malformed SPARQL Endpoint URI");
                Console.Error.WriteLine(uriEx.Message);
                Environment.Exit(-1);
                return;
            }
            if (verbose)
            {
                Console.Error.WriteLine("soh: Connection to SPARQL Uniform HTTP Protocol endpoint created OK");
            }

            Uri graphUri;

            try
            {
                if (arguments.ContainsKey("$3") && !arguments["$3"].Equals(String.Empty))
                {
                    if (arguments["$3"].Equals("default"))
                    {
                        graphUri = null;
                        if (verbose)
                        {
                            Console.Error.WriteLine("soh: Graph URI for Protocol request is 'default' (indicates the default unnamed graph)");
                        }
                    }
                    else
                    {
                        graphUri = new Uri(arguments["$3"]);
                        if (verbose)
                        {
                            Console.Error.WriteLine("soh: Graph URI for Protocol request is '" + graphUri.ToString() + "'");
                        }
                    }
                }
                else
                {
                    Console.Error.WriteLine("soh: Error: Third argument is required and must be the Graph URI or default to indicate the default unnamed Graph");
                    Environment.Exit(-1);
                    return;
                }
            }
            catch (UriFormatException uriEx)
            {
                Console.Error.WriteLine("soh: Error: Malformed Graph URI");
                Console.Error.WriteLine(uriEx.Message);
                Environment.Exit(-1);
                return;
            }

            try
            {
                switch (method)
                {
                case "GET":
                    if (arguments.ContainsKey("$4"))
                    {
                        Console.Error.WriteLine("soh: Error: Optional file argument for protocol mode is not permitted with the get method");
                        Environment.Exit(-1);
                        return;
                    }

                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Making a GET request to the Protocol endpoint");
                    }
                    Graph g = new Graph();
                    endpoint.LoadGraph(g, graphUri);
                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Received a Graph with " + g.Triples.Count + " Triples");
                    }

                    //Use users choice of output format otherwise RDF/XML
                    MimeTypeDefinition definition = null;
                    if (arguments.ContainsKey("accept"))
                    {
                        definition = MimeTypesHelper.GetDefinitions(arguments["accept"]).FirstOrDefault(d => d.CanWriteRdf);
                    }

                    if (definition != null)
                    {
                        Console.OutputEncoding = definition.Encoding;
                        IRdfWriter writer = definition.GetRdfWriter();
                        writer.Save(g, new StreamWriter(Console.OpenStandardOutput(), definition.Encoding));
                    }
                    else
                    {
                        if (arguments.ContainsKey("accept") && verbose)
                        {
                            Console.Error.WriteLine("soh: Warning: You wanted output in format '" + arguments["accept"] + "' but dotNetRDF does not support this format so RDF/XML will be returned instead");
                        }

                        RdfXmlWriter rdfXmlWriter = new RdfXmlWriter();
                        rdfXmlWriter.Save(g, new StreamWriter(Console.OpenStandardOutput(), Encoding.UTF8));
                    }

                    break;

                case "HEAD":
                    if (arguments.ContainsKey("$4"))
                    {
                        Console.Error.WriteLine("soh: Error: Optional file argument for protocol mode is not permitted with the head method");
                        Environment.Exit(-1);
                        return;
                    }

                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Making a HEAD request to the Protocol endpoint");
                    }

                    bool exists = endpoint.HasGraph(graphUri);
                    Console.WriteLine(exists.ToString().ToLower());
                    break;

                case "PUT":
                    //Parse in the Graph to be PUT first
                    if (arguments.ContainsKey("$4") && !arguments["$4"].Equals(String.Empty))
                    {
                        dataFile = arguments["$4"];
                    }
                    else
                    {
                        Console.Error.WriteLine("soh: Error: The file argument for protocol mode is required when using the put method");
                        Environment.Exit(-1);
                        return;
                    }
                    Graph toPut = new Graph();
                    FileLoader.Load(toPut, dataFile);
                    toPut.BaseUri = graphUri;

                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Graph to be uploaded has " + toPut.Triples.Count + " Triples");
                        Console.Error.WriteLine("soh: Making a PUT request to the Protocol endpoint");
                    }

                    endpoint.SaveGraph(toPut);
                    Console.WriteLine("soh: Graph saved to Protocol endpoint OK");
                    break;

                case "POST":
                    //Parse in the Graph to be PUT first
                    if (arguments.ContainsKey("$4") && !arguments["$4"].Equals(String.Empty))
                    {
                        dataFile = arguments["$4"];
                    }
                    else
                    {
                        Console.Error.WriteLine("soh: Error: The file argument for protocol mode is required when using the post method");
                        Environment.Exit(-1);
                        return;
                    }
                    Graph toPost = new Graph();
                    FileLoader.Load(toPost, dataFile);

                    if (verbose)
                    {
                        Console.Error.WriteLine("soh: Graph to be uploaded has " + toPost.Triples.Count + " Triples");
                        Console.Error.WriteLine("soh: Making a POST request to the Protocol endpoint");
                    }

                    endpoint.UpdateGraph(graphUri, toPost.Triples, null);
                    Console.WriteLine("soh: Graph updated to Protocol endpoint OK");
                    break;

                case "DELETE":
                    if (arguments.ContainsKey("$4"))
                    {
                        Console.Error.WriteLine("soh: Error: Optional file argument for protocol mode is not permitted with the head method");
                        Environment.Exit(-1);
                        return;
                    }
                    endpoint.DeleteGraph(graphUri);
                    Console.WriteLine("soh: Graph deleted from Protocol endpoint OK");
                    break;

                default:
                    Console.Error.WriteLine("soh: Error: " + method + " is not a HTTP Method supported by this tool");
                    Environment.Exit(-1);
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("soh: Error: Error processing HTTP Protocol request");
                Console.Error.WriteLine(ex.Message);
                while (ex.InnerException != null)
                {
                    Console.Error.WriteLine();
                    Console.Error.WriteLine(ex.InnerException.Message);
                    Console.Error.WriteLine(ex.InnerException.StackTrace);
                    ex = ex.InnerException;
                }
                Environment.Exit(-1);
                return;
            }
        }
Пример #20
0
        // See https://github.com/dotnetrdf/dotnetrdf/blob/5b7fc480346c90eb9b164fb4f8ee09f378442d52/Libraries/dotNetRDF.Web/HandlerHelper.cs#L157
        /// <summary>
        /// Helper function which returns the Results (Graph/Triple Store/SPARQL Results) back to the Client in one of their accepted formats
        /// </summary>
        /// <param name="context">Context of the HTTP Request</param>
        /// <param name="result">Results of the Sparql Query</param>
        /// <param name="config">Handler Configuration</param>
        public static void SendToClient(HttpContext context, SparqlQueryResult result)
        {
            MimeTypeDefinition definition = null;
            const string       TEXT_PLAIN = "text/plain";
            var acceptTypes = context.Request.Headers[HeaderNames.Accept];

            // Return the Results
            if (result.SparqlResultSet != null)
            {
                ISparqlResultsWriter sparqlWriter = null;

                // Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes.Count > 0)
                {
                    definition = MimeTypesHelper.GetDefinitions((IEnumerable <string>)acceptTypes).FirstOrDefault(d => d.CanWriteSparqlResults);
                }
                // Try and get the registered Definition for SPARQL Results XML
                if (definition == null)
                {
                    definition = MimeTypesHelper.GetDefinitions(MimeTypesHelper.SparqlResultsXml[0]).FirstOrDefault();
                }
                // If Definition is still null create a temporary definition
                if (definition == null)
                {
                    definition = new MimeTypeDefinition("SPARQL Results XML", MimeTypesHelper.SparqlResultsXml, Enumerable.Empty <String>());
                    definition.SparqlResultsWriterType = typeof(VDS.RDF.Writing.SparqlXmlWriter);
                }

                // Set up the Writer appropriately
                sparqlWriter = definition.GetSparqlResultsWriter();
                context.Response.ContentType = definition.CanonicalMimeType;
                // HandlerHelper.ApplyWriterOptions(sparqlWriter, config);

                // Send Result Set to Client
                context.Response.Headers[HeaderNames.ContentEncoding] = definition.Encoding.WebName;
                sparqlWriter.Save(result.SparqlResultSet, new StreamWriter(context.Response.Body, definition.Encoding));
            }
            else if (result.Graph != null)
            {
                IRdfWriter rdfWriter = null;
                var        ctype     = TEXT_PLAIN;
                // Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes.Count > 0)
                {
                    definition = MimeTypesHelper.GetDefinitions((IEnumerable <string>)acceptTypes).FirstOrDefault(d => d.CanWriteRdf);
                }
                if (definition == null)
                {
                    // If no appropriate definition then use the GetWriter method instead
                    rdfWriter = MimeTypesHelper.GetWriter((IEnumerable <string>)acceptTypes, out ctype);
                }
                else
                {
                    rdfWriter = definition.GetRdfWriter();
                }

                // Setup the writer
                if (definition != null)
                {
                    ctype = definition.CanonicalMimeType;
                }
                context.Response.ContentType = ctype;
                //HandlerHelper.ApplyWriterOptions(rdfWriter, config);

                // Clear any existing Response
                //context.Response.Clear();

                // Send Graph to Client
                if (definition != null)
                {
                    context.Response.Headers[HeaderNames.ContentEncoding] = definition.Encoding.WebName;
                    rdfWriter.Save(result.Graph, new StreamWriter(context.Response.Body, definition.Encoding));
                }
                else
                {
                    rdfWriter.Save(result.Graph, new StreamWriter(context.Response.Body));
                }
            }
            else
            {
                Debug.Assert(result == SparqlQueryResult.Null);
            }
        }
Пример #21
0
        /// <summary>
        /// Processes a SPARQL Query Request
        /// </summary>
        /// <param name="context">HTTP Context</param>
        public void ProcessRequest(HttpContext context)
        {
            this._config = this.LoadConfig(context);

            //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(context.Request.Url.AbsoluteUri));
                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))
            {
                queryText = context.Request.Form["query"];
            }

            //If no Query sent either show Query Form or give a HTTP 400 response
            if (queryText == null || queryText.Equals(String.Empty))
            {
                //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(context)).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(context, this._config, new Uri(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 Query Form or return a 400 Bad Request
                if (this._config.ShowQueryForm)
                {
                    this.ShowQueryForm(context);
                }
                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 (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.QueryString["named-graph-uri"] != null)
            {
                userNamedGraphs.AddRange(context.Request.QueryString.GetValues("named-graph-uri"));
            }
            else if (context.Request.Form["named-graph-uri"] != null)
            {
                userNamedGraphs.AddRange(context.Request.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 (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;
                }
            }

            try
            {
                //Now we're going to parse the Query
                SparqlQueryParser parser = new SparqlQueryParser(this._config.Syntax);
                parser.ExpressionFactories = this._config.ExpressionFactories;
                parser.QueryOptimiser      = this._config.QueryOptimiser;
                SparqlQuery query = parser.ParseFromString(queryText);
                query.AlgebraOptimisers = this._config.AlgebraOptimisers;

                //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.GetPermissionAction(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(new Uri(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(new Uri(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(new Uri(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 (Exception ex)
            {
                HandleErrors(context, "Error", queryText, ex);
            }
        }