I am trying to send a zip file in POST request body as form-data in GO. So, it is supposed to be in a key-value format. I am able to achieve the same while sending an unzipped file. Here is the snippet,
buf := new(bytes.Buffer)
multiPartWriter := multipart.NewWriter(buf)
part, err := multiPartWriter.CreateFormFile("File", fileName)
However, when it comes to zipping it, I am able to find this,
zipWriter := zip.NewWriter(buf)
zipFile, err := zipWriter.Create(fileName)
Unlike multipart.Writer, in case of zip.Writer I can't find any option to create form file in a key-value fashion.
How can I achieve this for zip as well?
Code snippet[updated],
func SendPostRequest(url string, content []byte, fileName string,
doZip bool)(*http.Response, error) {
buf := new(bytes.Buffer)
multiPartWriter := multipart.NewWriter(buf)
part, _ := multiPartWriter.CreateFormFile("File", fileName)
if doZip {
zipWriter := zip.NewWriter(part)
zipFile, _ := zipWriter.Create(fileName)
zipFile.Write(content)
zipWriter.Close()
} else {
part.Write(content)
multiPartWriter.Close()
}
request, _ := http.NewRequest(http.MethodPost, url, buf)
request.Header.Add(constants.Header_content_type_key, multiPartWriter.FormDataContentType())
client := &http.Client{}
response, err := client.Do(request)
return client.Do(request)
}
As a solution to this one - I am doing a zip of the content byte slice only, when it comes to zipping. Rest are common for both zipped/non-zipped approach. Here are the code snippets,
func sendPostRequest(url string, content []byte, projectId string, fileName string, fileType string, doZip bool) (*http.Response, error) {
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
part, err := writer.CreateFormFile("File", fileName)
if err != nil {
return nil, errors.New("Invocation of *multipart.Writer.CreateFormFile() failed: " + err.Error())
}
content, err = ZipBytes(fileName, content, doZip)
if err != nil {
return nil, err
}
_, err = part.Write(content)
if err != nil {
return nil, errors.New("Invocation of io.Writer.Write() failed: " + err.Error())
}
if err = writer.Close(); err != nil {
return nil, errors.New("Failed to close *multipart.Writer: " + err.Error())
}
request, err := http.NewRequest(http.MethodPost, url, buf)
if err != nil {
return nil, errors.New("Failed to create request for Validation API multipart file uploading: " + err.Error())
}
request.Header.Add(constants.Header_content_type_key, writer.FormDataContentType())
request.Header.Add(constants.Project_Id_header_str, projectId)
request.Header.Add(constants.File_type_header_str, fileType)
if doZip {
request.Header.Add(constants.IsZipped_header_str, "true")
} else {
request.Header.Add(constants.IsZipped_header_str, "false")
}
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
return nil, errors.New("Failed to invoke Validation API: " + err.Error())
} else if !strings.Contains(strconv.Itoa(response.StatusCode), "20") {
respMap, _ := processValidationResponse(response)
message := fmt.Sprintf("Failed to invoke Validation API with HTTP %s : %s", strconv.Itoa(response.StatusCode), respMap["message"])
return nil, errors.New(message)
}
return response, nil
}
func ZipBytes(fileName string, content []byte, doZip bool) ([]byte, error) {
if doZip {
log.Println("Zipped file will be sent for validation")
buf := new(bytes.Buffer)
zipWriter := zip.NewWriter(buf)
zipFile, err := zipWriter.Create(fileName)
if err != nil {
return nil, errors.New("Zip file creation failed: " + err.Error())
}
_, err = zipFile.Write(content)
if err != nil {
return nil, errors.New("Writing to zip file failed: " + err.Error())
}
if err = zipWriter.Close(); err != nil {
return nil, errors.New("Failed to close zip writer: " + err.Error())
}
return buf.Bytes(), nil
} else {
log.Println("Normal file will be sent for validation")
return content, nil
}
}