本文整理匯總了Golang中camlistore/org/pkg/blobref.StreamingFetcher.FetchStreaming方法的典型用法代碼示例。如果您正苦於以下問題:Golang StreamingFetcher.FetchStreaming方法的具體用法?Golang StreamingFetcher.FetchStreaming怎麽用?Golang StreamingFetcher.FetchStreaming使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類camlistore/org/pkg/blobref.StreamingFetcher
的用法示例。
在下文中一共展示了StreamingFetcher.FetchStreaming方法的5個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: fetch
func fetch(src blobref.StreamingFetcher, br *blobref.BlobRef) (r io.ReadCloser, err error) {
if *flagVerbose {
log.Printf("Fetching %s", br.String())
}
r, _, err = src.FetchStreaming(br)
if err != nil {
return nil, fmt.Errorf("Failed to fetch %s: %s", br, err)
}
return r, err
}
示例2: serveBlobRef
// serveBlobRef sends 'blobref' to 'conn' as directed by the Range header in 'req'
func serveBlobRef(conn http.ResponseWriter, req *http.Request,
blobRef *blobref.BlobRef, fetcher blobref.StreamingFetcher) {
if w, ok := fetcher.(blobserver.ContextWrapper); ok {
fetcher = w.WrapContext(req)
}
file, size, err := fetcher.FetchStreaming(blobRef)
switch err {
case nil:
break
case os.ErrNotExist:
conn.WriteHeader(http.StatusNotFound)
fmt.Fprintf(conn, "Blob %q not found", blobRef)
return
default:
httputil.ServerError(conn, req, err)
return
}
defer file.Close()
seeker, isSeeker := file.(io.Seeker)
reqRange := httprange.FromRequest(req)
if reqRange.SkipBytes() != 0 && isSeeker {
// TODO: set the Range-specific response headers too,
// acknowledging that we honored the content range
// request.
_, err = seeker.Seek(reqRange.SkipBytes(), 0)
if err != nil {
httputil.ServerError(conn, req, err)
return
}
}
var input io.Reader = file
if reqRange.LimitBytes() != -1 {
input = io.LimitReader(file, reqRange.LimitBytes())
}
remainBytes := size - reqRange.SkipBytes()
if reqRange.LimitBytes() != -1 &&
reqRange.LimitBytes() < remainBytes {
remainBytes = reqRange.LimitBytes()
}
conn.Header().Set("Content-Type", "application/octet-stream")
if reqRange.IsWholeFile() {
conn.Header().Set("Content-Length", strconv.FormatInt(size, 10))
// If it's small and all UTF-8, assume it's text and
// just render it in the browser. This is more for
// demos/debuggability than anything else. It isn't
// part of the spec.
if size <= 32<<10 {
var buf bytes.Buffer
_, err := io.Copy(&buf, input)
if err != nil {
httputil.ServerError(conn, req, err)
return
}
if utf8.Valid(buf.Bytes()) {
conn.Header().Set("Content-Type", "text/plain; charset=utf-8")
}
input = &buf
}
}
if !reqRange.IsWholeFile() {
conn.Header().Set("Content-Range",
fmt.Sprintf("bytes %d-%d/%d", reqRange.SkipBytes(),
reqRange.SkipBytes()+remainBytes,
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
// to verify the digest doesn't match. But we close the (chunked) response anyway,
// to further signal errors.
killConnection := func() {
if hj, ok := conn.(http.Hijacker); ok {
log.Printf("Force-closing TCP connection to signal error sending %q", blobRef)
if closer, _, err := hj.Hijack(); err != nil {
closer.Close()
}
}
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error sending file: %v, err=%v\n", blobRef, err)
killConnection()
return
}
if bytesCopied != remainBytes {
fmt.Fprintf(os.Stderr, "Error sending file: %v, copied=%d, not %d\n", blobRef,
bytesCopied, remainBytes)
killConnection()
//.........這裏部分代碼省略.........
示例3: handleGetViaSharing
// Unauthenticated user. Be paranoid.
func handleGetViaSharing(conn http.ResponseWriter, req *http.Request,
blobRef *blobref.BlobRef, fetcher blobref.StreamingFetcher) {
if req.Method != "GET" && req.Method != "HEAD" {
httputil.BadRequestError(conn, "Invalid method")
return
}
if w, ok := fetcher.(blobserver.ContextWrapper); ok {
fetcher = w.WrapContext(req)
}
viaPathOkay := false
startTime := time.Now()
defer func() {
if !viaPathOkay {
// Insert a delay, to hide timing attacks probing
// for the existence of blobs.
sleep := fetchFailureDelay - (time.Now().Sub(startTime))
time.Sleep(sleep)
}
}()
viaBlobs := make([]*blobref.BlobRef, 0)
if via := req.FormValue("via"); via != "" {
for _, vs := range strings.Split(via, ",") {
if br := blobref.Parse(vs); br == nil {
httputil.BadRequestError(conn, "Malformed blobref in via param")
return
} else {
viaBlobs = append(viaBlobs, br)
}
}
}
fetchChain := make([]*blobref.BlobRef, 0)
fetchChain = append(fetchChain, viaBlobs...)
fetchChain = append(fetchChain, blobRef)
for i, br := range fetchChain {
switch i {
case 0:
file, size, err := fetcher.FetchStreaming(br)
if err != nil {
log.Printf("Fetch chain 0 of %s failed: %v", br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
defer file.Close()
if size > schema.MaxSchemaBlobSize {
log.Printf("Fetch chain 0 of %s too large", br.String())
auth.SendUnauthorized(conn, req)
return
}
blob, err := schema.BlobFromReader(br, file)
if err != nil {
log.Printf("Can't create a blob from %v: %v", br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
share, ok := blob.AsShare()
if !ok {
log.Printf("Fetch chain 0 of %s wasn't a valid Share", br.String())
auth.SendUnauthorized(conn, req)
return
}
if len(fetchChain) > 1 && fetchChain[1].String() != share.Target().String() {
log.Printf("Fetch chain 0->1 (%s -> %q) unauthorized, expected hop to %q",
br.String(), fetchChain[1].String(), share.Target().String())
auth.SendUnauthorized(conn, req)
return
}
case len(fetchChain) - 1:
// Last one is fine (as long as its path up to here has been proven, and it's
// not the first thing in the chain)
continue
default:
file, _, err := fetcher.FetchStreaming(br)
if err != nil {
log.Printf("Fetch chain %d of %s failed: %v", i, br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
defer file.Close()
lr := io.LimitReader(file, schema.MaxSchemaBlobSize)
slurpBytes, err := ioutil.ReadAll(lr)
if err != nil {
log.Printf("Fetch chain %d of %s failed in slurp: %v", i, br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
saught := fetchChain[i+1].String()
if bytes.IndexAny(slurpBytes, saught) == -1 {
log.Printf("Fetch chain %d of %s failed; no reference to %s",
i, br.String(), saught)
auth.SendUnauthorized(conn, req)
return
}
}
}
viaPathOkay = true
//.........這裏部分代碼省略.........
示例4: handleGetViaSharing
// Unauthenticated user. Be paranoid.
func handleGetViaSharing(conn http.ResponseWriter, req *http.Request,
blobRef *blobref.BlobRef, fetcher blobref.StreamingFetcher) {
if w, ok := fetcher.(blobserver.ContextWrapper); ok {
fetcher = w.WrapContext(req)
}
viaPathOkay := false
startTime := time.Now()
defer func() {
if !viaPathOkay {
// Insert a delay, to hide timing attacks probing
// for the existence of blobs.
sleep := fetchFailureDelayNs - (time.Now().Sub(startTime))
if sleep > 0 {
time.Sleep(sleep)
}
}
}()
viaBlobs := make([]*blobref.BlobRef, 0)
if via := req.FormValue("via"); via != "" {
for _, vs := range strings.Split(via, ",") {
if br := blobref.Parse(vs); br == nil {
httputil.BadRequestError(conn, "Malformed blobref in via param")
return
} else {
viaBlobs = append(viaBlobs, br)
}
}
}
fetchChain := make([]*blobref.BlobRef, 0)
fetchChain = append(fetchChain, viaBlobs...)
fetchChain = append(fetchChain, blobRef)
for i, br := range fetchChain {
switch i {
case 0:
file, size, err := fetcher.FetchStreaming(br)
if err != nil {
log.Printf("Fetch chain 0 of %s failed: %v", br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
defer file.Close()
if size > maxJSONSize {
log.Printf("Fetch chain 0 of %s too large", br.String())
auth.SendUnauthorized(conn, req)
return
}
jd := json.NewDecoder(file)
m := make(map[string]interface{})
if err := jd.Decode(&m); err != nil {
log.Printf("Fetch chain 0 of %s wasn't JSON: %v", br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
if m["camliType"].(string) != "share" {
log.Printf("Fetch chain 0 of %s wasn't a share", br.String())
auth.SendUnauthorized(conn, req)
return
}
if len(fetchChain) > 1 && fetchChain[1].String() != m["target"].(string) {
log.Printf("Fetch chain 0->1 (%s -> %q) unauthorized, expected hop to %q",
br.String(), fetchChain[1].String(), m["target"])
auth.SendUnauthorized(conn, req)
return
}
case len(fetchChain) - 1:
// Last one is fine (as long as its path up to here has been proven, and it's
// not the first thing in the chain)
continue
default:
file, _, err := fetcher.FetchStreaming(br)
if err != nil {
log.Printf("Fetch chain %d of %s failed: %v", i, br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
defer file.Close()
lr := io.LimitReader(file, maxJSONSize)
slurpBytes, err := ioutil.ReadAll(lr)
if err != nil {
log.Printf("Fetch chain %d of %s failed in slurp: %v", i, br.String(), err)
auth.SendUnauthorized(conn, req)
return
}
saught := fetchChain[i+1].String()
if bytes.IndexAny(slurpBytes, saught) == -1 {
log.Printf("Fetch chain %d of %s failed; no reference to %s",
i, br.String(), saught)
auth.SendUnauthorized(conn, req)
return
}
}
}
viaPathOkay = true
serveBlobRef(conn, req, blobRef, fetcher)
//.........這裏部分代碼省略.........
示例5: serveBlobRef
// serveBlobRef sends 'blobref' to 'conn' as directed by the Range header in 'req'
func serveBlobRef(conn http.ResponseWriter, req *http.Request,
blobRef *blobref.BlobRef, fetcher blobref.StreamingFetcher) {
if w, ok := fetcher.(blobserver.ContextWrapper); ok {
fetcher = w.WrapContext(req)
}
file, size, err := fetcher.FetchStreaming(blobRef)
switch err {
case nil:
break
case os.ErrNotExist:
conn.WriteHeader(http.StatusNotFound)
fmt.Fprintf(conn, "Blob %q not found", blobRef)
return
default:
httputil.ServerError(conn, req, err)
return
}
defer file.Close()
seeker, isSeeker := file.(io.Seeker)
reqRange := httprange.FromRequest(req)
if reqRange.SkipBytes() != 0 && isSeeker {
// TODO: set the Range-specific response headers too,
// acknowledging that we honored the content range
// request.
_, err = seeker.Seek(reqRange.SkipBytes(), 0)
if err != nil {
httputil.ServerError(conn, req, err)
return
}
}
var input io.Reader = file
if reqRange.LimitBytes() != -1 {
input = io.LimitReader(file, reqRange.LimitBytes())
}
remainBytes := size - reqRange.SkipBytes()
if reqRange.LimitBytes() != -1 &&
reqRange.LimitBytes() < remainBytes {
remainBytes = reqRange.LimitBytes()
}
// Assume this generic content type by default. For better
// demos we'll try to sniff and guess the "right" MIME type in
// certain cases (no Range requests, etc) but this isn't part
// of the Camli spec at all. We just do it to ease demos.
contentType := "application/octet-stream"
if reqRange.IsWholeFile() {
const peekSize = 1024
bufReader := bufio.NewReaderSize(input, peekSize)
header, _ := bufReader.Peek(peekSize)
if len(header) >= 8 {
switch {
case utf8.Valid(header):
contentType = "text/plain; charset=utf-8"
case bytes.HasPrefix(header, []byte{0xff, 0xd8, 0xff, 0xe2}):
contentType = "image/jpeg"
case bytes.HasPrefix(header, []byte{0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa}):
contentType = "image/png"
}
}
input = bufReader
conn.Header().Set("Content-Length", strconv.FormatInt(size, 10))
}
conn.Header().Set("Content-Type", contentType)
if !reqRange.IsWholeFile() {
conn.Header().Set("Content-Range",
fmt.Sprintf("bytes %d-%d/%d", reqRange.SkipBytes(),
reqRange.SkipBytes()+remainBytes,
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
// to verify the digest doesn't match. But we close the (chunked) response anyway,
// to further signal errors.
killConnection := func() {
if hj, ok := conn.(http.Hijacker); ok {
log.Printf("Force-closing TCP connection to signal error sending %q", blobRef)
if closer, _, err := hj.Hijack(); err != nil {
closer.Close()
}
}
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error sending file: %v, err=%v\n", blobRef, err)
killConnection()
return
}
//.........這裏部分代碼省略.........