Skip to content

Commit

Permalink
Merge pull request #59 from panki/master
Browse files Browse the repository at this point in the history
Guess content type for binary params by filename extension
  • Loading branch information
huandu authored Mar 8, 2017
2 parents 5740aa8 + f2d02d2 commit eb717d2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
1 change: 1 addition & 0 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
ERROR_CODE_UNKNOWN = -1 // unknown facebook graph api error code.

_MIME_FORM_URLENCODED = "application/x-www-form-urlencoded"
_MIME_FORM_DATA = "multipart/form-data"
)

// Graph API debug mode values.
Expand Down
22 changes: 22 additions & 0 deletions facebook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"fmt"
"testing"
"time"
"strings"
)

const (
Expand Down Expand Up @@ -890,6 +891,27 @@ func TestParamsEncode(t *testing.T) {
t.Logf("complex encode result is '%v'. [e:%v] [mime:%v]", buf.String(), err, mime)
}

func TestBinaryParamsEncode(t *testing.T) {

buf := &bytes.Buffer{}
params := Params{}
params["attachment"] = FileAlias("image.jpg", "LICENSE")

contentTypeImage := "Content-Type: image/jpeg"
if mime, err := params.Encode(buf); err != nil || !strings.Contains(mime, _MIME_FORM_DATA) || !strings.Contains(buf.String(), contentTypeImage) {
t.Fatalf("wrong binary params encode result. expected content type is '%v'. actual is '%v'. [e:%v] [mime:%v]", contentTypeImage, buf.String(), err, mime)
}

// Fallback for unknown content types
// should be application/octet-stream
buf.Reset()
params = Params{"attachment": FileAlias("image.unknown", "LICENSE")}
contentTypeOctet := "Content-Type: application/octet-stream"
if mime, err := params.Encode(buf); err != nil || !strings.Contains(mime, _MIME_FORM_DATA) || !strings.Contains(buf.String(), contentTypeOctet) {
t.Fatalf("wrong binary params encode result. expected content type is '%v'. actual is '%v'. [e:%v] [mime:%v]", contentTypeOctet, buf.String(), err, mime)
}
}

func TestStructFieldTag(t *testing.T) {
strNormalField := `{
"field2": "hey",
Expand Down
28 changes: 26 additions & 2 deletions params.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ package facebook

import (
"encoding/json"
"fmt"
"io"
"mime"
"mime/multipart"
"net/textproto"
"net/url"
"os"
"path"
"reflect"
"runtime"
"strings"
)

// Makes a new Params instance by given data.
Expand Down Expand Up @@ -158,7 +163,8 @@ func (params Params) encodeMultipartForm(writer io.Writer) (mime string, err err
switch value := v.(type) {
case *binaryData:
var dst io.Writer
dst, err = w.CreateFormFile(k, value.Filename)
filePart := createFormFile(k, value.Filename)
dst, err = w.CreatePart(filePart)

if err != nil {
return
Expand All @@ -175,7 +181,8 @@ func (params Params) encodeMultipartForm(writer io.Writer) (mime string, err err
var file *os.File
var path string

dst, err = w.CreateFormFile(k, value.Filename)
filePart := createFormFile(k, value.Filename)
dst, err = w.CreatePart(filePart)

if err != nil {
return
Expand Down Expand Up @@ -225,3 +232,20 @@ func (params Params) encodeMultipartForm(writer io.Writer) (mime string, err err

return
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func createFormFile(fieldName, fileName string) textproto.MIMEHeader {
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition",
fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
quoteEscaper.Replace(fieldName), quoteEscaper.Replace(fileName)))

contentType := mime.TypeByExtension(path.Ext(fileName))
if contentType == "" {
contentType = "application/octet-stream"
}

h.Set("Content-Type", contentType)
return h
}

0 comments on commit eb717d2

Please sign in to comment.