Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there anyway to make multipart formdata has order? #669

Open
Sczlog opened this issue Jun 21, 2023 · 6 comments
Open

Is there anyway to make multipart formdata has order? #669

Sczlog opened this issue Jun 21, 2023 · 6 comments

Comments

@Sczlog
Copy link

Sczlog commented Jun 21, 2023

I am working with graphql-upload and it's processor must accept one field before any other fields, otherwise it will throw an error.
I know that map has no order and should has no order, but if there is anyway to make a raw body of multipart and keep its order?

image

@Sczlog Sczlog changed the title Is there anyway to make formdata has order? Is there anyway to make multipart formdata has order? Jun 21, 2023
@Sczlog
Copy link
Author

Sczlog commented Jun 21, 2023

Find myself a workaround, use mime/multipart to create body, set raw body and content-type will keep the order.

var bBody bytes.Buffer
writer := multipart.NewWriter(&bBody)

writer.WriteField("firstkey","firstvalue")
writer.WriteField("secondkey","secondvalue")
part, err := writer.CreateFormFile("fieldname", "filename")
if err != nil {
	return nil, err
}
part.Write([]byte("filecontent"))
writer.Close()
request := c.Client.R()
request.SetHeader("Content-Type", writer.FormDataContentType())
request.SetBody(bBody.Bytes())
resp, err := request.Post("endpoint")

@jeevatkm
Copy link
Member

@Sczlog Thanks for bringing it up and finding a workaround to move forward. I may think of a way to preserve order.

@praem90
Copy link
Contributor

praem90 commented Sep 25, 2023

Can we add a new method that can accept a slice instead of map and write it to the body in the same order ?

@chb0github
Copy link

My rant: Go insists that maps don't/can't have order. But that's an implementation issue based on the fact that these are Hash based maps instead of Tree based maps (which are ordered).

What might be a slightly better solution than a slice (just a consideration) - take a sort function. Then it can be by insertion order or actual sort order.

I don't know what the spec for mime/multipart says, but definitely don't deviate from it.

@jeevatkm
Copy link
Member

@chb0github I hear you! I will have to check the RFC spec for this part.

A possible workaround/approach (as @praem90 mentioned above) is to add a method to accept the slice and process it.

@gospider007
Copy link

I am working with graphql-upload and it's processor must accept one field before any other fields, otherwise it will throw an error. I know that map has no order and should has no order, but if there is anyway to make a raw body of multipart and keep its order?

image

this can help you:

package main

import (
	"log"
	"strings"

	"github.com/gospider007/requests"
)

func main() {
	orderMap := requests.NewOrderMap()
	orderMap.Set("name", "test")
	orderMap.Set("age", 11)
	orderMap.Set("sex", "boy")

	resp, err := requests.Post(nil, "https://httpbin.org/anything", requests.RequestOption{
		Form: orderMap,
	})
	if err != nil {
		log.Panic(err)
	}
	jsonData, err := resp.Json()
	if err != nil {
		log.Panic(err)
	}
	if !strings.HasPrefix(jsonData.Get("headers.Content-Type").String(), "multipart/form-data") {
		log.Panic("json data error")
	}
	if jsonData.Get("form.name").String() != "test" {
		log.Panic("json data error")
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants