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
1=== modified file 'Makefile'
2--- Makefile 2014-01-10 12:08:44 +0000
3+++ Makefile 2014-01-13 14:34:35 +0000
4@@ -1,7 +1,7 @@
5 check: install
6 shfood &
7- go test ./...
8- python ./tests/client_test.py
9+ -go test ./...
10+ -python ./tests/client_test.py
11 killall shfood
12
13 install:
14
15=== modified file 'client/client.go'
16--- client/client.go 2014-01-10 11:49:42 +0000
17+++ client/client.go 2014-01-13 14:34:35 +0000
18@@ -201,5 +201,30 @@
19 }
20 _, err = io.Copy(os.Stdout, resp.Body)
21 return err
22- panic("no impl")
23+}
24+
25+func Sha(addr, path string) (string, error) {
26+ authString, err := loadAuth()
27+ if err != nil {
28+ return "", err
29+ }
30+ u := url.URL{
31+ Scheme: "http",
32+ Host: addr,
33+ Path: path,
34+ }
35+ req, err := http.NewRequest("HEAD", u.String(), nil)
36+ if err != nil {
37+ return "", err
38+ }
39+ req.Header.Add("Authorization", authString)
40+ resp, err := http.DefaultClient.Do(req)
41+ if err != nil {
42+ return "", err
43+ }
44+ if resp.StatusCode != 200 {
45+ return "", fmt.Errorf(resp.Status)
46+ }
47+ sha := resp.Header.Get("Content-sha256")
48+ return sha, nil
49 }
50
51=== modified file 'client/client_test.go'
52--- client/client_test.go 2014-01-09 16:41:03 +0000
53+++ client/client_test.go 2014-01-13 14:34:35 +0000
54@@ -1,6 +1,8 @@
55 package client
56
57 import (
58+ "crypto/sha256"
59+ "encoding/base64"
60 "encoding/json"
61 . "launchpad.net/gocheck"
62 "testing"
63@@ -8,7 +10,10 @@
64
65 func Test(t *testing.T) { TestingT(t) }
66
67-var addr = "localhost:8080"
68+var (
69+ addr = "localhost:8080"
70+ hasher = sha256.New()
71+)
72
73 type ClientSuite struct{}
74
75@@ -43,3 +48,16 @@
76 err = Delete(addr, path)
77 c.Assert(err, IsNil)
78 }
79+
80+func (s *ClientSuite) TestHead(c *C) {
81+ data := []byte("hello there")
82+ path := "/test-data"
83+ err := Put(addr, path, data)
84+ c.Assert(err, IsNil)
85+ hasher.Write(data)
86+ expected := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
87+
88+ sha, err := Sha(addr, path)
89+ c.Assert(err, IsNil)
90+ c.Assert(sha, Equals, expected)
91+}
92
93=== modified file 'cmd/shfoo/main.go'
94--- cmd/shfoo/main.go 2014-01-10 11:49:42 +0000
95+++ cmd/shfoo/main.go 2014-01-13 14:34:35 +0000
96@@ -34,6 +34,7 @@
97 var with *string = flag.String("with", "", "Share read-access with user")
98 var addr *string = flag.String("http", "localhost:8080", "Remote sharinfoo address")
99 var access *string = flag.String("access", "", "Get list of users with access to this path")
100+var sha *string = flag.String("sha", "", "Get the sha256 of the file")
101
102 func die(err error) {
103 log.Println(err)
104@@ -68,6 +69,12 @@
105 }
106 os.Stdout.Write(output)
107 fmt.Println("")
108+ case *sha != "":
109+ output, err := client.Sha(*addr, *sha)
110+ if err != nil {
111+ die(err)
112+ }
113+ fmt.Println(output)
114 default:
115 err = fmt.Errorf("No action specified")
116 }
117
118=== modified file 'server.go'
119--- server.go 2014-01-09 16:31:27 +0000
120+++ server.go 2014-01-13 14:34:35 +0000
121@@ -17,6 +17,8 @@
122 package sharinfoo
123
124 import (
125+ "crypto/sha256"
126+ "encoding/base64"
127 "encoding/json"
128 "fmt"
129 "io"
130@@ -114,6 +116,30 @@
131 if err != nil {
132 log.Println(err)
133 }
134+ case "HEAD":
135+ hasher := sha256.New()
136+ access, err := fs.store.Access(userId, path)
137+ if err != nil {
138+ respError(w, err)
139+ return
140+ }
141+ if !access.CanRead() {
142+ respForbidden(w)
143+ return
144+ }
145+ content, err := fs.store.Get(path)
146+ if err != nil {
147+ respError(w, err)
148+ return
149+ }
150+ _, err = io.Copy(hasher, content)
151+ if err != nil {
152+ respError(w, err)
153+ return
154+ }
155+ sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
156+ w.Header().Add("Content-sha256", sha)
157+ w.WriteHeader(http.StatusOK)
158 case "DELETE":
159 access, err := fs.store.Access(userId, path)
160 if err != nil {
161
162=== modified file 'tests/client_test.py'
163--- tests/client_test.py 2014-01-10 12:37:33 +0000
164+++ tests/client_test.py 2014-01-13 14:34:35 +0000
165@@ -4,6 +4,8 @@
166 import sys
167 import json
168 import unittest
169+import hashlib
170+import base64
171
172 sample_data = "sample.txt"
173 test_data = "test.txt"
174@@ -32,6 +34,12 @@
175 subprocess.check_call(["shfoo", "-delete", "/%s" % path])
176
177
178+def sha_command(path):
179+ out = subprocess.Popen(["shfoo", "-sha", "/%s" % path],
180+ stdout=subprocess.PIPE)
181+ return out.stdout.read().strip()
182+
183+
184 def access_command(path):
185 out = subprocess.Popen(["shfoo", "-access", "/%s" % path],
186 stdout=subprocess.PIPE)
187@@ -67,5 +75,11 @@
188 out = access_command(test_data)
189 self.assertEquals(out[1]["test123@a.com"], True)
190
191+ def test_sha(self):
192+ sha = hashlib.sha256(open(sample_data).read()).digest()
193+ expected = base64.urlsafe_b64encode(sha)
194+ out = sha_command(test_data)
195+ self.assertEquals(out, expected)
196+
197 if __name__ == '__main__':
198 unittest.main()

Subscribers

People subscribed via source and target branches