我无法让AppEngine Blobstore上传示例正常运行。进一步看,我看到Blobstore.Send()总是返回HTTP 206“部分响应”。
package blobstore_example
import (
"html/template"
"io"
"net/http"
"appengine"
"appengine/blobstore"
)
func serveError(c appengine.Context, w http.ResponseWriter, err error) {
w.WriteHeader(http.StatusInternalServerError)
w.Header().Set("Content-Type", "text/plain")
io.WriteString(w, "Internal Server Error")
c.Errorf("%v", err)
}
var rootTemplate = template.Must(template.New("root").Parse(rootTemplateHTML))
const rootTemplateHTML = `
<html><body>
<form action="{{.}}" method="POST" enctype="multipart/form-data">
Upload File: <input type="file" name="file"><br>
<input type="submit" name="submit" value="Submit">
</form></body></html>
`
func handleRoot(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
uploadURL, err := blobstore.UploadURL(c, "/upload", nil)
if err != nil {
serveError(c, w, err)
return
}
w.Header().Set("Content-Type", "text/html")
err = rootTemplate.Execute(w, uploadURL)
if err != nil {
c.Errorf("%v", err)
}
}
func handleServe(w http.ResponseWriter, r *http.Request) {
blobstore.Send(w, appengine.BlobKey(r.FormValue("blobKey")))
}
func handleUpload(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
blobs, _, err := blobstore.ParseUpload(r)
if err != nil {
serveError(c, w, err)
return
}
file := blobs["file"]
if len(file) == 0 {
c.Errorf("no file uploaded")
http.Redirect(w, r, "/", http.StatusFound)
return
}
http.Redirect(w, r, "/serve/?blobKey="+string(file[0].BlobKey), http.StatusFound)
}
func init() {
http.HandleFunc("/", handleRoot)
http.HandleFunc("/serve/", handleServe)
http.HandleFunc("/upload", handleUpload)
}
Firefox 32不播放此内容并说:
Video can't be played because the file is corrupt.
然而,如果我使用wget保存文件,我会得到包含所有字节的精确mp4文件 - 本地播放器可以播放mp4。
捕获HTTP数据包我发现Firefox并没有要求HTTP请求中的字节范围 - 但Blobstore响应包括:
Content-Range: bytes 0-245778/245779\r\n
(顺便说一句是mp4文件的完整大小)。
那么为什么Blobstore认为它必须返回HTTP 206? ......以及如何不去?