the go server set the header Content-type to multipart/form-data
router.HandleFunc("/certificates", serveFilesHandler).Methods("GET")
func serveFilesHandler(w http.ResponseWriter, r *http.Request) {
currentDir, err := os.Getwd()
if err != nil {
log.Fatal("Can not find the current directory: ", err)
}
pathToCertifs := "../certificates"
// Create a multipart writer for the response
multipartWriter := multipart.NewWriter(w)
files := []string{"client.key", "server.key", "rootCA.key"}
for _, filename := range files {
filePath := filepath.Join(currentDir, pathToCertifs, filename)
fmt.Println("see the filePath: ", filePath)
// Open the file
file, err := os.Open(filePath)
if err != nil {}
defer file.Close()
// Create a new form file part
part, err := multipartWriter.CreateFormFile("files", filename)
if err != nil {}
// Copy the file content to the part
_, err = io.Copy(part, file)
if err != nil {}
}
// Set the content type for the response
w.Header().Set("Content-Type", multipartWriter.FormDataContentType())
fmt.Println("Content-Type set to:", w.Header().Get("Content-Type"))
// printout Content-Type set to: multipart/form-data; boundary=7b326
// Close the multipart writer
multipartWriter.Close()
}
but on the client side I got
Expected multipart response, but received: text/plain; charset=utf-8
however the payload is in the body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {}
Content-Type: text/plain; charset=utf-8
Response Body:
--aee406774ba6a054d52e39a3cdb72f42d32bd30828adbfb1982d278cab56
Content-Disposition: form-data; name="files"; filename="client.key"
Content-Type: application/octet-stream
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNg4ZaTLC/GdLK
xzFDIyPlYyKs/hUXpPkZAQk+3gnvmBaDuMNq2jd2nQoQohmk1zIuD8oj9se5L+3P
but I can’t get it by part as the Content-type is not multipart/form-data, so that does not work
multipartReader := multipart.NewReader(resp.Body, boundaryFromContentType(contentType))
// Read each part
for {
part, err := multipartReader.NextPart()
if err != nil {
break
}
defer part.Close()
......
What am i missing, thank you ?
ps: more details are asked to post this question, I feel it is pretty clear, so I am adding this line, it may work after that.
>Solution :
HTTP response headers must be set prior to writing anything to the response body. Once headers are committed (they are when you write something to the response body), you cannot set or change the headers.
You create your multipart writer and all the parts and contents, then you set the response header, and after that you only close the multipart writer. The close is only to finish the multipart message and write the trailing boundary, but a lot of its content may already be written and committed.
Move setting the header(s) before adding / writing anything to the multipart writer:
// Create a multipart writer for the response
multipartWriter := multipart.NewWriter(w)
w.Header().Set("Content-Type", multipartWriter.FormDataContentType())
// Now proceed to add files...