Browse Source

Merge branch 'master' into fix/issue92

Andrei 4 years ago
parent
commit
83c79138d2
11 changed files with 313 additions and 154 deletions
  1. 2 0
      .gitignore
  2. 11 4
      .travis.yml
  3. 115 0
      Gopkg.lock
  4. 58 0
      Gopkg.toml
  5. 42 26
      README.md
  6. 47 82
      graph.go
  7. 5 5
      graph_test.go
  8. 14 16
      mime.go
  9. 0 2
      server.go
  10. 11 11
      smtp_test.go
  11. 8 8
      webid.go

+ 2 - 0
.gitignore

@@ -1,3 +1,5 @@
 _bench
 coverage.out
 gold.conf
+.idea
+vendor

+ 11 - 4
.travis.yml

@@ -1,9 +1,16 @@
 language: go
-go: 1.5.1
-install: go get -t -v ./...
+
+go:
+- 1.10.x
+
 before_install:
- - sudo apt-get update -qq
- - sudo apt-get install -qq libraptor2-dev libmagic-dev
+- sudo apt-get update -qq
+- sudo apt-get install -qq libraptor2-dev libmagic-dev
+- go get -u github.com/golang/dep/...
+- dep ensure
+
+script:
+- go test ./...
 
 notifications:
   webhooks:

+ 115 - 0
Gopkg.lock

@@ -0,0 +1,115 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  digest = "1:0f98f59e9a2f4070d66f0c9c39561f68fcd1dc837b22a852d28d0003aebd1b1e"
+  name = "github.com/boltdb/bolt"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8"
+  version = "v1.3.1"
+
+[[projects]]
+  digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
+  name = "github.com/davecgh/go-spew"
+  packages = ["spew"]
+  pruneopts = "UT"
+  revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
+  version = "v1.1.1"
+
+[[projects]]
+  digest = "1:2b7b174ae68705866555b73fd848de0749b93b1f99e3295e27f89bebe8702203"
+  name = "github.com/elazarl/goproxy"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "947c36da3153ff334e74d9d980de341d25f358ba"
+  version = "v1.1"
+
+[[projects]]
+  branch = "master"
+  digest = "1:d4d1295925d5dfab49954082388dd3556860fa2daa70df9775a6d5bfec6c5054"
+  name = "github.com/gabriel-vasile/mimetype"
+  packages = [
+    ".",
+    "matchers",
+  ]
+  pruneopts = "UT"
+  revision = "d4f1602c882009c84583421e8f6e124d3eca176e"
+
+[[projects]]
+  digest = "1:e72d1ebb8d395cf9f346fd9cbc652e5ae222dd85e0ac842dc57f175abed6d195"
+  name = "github.com/gorilla/securecookie"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983"
+  version = "v1.1.1"
+
+[[projects]]
+  branch = "master"
+  digest = "1:b7d73b96db1c3cd12fcf58c80c4226784cca158b96b8e7d2db0795c3dcfb4c88"
+  name = "github.com/linkeddata/gojsonld"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "4f5db6791326b8962ede4edbba693edcf20fd1ad"
+
+[[projects]]
+  digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
+  name = "github.com/pmezard/go-difflib"
+  packages = ["difflib"]
+  pruneopts = "UT"
+  revision = "792786c7400a136282c1664665ae0a8db921c6c2"
+  version = "v1.0.0"
+
+[[projects]]
+  branch = "master"
+  digest = "1:cb671a4d71ede584c1584051326929ba4fb0d0653650c26a24df04e4b6e7060c"
+  name = "github.com/presbrey/goraptor"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "d14aff371f65d19049be51de3b604f22a2ca853e"
+
+[[projects]]
+  digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83"
+  name = "github.com/stretchr/testify"
+  packages = ["assert"]
+  pruneopts = "UT"
+  revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
+  version = "v1.2.2"
+
+[[projects]]
+  branch = "master"
+  digest = "1:da939eb838c6b235621e8551297b050c2e32f1b5400ca6bab0ced87c7827ed81"
+  name = "golang.org/x/net"
+  packages = [
+    "context",
+    "webdav",
+    "webdav/internal/xml",
+    "websocket",
+  ]
+  pruneopts = "UT"
+  revision = "4dfa2610cdf3b287375bbba5b8f2a14d3b01d8de"
+
+[[projects]]
+  branch = "master"
+  digest = "1:e2ced6fdf654069e8713c96012275fbd245381673d53e8c8ace640b28441a28b"
+  name = "golang.org/x/sys"
+  packages = ["unix"]
+  pruneopts = "UT"
+  revision = "e4b3c5e9061176387e7cea65e4dc5853801f3fb7"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  input-imports = [
+    "github.com/boltdb/bolt",
+    "github.com/elazarl/goproxy",
+    "github.com/gabriel-vasile/mimetype",
+    "github.com/gorilla/securecookie",
+    "github.com/linkeddata/gojsonld",
+    "github.com/presbrey/goraptor",
+    "github.com/stretchr/testify/assert",
+    "golang.org/x/net/webdav",
+    "golang.org/x/net/websocket",
+  ]
+  solver-name = "gps-cdcl"
+  solver-version = 1

+ 58 - 0
Gopkg.toml

@@ -0,0 +1,58 @@
+# Gopkg.toml example
+#
+# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+#   name = "github.com/user/project"
+#   version = "1.0.0"
+#
+# [[constraint]]
+#   name = "github.com/user/project2"
+#   branch = "dev"
+#   source = "github.com/myfork/project2"
+#
+# [[override]]
+#   name = "github.com/x/y"
+#   version = "2.4.0"
+#
+# [prune]
+#   non-go = false
+#   go-tests = true
+#   unused-packages = true
+
+
+[[constraint]]
+  name = "github.com/boltdb/bolt"
+  version = "1.3.1"
+
+[[constraint]]
+  name = "github.com/elazarl/goproxy"
+  version = "1.1.0"
+
+[[constraint]]
+  name = "github.com/gorilla/securecookie"
+  version = "1.1.1"
+
+[[constraint]]
+  branch = "master"
+  name = "github.com/linkeddata/gojsonld"
+
+[[constraint]]
+  branch = "master"
+  name = "github.com/presbrey/goraptor"
+
+[[constraint]]
+  name = "github.com/stretchr/testify"
+  version = "1.2.2"
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/net"
+
+[prune]
+  go-tests = true
+  unused-packages = true

+ 42 - 26
README.md

@@ -1,5 +1,5 @@
 # gold
-
+   
 [![](https://img.shields.io/badge/project-Solid-7C4DFF.svg?style=flat-square)](https://github.com/solid/solid)
 [![Join the chat at https://gitter.im/linkeddata/gold](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/linkeddata/gold?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 
@@ -15,54 +15,69 @@ Written in Go, based on
 
 ### From docker repository:
 
-    sudo docker pull linkeddata/gold
-
-    sudo docker run -p ip:port:443 linkeddata/gold
-
+```
+sudo docker pull linkeddata/gold
+sudo docker run -p ip:port:443 linkeddata/gold
+```
 Replace `ip` and `port` with your host computer's IP address and port number.
 
 To check the status of the container, type:
 
-    sudo docker ps
+```
+sudo docker ps
+```
 
 `IMPORTANT`: if you want to mount a host directory into the container, you can use the -v parameter:
 
-    sudo docker run -p ip:port:443 -v /home/user/data:/data linkeddata/gold
+```
+sudo docker run -p ip:port:443 -v /home/user/data:/data linkeddata/gold
+```
 
 This will mount the host directory, `/home/user/data`, into the container as the `/data/` directory. Doing this will allow you to reuse the data directory without worrying about persistence inside the container.
 
 ### From Github:
 
-1. Setup Go + dependencies:
+1. Setup Go:
 
-  * **Mac OS X**: `brew install go raptor libmagic`
-  * **Ubuntu**: `sudo apt-get install golang-go libraptor2-dev libmagic-dev`
+    * **Mac OS X**: `brew install go`
+    * **Ubuntu**: `sudo apt-get install golang-go`
+    * **Fedora**: `sudo dnf install golang`
 
-2. Set the `GOPATH` variable (required by Go):
+1. Set the `GOPATH` variable (required by Go):
 
-  ```bash
-  mkdir ~/go
-  export GOPATH=~/go
-  ```
+      ```bash
+      mkdir ~/go
+      export GOPATH=~/go
+      ```
+    
+      (Optionally consider adding `export GOPATH=~/go` to your `.bashrc` or profile).
 
-  (Optionally consider adding `export GOPATH=~/go` to your `.bashrc` or profile).
+1. Check that you have the required Go version (**Go 1.4 or later**):
 
-3. Check that you have the required Go version (**Go 1.4 or later**):
+      ```
+      go version
+      ```
+    
+      If you don't, please [install](http://golang.org/doc/install) a more recent
+      version.
 
-  ```
-  go version
-  ```
-
-  If you don't, please [install](http://golang.org/doc/install) a more recent
-  version.
-
-4. Use the `go get` command to install the server and all the dependencies:
+1. Use the `go get` command to install the server and all the dependencies:
 
+    ```
     go get github.com/linkeddata/gold/server
+    ```
+    
+1. Install dependencies:
+    * **Mac OS X**: `brew install raptor libmagic`
+    * **Ubuntu**: `sudo apt-get install libraptor2-dev libmagic-dev`
+    * **Fedora**: `sudo dnf install raptor2-devel file-devel`
+  
 
-5. (Optional) Install extra dependencies used by the tests:
+1. (Optional) Install extra dependencies used by the tests:
 
+    ```
     go get github.com/stretchr/testify/assert
+    ```
 
 ## Running the Server
 
@@ -103,6 +118,7 @@ Something like: `-root=/var/www/data/` or `-root=~/data/`.
     -root=/home/user/data/ -debug -boltPath=/tmp/bolt.db
   ```
 
+
 ## Configuration
 
 You can use the provided `gold.conf-example` file to create your own

+ 47 - 82
graph.go

@@ -54,11 +54,11 @@ func NewGraph(uri string) *Graph {
 	if uri[:5] != "http:" && uri[:6] != "https:" {
 		panic(uri)
 	}
+
 	return &Graph{
 		triples: make(map[*Triple]bool),
-
-		uri:  uri,
-		term: NewResource(uri),
+		uri:     uri,
+		term:    NewResource(uri),
 	}
 }
 
@@ -110,37 +110,7 @@ func jterm2term(term jsonld.Term) Term {
 // One returns one triple based on a triple pattern of S, P, O objects
 func (g *Graph) One(s Term, p Term, o Term) *Triple {
 	for triple := range g.IterTriples() {
-		if s != nil {
-			if p != nil {
-				if o != nil {
-					if triple.Subject.Equal(s) && triple.Predicate.Equal(p) && triple.Object.Equal(o) {
-						return triple
-					}
-				} else {
-					if triple.Subject.Equal(s) && triple.Predicate.Equal(p) {
-						return triple
-					}
-				}
-			} else {
-				if triple.Subject.Equal(s) {
-					return triple
-				}
-			}
-		} else if p != nil {
-			if o != nil {
-				if triple.Predicate.Equal(p) && triple.Object.Equal(o) {
-					return triple
-				}
-			} else {
-				if triple.Predicate.Equal(p) {
-					return triple
-				}
-			}
-		} else if o != nil {
-			if triple.Object.Equal(o) {
-				return triple
-			}
-		} else {
+		if isNilOrEquals(s, triple.Subject) && isNilOrEquals(p, triple.Predicate) && isNilOrEquals(o, triple.Object) {
 			return triple
 		}
 	}
@@ -178,36 +148,12 @@ func (g *Graph) Remove(t *Triple) {
 func (g *Graph) All(s Term, p Term, o Term) []*Triple {
 	var triples []*Triple
 	for triple := range g.IterTriples() {
-		if s != nil {
-			if p != nil {
-				if o != nil {
-					if triple.Subject.Equal(s) && triple.Predicate.Equal(p) && triple.Object.Equal(o) {
-						triples = append(triples, triple)
-					}
-				} else {
-					if triple.Subject.Equal(s) && triple.Predicate.Equal(p) {
-						triples = append(triples, triple)
-					}
-				}
-			} else {
-				if triple.Subject.Equal(s) {
-					triples = append(triples, triple)
-				}
-			}
-		} else if p != nil {
-			if o != nil {
-				if triple.Predicate.Equal(p) && triple.Object.Equal(o) {
-					triples = append(triples, triple)
-				}
-			} else {
-				if triple.Predicate.Equal(p) {
-					triples = append(triples, triple)
-				}
-			}
-		} else if o != nil {
-			if triple.Object.Equal(o) {
-				triples = append(triples, triple)
-			}
+		if s == nil && p == nil && o == nil {
+			continue
+		}
+
+		if isNilOrEquals(s, triple.Subject) && isNilOrEquals(p, triple.Predicate) && isNilOrEquals(o, triple.Object) {
+			triples = append(triples, triple)
 		}
 	}
 	return triples
@@ -215,11 +161,7 @@ func (g *Graph) All(s Term, p Term, o Term) []*Triple {
 
 // AddStatement adds a Statement object
 func (g *Graph) AddStatement(st *crdf.Statement) {
-	s, p, o := term2term(st.Subject), term2term(st.Predicate), term2term(st.Object)
-	for range g.All(s, p, o) {
-		return
-	}
-	g.AddTriple(s, p, o)
+	g.AddTriple(term2term(st.Subject), term2term(st.Predicate), term2term(st.Object))
 }
 
 // Parse is used to parse RDF data from a reader, using the provided mime type
@@ -228,10 +170,20 @@ func (g *Graph) Parse(reader io.Reader, mime string) {
 	if len(parserName) == 0 {
 		parserName = "guess"
 	}
+
 	if parserName == "jsonld" {
 		buf := new(bytes.Buffer)
-		buf.ReadFrom(reader)
+		if _, err := buf.ReadFrom(reader); err != nil {
+			log.Println(err)
+			return
+		}
+
 		jsonData, err := jsonld.ReadJSON(buf.Bytes())
+		if err != nil {
+			log.Println(err)
+			return
+		}
+
 		options := &jsonld.Options{}
 		options.Base = ""
 		options.ProduceGeneralizedRdf = false
@@ -240,20 +192,22 @@ func (g *Graph) Parse(reader io.Reader, mime string) {
 			log.Println(err)
 			return
 		}
+
 		for t := range dataSet.IterTriples() {
 			g.AddTriple(jterm2term(t.Subject), jterm2term(t.Predicate), jterm2term(t.Object))
 		}
 
-	} else {
-		parser := crdf.NewParser(parserName)
-		parser.SetLogHandler(func(level int, message string) {
-			log.Println(message)
-		})
-		defer parser.Free()
-		out := parser.Parse(reader, g.uri)
-		for s := range out {
-			g.AddStatement(s)
-		}
+		return
+	}
+
+	parser := crdf.NewParser(parserName)
+	parser.SetLogHandler(func(level int, message string) {
+		log.Println(message)
+	})
+	defer parser.Free()
+
+	for s := range parser.Parse(reader, g.uri) {
+		g.AddStatement(s)
 	}
 }
 
@@ -279,9 +233,11 @@ func (g *Graph) ReadFile(filename string) {
 	stat, err := os.Stat(filename)
 	if os.IsNotExist(err) {
 		return
-	} else if stat.IsDir() {
+	}
+	if stat.IsDir() {
 		return
-	} else if !stat.IsDir() && err != nil {
+	}
+	if !stat.IsDir() && err != nil {
 		log.Println(err)
 		return
 	}
@@ -482,3 +438,12 @@ func (g *Graph) JSONPatch(r io.Reader) error {
 	}
 	return nil
 }
+
+// isNilOrEquals is a helper function returns true if first term is nil, otherwise checks equality
+func isNilOrEquals(t1 Term, t2 Term) bool {
+	if t1 == nil {
+		return true
+	}
+
+	return t2.Equal(t1)
+}

+ 5 - 5
graph_test.go

@@ -86,9 +86,9 @@ func TestGraphAll(t *testing.T) {
 	g.AddTriple(NewResource("g"), NewResource("b2"), NewResource("e"))
 	g.AddTriple(NewResource("g"), NewResource("b2"), NewResource("c"))
 
-	assert.Equal(t, len(g.All(nil, nil, nil)), 0)
-	assert.Equal(t, len(g.All(NewResource("a"), nil, nil)), 3)
-	assert.Equal(t, len(g.All(nil, NewResource("b"), nil)), 2)
-	assert.Equal(t, len(g.All(nil, nil, NewResource("d"))), 1)
-	assert.Equal(t, len(g.All(nil, nil, NewResource("c"))), 2)
+	assert.Equal(t, 0, len(g.All(nil, nil, nil)))
+	assert.Equal(t, 3, len(g.All(NewResource("a"), nil, nil)))
+	assert.Equal(t, 2, len(g.All(nil, NewResource("b"), nil)))
+	assert.Equal(t, 1, len(g.All(nil, nil, NewResource("d"))))
+	assert.Equal(t, 2, len(g.All(nil, nil, NewResource("c"))))
 }

+ 14 - 16
mime.go

@@ -2,11 +2,13 @@ package gold
 
 import (
 	"errors"
-	crdf "github.com/presbrey/goraptor"
+	"fmt"
 	"mime"
 	"path/filepath"
 
-	"github.com/rakyll/magicmime"
+	"github.com/gabriel-vasile/mimetype"
+	crdf "github.com/presbrey/goraptor"
+
 	"regexp"
 	"sync"
 )
@@ -76,25 +78,21 @@ func init() {
 		}
 		serializerMimes = append(serializerMimes, mime)
 	}
-
-	magicmime.Open(magicmime.MAGIC_MIME_TYPE)
 }
 
-func GuessMimeType(path string) (mimeType string, err error) {
-	// Get the mime type of the file. In some cases, MagicMime
-	// returns an empty string, and in rare cases (about 1 in 10000),
-	// it returns unprintable characters. These are not valid mime
-	// types and cause ingest to fail. So we default to the safe
-	// text/plain and then set the MimeType only if
-	// MagicMime returned something that looks legit.
-	// Open the Mime Magic DB only once.
-	mimeType = "text/plain"
-	mutex.Lock()
-	guessedType, _ := magicmime.TypeByFile(path)
-	mutex.Unlock()
+func GuessMimeType(path string) (string, error) {
+	mimeType := "text/plain"
+
+	guessedType, _, err := mimetype.DetectFile(path)
+	if err != nil {
+		fmt.Printf("Unknown mimeType from file: %s ==> %s", path, err)
+		return mimeType, err
+	}
+
 	if guessedType != "" && validMimeType.MatchString(guessedType) {
 		mimeType = guessedType
 	}
+
 	return mimeType, nil
 }
 

+ 0 - 2
server.go

@@ -45,8 +45,6 @@ var (
 	debugFlags  = log.Flags() | log.Lshortfile
 	debugPrefix = "[debug] "
 
-	// magic *magicmime.Magic
-
 	methodsAll = []string{
 		"OPTIONS", "HEAD", "GET",
 		"PATCH", "POST", "PUT", "MKCOL", "DELETE",

+ 11 - 11
smtp_test.go

@@ -192,14 +192,14 @@ func TestFakeSMTPDial(t *testing.T) {
 	assert.NoError(t, err)
 }
 
-func TestFakeSMTPSecureDial(t *testing.T) {
-	t.Parallel()
-	// give the server some time to start
-	time.Sleep(200 * time.Millisecond)
-	tlsconfig := &tls.Config{
-		InsecureSkipVerify: true,
-		ServerName:         "localhost",
-	}
-	_, err := tls.Dial("tcp", "localhost:3030", tlsconfig)
-	assert.NoError(t, err)
-}
+//func TestFakeSMTPSecureDial(t *testing.T) {
+//	t.Parallel()
+//	// give the server some time to start
+//	time.Sleep(200 * time.Millisecond)
+//	tlsconfig := &tls.Config{
+//		InsecureSkipVerify: true,
+//		ServerName:         "localhost",
+//	}
+//	_, err := tls.Dial("tcp", "localhost:3030", tlsconfig)
+//	assert.NoError(t, err)
+//}

+ 8 - 8
webid.go

@@ -491,15 +491,15 @@ func (req *httpRequest) AddWorkspaces(account webidAccount, g *Graph) error {
 		}
 
 		// Append workspace URL to the preferencesFile
-		if ws.Name != "Inbox" || ws.Name != "Timeline" {
-			pref.AddTriple(wsTerm, ns.rdf.Get("type"), ns.space.Get("Workspace"))
-			if len(ws.Type) > 0 {
-				pref.AddTriple(wsTerm, ns.rdf.Get("type"), ns.space.Get(ws.Type))
-			}
-			pref.AddTriple(wsTerm, ns.dct.Get("title"), NewLiteral(ws.Label))
-
-			pref.AddTriple(NewResource(account.WebID), ns.space.Get("workspace"), wsTerm)
+		//if ws.Name != "Inbox" || ws.Name != "Timeline" { <- this assertion is always true ...
+		pref.AddTriple(wsTerm, ns.rdf.Get("type"), ns.space.Get("Workspace"))
+		if len(ws.Type) > 0 {
+			pref.AddTriple(wsTerm, ns.rdf.Get("type"), ns.space.Get(ws.Type))
 		}
+		pref.AddTriple(wsTerm, ns.dct.Get("title"), NewLiteral(ws.Label))
+
+		pref.AddTriple(NewResource(account.WebID), ns.space.Get("workspace"), wsTerm)
+		//}
 	}
 
 	resource, _ := req.pathInfo(account.PrefURI)