Merge lp:~mattyw/sharinfoo/head-sha into lp:sharinfoo

Proposed by Matthew Williams
Status: Merged
Merged at revision: 12
Proposed branch: lp:~mattyw/sharinfoo/head-sha
Merge into: lp:sharinfoo
Diff against target: 198 lines (+94/-4)
6 files modified
Makefile (+2/-2)
client/client.go (+26/-1)
client/client_test.go (+19/-1)
cmd/shfoo/main.go (+7/-0)
server.go (+26/-0)
tests/client_test.py (+14/-0)
To merge this branch: bzr merge lp:~mattyw/sharinfoo/head-sha
Reviewer Review Type Date Requested Status
Vincenzo Di Somma (community) Approve
Casey Marshall Approve
Review via email: mp+201366@code.launchpad.net

Commit message

Added support for a call to HEAD which will return the sha256 of the file contents.

The return will be base64 encoded

Description of the change

Added support for a call to HEAD which will return the sha256 of the file contents.

The return will be base64 encoded

To post a comment you must log in.
lp:~mattyw/sharinfoo/head-sha updated
22. By Matthew Williams

added -sha to the client, added test for it

Revision history for this message
Casey Marshall (cmars) :
review: Approve
Revision history for this message
Vincenzo Di Somma (vds) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2014-01-10 12:08:44 +0000
+++ Makefile 2014-01-13 14:34:35 +0000
@@ -1,7 +1,7 @@
1check: install1check: install
2 shfood &2 shfood &
3 go test ./...3 -go test ./...
4 python ./tests/client_test.py4 -python ./tests/client_test.py
5 killall shfood5 killall shfood
66
7install:7install:
88
=== modified file 'client/client.go'
--- client/client.go 2014-01-10 11:49:42 +0000
+++ client/client.go 2014-01-13 14:34:35 +0000
@@ -201,5 +201,30 @@
201 }201 }
202 _, err = io.Copy(os.Stdout, resp.Body)202 _, err = io.Copy(os.Stdout, resp.Body)
203 return err203 return err
204 panic("no impl")204}
205
206func Sha(addr, path string) (string, error) {
207 authString, err := loadAuth()
208 if err != nil {
209 return "", err
210 }
211 u := url.URL{
212 Scheme: "http",
213 Host: addr,
214 Path: path,
215 }
216 req, err := http.NewRequest("HEAD", u.String(), nil)
217 if err != nil {
218 return "", err
219 }
220 req.Header.Add("Authorization", authString)
221 resp, err := http.DefaultClient.Do(req)
222 if err != nil {
223 return "", err
224 }
225 if resp.StatusCode != 200 {
226 return "", fmt.Errorf(resp.Status)
227 }
228 sha := resp.Header.Get("Content-sha256")
229 return sha, nil
205}230}
206231
=== modified file 'client/client_test.go'
--- client/client_test.go 2014-01-09 16:41:03 +0000
+++ client/client_test.go 2014-01-13 14:34:35 +0000
@@ -1,6 +1,8 @@
1package client1package client
22
3import (3import (
4 "crypto/sha256"
5 "encoding/base64"
4 "encoding/json"6 "encoding/json"
5 . "launchpad.net/gocheck"7 . "launchpad.net/gocheck"
6 "testing"8 "testing"
@@ -8,7 +10,10 @@
810
9func Test(t *testing.T) { TestingT(t) }11func Test(t *testing.T) { TestingT(t) }
1012
11var addr = "localhost:8080"13var (
14 addr = "localhost:8080"
15 hasher = sha256.New()
16)
1217
13type ClientSuite struct{}18type ClientSuite struct{}
1419
@@ -43,3 +48,16 @@
43 err = Delete(addr, path)48 err = Delete(addr, path)
44 c.Assert(err, IsNil)49 c.Assert(err, IsNil)
45}50}
51
52func (s *ClientSuite) TestHead(c *C) {
53 data := []byte("hello there")
54 path := "/test-data"
55 err := Put(addr, path, data)
56 c.Assert(err, IsNil)
57 hasher.Write(data)
58 expected := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
59
60 sha, err := Sha(addr, path)
61 c.Assert(err, IsNil)
62 c.Assert(sha, Equals, expected)
63}
4664
=== modified file 'cmd/shfoo/main.go'
--- cmd/shfoo/main.go 2014-01-10 11:49:42 +0000
+++ cmd/shfoo/main.go 2014-01-13 14:34:35 +0000
@@ -34,6 +34,7 @@
34var with *string = flag.String("with", "", "Share read-access with user")34var with *string = flag.String("with", "", "Share read-access with user")
35var addr *string = flag.String("http", "localhost:8080", "Remote sharinfoo address")35var addr *string = flag.String("http", "localhost:8080", "Remote sharinfoo address")
36var access *string = flag.String("access", "", "Get list of users with access to this path")36var access *string = flag.String("access", "", "Get list of users with access to this path")
37var sha *string = flag.String("sha", "", "Get the sha256 of the file")
3738
38func die(err error) {39func die(err error) {
39 log.Println(err)40 log.Println(err)
@@ -68,6 +69,12 @@
68 }69 }
69 os.Stdout.Write(output)70 os.Stdout.Write(output)
70 fmt.Println("")71 fmt.Println("")
72 case *sha != "":
73 output, err := client.Sha(*addr, *sha)
74 if err != nil {
75 die(err)
76 }
77 fmt.Println(output)
71 default:78 default:
72 err = fmt.Errorf("No action specified")79 err = fmt.Errorf("No action specified")
73 }80 }
7481
=== modified file 'server.go'
--- server.go 2014-01-09 16:31:27 +0000
+++ server.go 2014-01-13 14:34:35 +0000
@@ -17,6 +17,8 @@
17package sharinfoo17package sharinfoo
1818
19import (19import (
20 "crypto/sha256"
21 "encoding/base64"
20 "encoding/json"22 "encoding/json"
21 "fmt"23 "fmt"
22 "io"24 "io"
@@ -114,6 +116,30 @@
114 if err != nil {116 if err != nil {
115 log.Println(err)117 log.Println(err)
116 }118 }
119 case "HEAD":
120 hasher := sha256.New()
121 access, err := fs.store.Access(userId, path)
122 if err != nil {
123 respError(w, err)
124 return
125 }
126 if !access.CanRead() {
127 respForbidden(w)
128 return
129 }
130 content, err := fs.store.Get(path)
131 if err != nil {
132 respError(w, err)
133 return
134 }
135 _, err = io.Copy(hasher, content)
136 if err != nil {
137 respError(w, err)
138 return
139 }
140 sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
141 w.Header().Add("Content-sha256", sha)
142 w.WriteHeader(http.StatusOK)
117 case "DELETE":143 case "DELETE":
118 access, err := fs.store.Access(userId, path)144 access, err := fs.store.Access(userId, path)
119 if err != nil {145 if err != nil {
120146
=== modified file 'tests/client_test.py'
--- tests/client_test.py 2014-01-10 12:37:33 +0000
+++ tests/client_test.py 2014-01-13 14:34:35 +0000
@@ -4,6 +4,8 @@
4import sys4import sys
5import json5import json
6import unittest6import unittest
7import hashlib
8import base64
79
8sample_data = "sample.txt"10sample_data = "sample.txt"
9test_data = "test.txt"11test_data = "test.txt"
@@ -32,6 +34,12 @@
32 subprocess.check_call(["shfoo", "-delete", "/%s" % path])34 subprocess.check_call(["shfoo", "-delete", "/%s" % path])
3335
3436
37def sha_command(path):
38 out = subprocess.Popen(["shfoo", "-sha", "/%s" % path],
39 stdout=subprocess.PIPE)
40 return out.stdout.read().strip()
41
42
35def access_command(path):43def access_command(path):
36 out = subprocess.Popen(["shfoo", "-access", "/%s" % path],44 out = subprocess.Popen(["shfoo", "-access", "/%s" % path],
37 stdout=subprocess.PIPE)45 stdout=subprocess.PIPE)
@@ -67,5 +75,11 @@
67 out = access_command(test_data)75 out = access_command(test_data)
68 self.assertEquals(out[1]["test123@a.com"], True)76 self.assertEquals(out[1]["test123@a.com"], True)
6977
78 def test_sha(self):
79 sha = hashlib.sha256(open(sample_data).read()).digest()
80 expected = base64.urlsafe_b64encode(sha)
81 out = sha_command(test_data)
82 self.assertEquals(out, expected)
83
70if __name__ == '__main__':84if __name__ == '__main__':
71 unittest.main()85 unittest.main()

Subscribers

People subscribed via source and target branches