mirror of https://github.com/perkeep/perkeep.git
Merge branch 'master' of danga.com:camlistore
This commit is contained in:
commit
891a4d7434
|
@ -29,8 +29,36 @@ func handleGet(conn *http.Conn, req *http.Request) {
|
|||
serverError(conn, err)
|
||||
return
|
||||
}
|
||||
|
||||
reqRange := getRequestedRange(req)
|
||||
if reqRange.SkipBytes != 0 {
|
||||
_, err = file.Seek(reqRange.SkipBytes, 0)
|
||||
if err != nil {
|
||||
serverError(conn, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var input io.Reader = file
|
||||
if reqRange.LimitBytes != -1 {
|
||||
input = io.LimitReader(file, reqRange.LimitBytes)
|
||||
}
|
||||
|
||||
remainBytes := stat.Size - reqRange.SkipBytes
|
||||
if reqRange.LimitBytes != -1 &&
|
||||
reqRange.LimitBytes < remainBytes {
|
||||
remainBytes = reqRange.LimitBytes
|
||||
}
|
||||
|
||||
conn.SetHeader("Content-Type", "application/octet-stream")
|
||||
bytesCopied, err := io.Copy(conn, file)
|
||||
if !reqRange.IsWholeFile() {
|
||||
conn.SetHeader("Content-Range",
|
||||
fmt.Sprintf("bytes %d-%d/%d", reqRange.SkipBytes,
|
||||
reqRange.SkipBytes + remainBytes,
|
||||
stat.Size))
|
||||
conn.WriteHeader(http.StatusPartialContent)
|
||||
}
|
||||
bytesCopied, err := io.Copy(conn, input)
|
||||
|
||||
// If there's an error at this point, it's too late to tell the client,
|
||||
// as they've already been receiving bytes. But they should be smart enough
|
||||
|
@ -44,9 +72,9 @@ func handleGet(conn *http.Conn, req *http.Request) {
|
|||
}
|
||||
return
|
||||
}
|
||||
if bytesCopied != stat.Size {
|
||||
fmt.Fprintf(os.Stderr, "Error sending file: %v, copied= %d, not %d%v\n", blobRef,
|
||||
bytesCopied, stat.Size)
|
||||
if bytesCopied != remainBytes {
|
||||
fmt.Fprintf(os.Stderr, "Error sending file: %v, copied=%d, not %d\n", blobRef,
|
||||
bytesCopied, remainBytes)
|
||||
closer, _, err := conn.Hijack()
|
||||
if err != nil {
|
||||
closer.Close()
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Default is {0, -1} to read all of a file.
|
||||
type requestedRange struct {
|
||||
SkipBytes int64
|
||||
LimitBytes int64 // or -1 to read all
|
||||
}
|
||||
|
||||
func (rr *requestedRange) IsWholeFile() bool {
|
||||
return rr.SkipBytes == 0 && rr.LimitBytes == -1;
|
||||
}
|
||||
|
||||
var wholeRange = &requestedRange{0, -1}
|
||||
|
||||
var rangePattern = regexp.MustCompile(`bytes=([0-9]+)-([0-9]*)`)
|
||||
|
||||
func getRequestedRange(req *http.Request) *requestedRange {
|
||||
rrange, ok := req.Header["Range"]
|
||||
if !ok {
|
||||
return wholeRange
|
||||
}
|
||||
return getRequestedRangeFromString(rrange)
|
||||
}
|
||||
|
||||
func getRequestedRangeFromString(rrange string) *requestedRange {
|
||||
matches := rangePattern.MatchStrings(rrange)
|
||||
if len(matches) == 0 {
|
||||
return wholeRange;
|
||||
}
|
||||
skipBytes, _ := strconv.Atoi64(matches[1])
|
||||
lastByteInclusive := int64(-1)
|
||||
if len(matches[2]) > 0 {
|
||||
lastByteInclusive, _ = strconv.Atoi64(matches[2])
|
||||
}
|
||||
limitBytes := int64(-1)
|
||||
if lastByteInclusive != -1 {
|
||||
limitBytes = lastByteInclusive - skipBytes + 1
|
||||
if limitBytes < 0 {
|
||||
limitBytes = 0
|
||||
}
|
||||
}
|
||||
return &requestedRange{skipBytes, limitBytes}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func testRange(t *t.Testing) {
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Lame upload script for development testing only. Doesn't do the
|
||||
# preupload step and hard-codes the Go server's upload path (not
|
||||
# conformant to spec).
|
||||
|
||||
use strict;
|
||||
my $file = shift or die
|
||||
"Usage: upload-file.pl: <file>";
|
||||
-r $file or die "$file isn't readable.";
|
||||
-f $file or die "$file isn't a file.";
|
||||
|
||||
die "bogus filename" if $file =~ /[ <>&\!]/;
|
||||
|
||||
my $sha1 = `sha1sum $file`;
|
||||
chomp $sha1;
|
||||
$sha1 =~ s/\s.+//;
|
||||
|
||||
system("curl", "-u", "foo:foo", "-F", "sha1-$sha1=\@$file",
|
||||
"http://127.0.0.1:3179/camli/upload") and die "upload failed.";
|
||||
print "Uploaded http://127.0.0.1:3179/camli/sha1-$sha1\n";
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
curl -u foo:foo -F sha1-7c63f74bbe0b1de55ec41ad0d9297a3762ecfdbc=@/bin/true http://127.0.0.1:3179/camli/upload
|
||||
|
Loading…
Reference in New Issue