github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/upload/10_post_cli.go (about) 1 package upload 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "log" 8 "mime/multipart" 9 "net/http" 10 "net/textproto" 11 "os" 12 "path/filepath" 13 "strings" 14 ) 15 16 // CreateFilePostRequest2 prepares a multipart 17 // file upload POST request 18 func CreateFilePostRequest( 19 url, fileParamName, filePath string, 20 extraParams map[string]string, 21 ) (*http.Request, error) { 22 23 // try opening the file 24 file, err := os.Open(filePath) 25 if err != nil { 26 return nil, err 27 } 28 defer file.Close() 29 30 // first 512 bytes are used to evaluate mime type 31 first512 := make([]byte, 512) 32 file.Read(first512) 33 file.Seek(0, 0) 34 ct := http.DetectContentType(first512) 35 log.Println("detected", ct) 36 37 // prepare request body buffer 38 body := &bytes.Buffer{} 39 40 wrtr := multipart.NewWriter(body) 41 42 // append extra params 43 for param, val := range extraParams { 44 err = wrtr.WriteField(param, val) 45 if err != nil { 46 return nil, err 47 } 48 } 49 50 // create a multipart file header with the given param name and file 51 h := make(textproto.MIMEHeader) 52 cd := fmt.Sprintf(`form-data; name="%s"; filename="%s"`, 53 escapeQuotes(fileParamName), escapeQuotes(filepath.Base(filePath))) 54 h.Set("Content-Disposition", cd) 55 h.Set("Content-Type", ct) 56 57 formfilePart, err := wrtr.CreatePart(h) 58 if err != nil { 59 return nil, err 60 } 61 62 // write the file to the part 63 num, err := io.Copy(formfilePart, file) 64 log.Println("copied", num, "bytes") 65 66 // the writer must be closed to finalize the file entry 67 err = wrtr.Close() 68 if err != nil { 69 return nil, err 70 } 71 72 // finally create the request 73 req, err := http.NewRequest("POST", url, body) 74 if err != nil { 75 return nil, err 76 } 77 78 // set type & boundary 79 req.Header.Set("Content-Type", wrtr.FormDataContentType()) 80 81 return req, err 82 83 } 84 85 var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") 86 87 func escapeQuotes(s string) string { 88 return quoteEscaper.Replace(s) 89 }