I'm writing a manager for cloud support of legacy IOT devices in Go, the devices establish a tcp connection with the manager, then that connection gets held open for bi-directional communication. The api for the devices is REST(ish) and the commands are written over the TCP pipe. For any HTTP/JSON commands that send a json payload, I have everything working, but yesterday I started working on firmware update, which requires I send a binary file instead of json.
I've been loving golang but this is a bit of a stretch for me. I've tried:
- Use Postman POST, works.
- Tried to use the same approach as the commands that have JSON payloads, but no luck.
- Try to simplify and mimic what Postman is doing in Go to get to working Go code. I took out the error checking for brevity, but no errors are thrown:
func downloadFirmware() { file, _ := os.Open(`c:\users\wayne\development\go\accesscontrol\core\firmware\myfile.img`) body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, _:= writer.CreateFormFile("file", "firmware.img") io.Copy(part, file) _ = writer.Close() request, _:= http.NewRequest("POST", `http://192.168.85.249/eidc/download`, body) request.SetBasicAuth(config.Credentials.UserName, config.Credentials.Password) request.Header.Set("Content-Type", writer.FormDataContentType()) request.Header.Set(`Host`, config.OutboundConfig.PrimaryHostAddress) request.Header.Set(`User-Agent`, `Listener`) request.Header.Set(`Accept-Encoding`, `gzip, deflate, br`) request.Header.Set(`Connection`, `keep-alive`) request.Header.Set("Content-Length", fmt.Sprint(body.Len())) client := &http.Client{} response, err := client.Do(request) byteBody, _ := io.ReadAll(response.Body) fmt.Println(string(byteBody)) response.Body.Close() file.Close()}
Monitoring with Wireshark I see the file get pushed, but the response from the device is failure, error downloading file.
I keep wondering if there's some termination character I need to add to the file or some other way of indicating the end of the file? I've checked the content length that gets generated and it matches Postman.