Skip to content

Commit

Permalink
added generic way to auto detect multipart content type
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed Jan 23, 2018
1 parent d212d85 commit 513d3b0
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"net/textproto"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -98,32 +100,63 @@ func getLogger(w io.Writer) *log.Logger {
return log.New(w, "RESTY ", log.LstdFlags)
}

func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}

func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r io.Reader) error {
// Auto detect actual multipart content type
cbuf := make([]byte, 512)
if _, err := r.Read(cbuf); err != nil {
return err
}
contentType := http.DetectContentType(cbuf)

h := make(textproto.MIMEHeader)
h.Set("Content-Disposition",
fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
escapeQuotes(fieldName), escapeQuotes(fileName)))
h.Set("Content-Type", contentType)
partWriter, err := w.CreatePart(h)
if err != nil {
return err
}
defer func() {
_ = file.Close()
}()

part, err := w.CreateFormFile(fieldName, filepath.Base(path))
size, err := partWriter.Write(cbuf)
if err != nil {
return err
}
_, err = io.Copy(part, file)

return err
for {
size, err = r.Read(cbuf)
if size == 0 || err == io.EOF {
break
}
_, err = partWriter.Write(cbuf)
if err != nil {
return err
}
}

return nil
}

func addFileReader(w *multipart.Writer, f *File) error {
part, err := w.CreateFormFile(f.ParamName, f.Name)
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
_, err = io.Copy(part, f.Reader)
defer func() {
_ = file.Close()
}()

return err
return writeMultipartFormFile(w, fieldName, filepath.Base(path), file)
}

func addFileReader(w *multipart.Writer, f *File) error {
return writeMultipartFormFile(w, f.ParamName, f.Name, f.Reader)
}

func getPointer(v interface{}) interface{} {
Expand Down

0 comments on commit 513d3b0

Please sign in to comment.