e25a74801a0c — Sean Russell 11 years ago
Fixed POST for all cases.
3 files changed, 49 insertions(+), 18 deletions(-)

M api.go
M generator.go
M post.go
M api.go +1 -1
@@ 86,7 86,7 @@ type DataTypeFields struct {
 func (p DataTypeFields) typeOf() string {
 	switch p.Type {
 	case "File":
-		return "io.Reader"
+		return "*os.File"
 	case "integer":
 		if p.Format == "int64" {
 			return p.Format

          
M generator.go +3 -0
@@ 15,6 15,7 @@ func Generate(pack string, j []byte, out
 	}
 	out <- fmt.Sprintf("package %s", pack)
 	out <- ""
+	// FIXME: only import packages that are used
 	out <- "import ("
 	out <- "\t\"bytes\""
 	out <- "\t\"encoding/json\""

          
@@ 22,7 23,9 @@ func Generate(pack string, j []byte, out
 	out <- "\t\"fmt\""
 	out <- "\t\"io\""
 	out <- "\t\"io/ioutil\""
+	out <- "\t\"mime/multipart\""
 	out <- "\t\"net/http\""
+	out <- "\t\"os\""
 	out <- ")"
 	out <- ""
 	switch t.(type) {

          
M post.go +45 -17
@@ 16,6 16,7 @@ func genPostBase(api Api, op Operation, 
 	formatArgs := []string{"basePath"}
 	params := make(map[string]string)
 	hasBody := false
+	var file Parameter
 	for _, p := range op.Parameters {
 		if p.Minimum != "" {
 			out <- fmt.Sprintf("\tif %s < %s(%s) {", p.Name, p.typeOf(), p.Minimum)

          
@@ 32,11 33,15 @@ func genPostBase(api Api, op Operation, 
 			format = strings.Replace(format, match, "%v", 1)
 			formatArgs = append(formatArgs, p.Name)
 		} else if p.ParamType == "body" {
-			hasBody = true
-			out <- fmt.Sprintf("\tb, e := json.Marshal(%s)", p.Name)
-			out <- "\tif e != nil {"
-			out <- "\t\treturn e"
-			out <- "\t}"
+			if p.Type == "File" {
+				file = p
+			} else {
+				hasBody = true
+				out <- fmt.Sprintf("\tb, e := json.Marshal(%s)", p.Name)
+				out <- "\tif e != nil {"
+				out <- "\t\treturn e"
+				out <- "\t}"
+			}
 		} else {
 			v := p.Name
 			if p.Type == "array" {

          
@@ 46,17 51,6 @@ func genPostBase(api Api, op Operation, 
 		}
 	}
 	format += `"`
-	// FIXME for the case of body AND params
-	if len(params) > 0 && !hasBody {
-		out <- "\tm := make(map[string]interface{})"
-		for n, v := range params {
-			out <- fmt.Sprintf("\tm[%#v] = %s", n, v)
-		}
-		out <- "\tb, e := json.Marshal(m)"
-		out <- "\tif e != nil {"
-		out <- "\t\treturn e"
-		out <- "\t}"
-	}
 	url := "\turl := fmt.Sprintf(" + format
 	for _, v := range formatArgs {
 		url += ", " + v

          
@@ 64,7 58,11 @@ func genPostBase(api Api, op Operation, 
 	url += ")"
 	out <- url
 	out <- "\tclient := &http.Client{}"
-	out <- fmt.Sprintf("\treq, err := http.NewRequest(%#v, url, bytes.NewReader(b))", op.Method)
+	if hasBody {
+		out <- fmt.Sprintf("\treq, err := http.NewRequest(%#v, url, bytes.NewReader(b))", op.Method)
+	} else {
+		postMultipartFile(op, file, params, out)
+	}
 	out <- "\tresp, err := client.Do(req)"
 	out <- "\tif err != nil {"
 	out <- fmt.Sprintf("\t\treturn %serr", zero)

          
@@ 83,3 81,33 @@ func genPostBase(api Api, op Operation, 
 func genPost(api Api, op Operation, out chan string) {
 	genPostBase(api, op, out)
 }
+
+func postMultipartFile(op Operation, file Parameter, params map[string]string, out chan string) {
+    out <- "\tvar b bytes.Buffer"
+    out <- "\tw := multipart.NewWriter(&b)"
+    out <- "\tvar fw io.Writer"
+    out <- "\tvar err error"
+    if file.Name != "" {
+		out <- fmt.Sprintf("\tfw, err = w.CreateFormFile(%#v, file.Name())", file.Name)
+		out <- "\tif err != nil {"
+		out <- "\t\treturn err"
+		out <- "\t}"
+		out <- "\tif _, err = io.Copy(fw, file); err != nil {"
+		out <- "\t\treturn err"
+		out <- "\t}"
+	}
+	for k, v := range params {
+		out <- fmt.Sprintf("\tif fw, err = w.CreateFormField(%#v); err != nil {", k)
+		out <- "\t\treturn err"
+		out <- "\t}"
+		out <- fmt.Sprintf("\tif _, err = fw.Write([]byte(%s)); err != nil {", v)
+		out <- "\t\treturn err"
+		out <- "\t}"
+	}
+    out <- "\tw.Close()"
+    out <- fmt.Sprintf("\treq, err := http.NewRequest(%#v, url, &b)", op.Method)
+    out <- "\tif err != nil {"
+    out <- "\t\treturn err"
+    out <- "\t}"
+    out <- "\treq.Header.Set(\"Content-Type\", w.FormDataContentType())"
+}