func upload(w http.ResponseWriter, r *http.Request) { // I dunno it'd just be cool to see where we are in our code from the server should prolly just delete this fmt.Println("handling file upload", r.Method) if r.Method == "POST" { // debugging only fmt.Println("We've got a POST")
r.ParseMultipartForm(32 << 20) file, handler, err := r.FormFile("uploadfile") if err != nil { fmt.Println("FormFile: ", err) return }
// Meat and potatoes - the only reason this method exists fileURL, err := storage.UploadFileToBucket(file, handler, bucketID) if err != nil { fmt.Println("UploadFileToBucket: ", err) }
// I think clients would appreciate if we told them that we created something w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]string{"url": fileURL}) } else { // You can't expect me to create a resource - Do you GET me? err := fmt.Errorf("Method is not supported, %s\n", r.Method) fmt.Print(err)
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) }}
no such file
r.FormFile
unexpected EOF
func uploadLarge(w http.ResponseWriter, r *http.Request) {
func UploadLargeFile(fr *multipart.Reader, bucketID string) (url string, err error) { if client == nil { client = createStorageClient() }
bucket, ok := buckets[bucketID] if !ok { bucket = client.Bucket(bucketID) buckets[bucketID] = bucket }
var uploadFile *multipart.Part for { p, err := fr.NextPart() if err == io.EOF { break } if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) } if p.FormName() == "uploadfile" { uploadFile = p fmt.Println("UploadFile: ", uploadFile) } }
// Create the object writer and send the file to GCS ctx := context.Background() w := bucket.Object(uploadFile.FileName()).NewWriter(ctx) w.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}} w.CacheControl = "public, max-age=86400"
// Copy the file data to the writer if _, err := io.Copy(w, uploadFile); err != nil { fmt.Println("Copy: ", err) return "", err } if err := w.Close(); err != nil { return "", err }
const publicURL = "https://storage.googleapis.com/%s/%s" return fmt.Sprintf(publicURL, bucketID, uploadFile.FileName()), nil}
func uploadFileToService(path string, fileName string, paramName string) string { // Open the file that we plan on uploading file, err := os.Open(path) if err != nil { log.Fatal("File Open:", err) } defer file.Close()
rPipe, wPipe := io.Pipe() req, err := http.NewRequest("POST", serviceHost+"/upload", rPipe) if err != nil { log.Fatal("NewRequest", err) }
w := multipart.NewWriter(wPipe) req.Header.Set("Content-Type", w.FormDataContentType()) // Need to read and write in parallel so spawn a goroutine to write to the // pipe when being read from go func() { defer wPipe.Close() part, err := w.CreateFormFile(paramName, fileName) if err != nil { log.Fatal("CreateFormFile:", err) }
if _, err := io.Copy(part, file); err != nil { log.Fatal("CopyFile:", err) }
if err = w.Close(); err != nil { log.Fatal("multipart.Writer.Close:", err) } }()
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal("Do Request", err) } defer resp.Body.Close()
ret, err := ioutil.ReadAll(resp.Body) return string(ret)}
Perhaps calling next part is consuming reader, so when you break at once you hit io.EOF, the reader you memorised has been consumed.
Again, just a guess, I’ve never used the multipart package in anger.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/XoSPHwWfyQ8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.