@cryptotaxi247 / kubo / commits / e71dce5df

gateway: fix seeker can't seek on specific files

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Oct 18, 2017 at 20:10 UTC e71dce5dfba3616e5ade4abf0844925389497a56
5 files changed +37 -4
core/corehttp/gateway_handler.go
+12 -1
@@ -268,7 +268,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
268
269 if !dir {
270 name := gopath.Base(urlPath)
271 - http.ServeContent(w, r, name, modtime, dr)
271 + i.serverFile(w, r, name, modtime, dr)
272 return
273 }
274
@@ -372,6 +372,17 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
372 }
373 }
374
375 +func (i *gatewayHandler) serverFile(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) {
376 + http.ServeContent(w, req, name, modtime, content)
377 + //TODO: check for errors in ServeContent.. somehow
378 +
379 + // If http.ServeContent can't figure out content size it won't write it to the
380 + // responseWriter, Content-Length not being set is a good indicator of this
381 + if req.Method != "HEAD" && w.Header().Get("Content-Length") == "" {
382 + io.Copy(w, content)
383 + }
384 +}
385 +
386 func (i *gatewayHandler) postHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
387 p, err := i.api.Unixfs().Add(ctx, r.Body)
388 if err != nil {
test/sharness/t0110-gateway-data/foo.block new
+2
@@ -0,0 +1,2 @@
1 +
2 + foo
\ No newline at end of file
test/sharness/t0110-gateway-data/foofoo.block
Binary files /dev/null and b/test/sharness/t0110-gateway-data/foofoo.block differ
test/sharness/t0110-gateway.sh
+13 -2
@@ -124,7 +124,7 @@ test_expect_success "HEAD 'index.html' has no content" '
124 # test ipfs readonly api
125
126 test_curl_gateway_api() {
127 - curl -sfo actual "http://127.0.0.1:$port/api/v0/$1"
127 + curl -sfo actual "http://127.0.0.1:$port/api/v0/$1"
128 }
129
130 test_expect_success "get IPFS directory file through readonly API succeeds" '
@@ -140,7 +140,7 @@ test_expect_success "refs IPFS directory file through readonly API succeeds" '
140 '
141
142 test_expect_success "test gateway api is sanitized" '
143 -for cmd in "add" "block/put" "bootstrap" "config" "dht" "diag" "dns" "get" "id" "mount" "name/publish" "object/put" "object/new" "object/patch" "pin" "ping" "refs/local" "repo" "resolve" "stats" "swarm" "file" "update" "version" "bitswap"; do
143 + for cmd in "add" "block/put" "bootstrap" "config" "dht" "diag" "dns" "get" "id" "mount" "name/publish" "object/put" "object/new" "object/patch" "pin" "ping" "refs/local" "repo" "resolve" "stats" "swarm" "file" "update" "version" "bitswap"; do
144 test_curl_resp_http_code "http://127.0.0.1:$port/api/v0/$cmd" "HTTP/1.1 404 Not Found"
145 done
146 '
@@ -155,6 +155,17 @@ test_expect_success "try fetching it from gateway" '
155 test_cmp rfile ffile
156 '
157
158 +test_expect_success "Add compact blocks" '
159 + ipfs block put ../t0110-gateway-data/foo.block &&
160 + FOO2_HASH=$(ipfs block put ../t0110-gateway-data/foofoo.block) &&
161 + printf "foofoo" > expected
162 +'
163 +
164 +test_expect_success "GET compact blocks succeeds" '
165 + curl -o actual "http://127.0.0.1:$port/ipfs/$FOO2_HASH" &&
166 + test_cmp expected actual
167 +'
168 +
169 test_kill_ipfs_daemon
170
171 test_done
unixfs/io/pbdagreader.go
+10 -1
@@ -243,7 +243,16 @@ func (dr *pbDagReader) Seek(offset int64, whence int) (int64, error) {
243 return dr.Seek(noffset, io.SeekStart)
244 case io.SeekEnd:
245 noffset := int64(dr.pbdata.GetFilesize()) - offset
246 - return dr.Seek(noffset, io.SeekStart)
246 + n, err := dr.Seek(noffset, io.SeekStart)
247 +
248 + // Return negative number if we can't figure out the file size. Using io.EOF
249 + // for this seems to be good(-enough) solution as it's only returned by
250 + // precalcNextBuf when we step out of file range.
251 + // This is needed for gateway to function properly
252 + if err == io.EOF && *dr.pbdata.Type == ftpb.Data_File {
253 + return -1, nil
254 + }
255 + return n, err
256 default:
257 return 0, errors.New("invalid whence")
258 }