Handle file uploading with go
I managed to solve my problem, so here it is in case someone else needs it. And thanks @JiangYD for the tip of using curl to test the server.
TL;DR
- I wrote
http.HandleFunc("/submit/", submit)
but I was making a POST request to/submit
(note the missing slash) << This is important because of redirections - Don't specify the Content-Type yourself, the browser will do it for you
LONG ANSWER
I did as @JiangYD said and used curl to test the server, I updated my answer with the response. I found odd that there was a 301 Redirect since I didn't put it there, I decided to use the following curl command
curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' -L http://localhost:8080/submit
(note the -L) That way curl followed the redirect, though it failed again because, when redirecting, curl switched from POST to GET but with that response I found out that the request to /submit
was being redirected to /submit/
and I remembered that's how I wrote it in the main
function.
After fixing that it still failed, the response was http: no such file
and by looking at the net/http
code I found that it meant the field didn't exist, so I did a quick test iterating over all the field names obtained:
for k, _ := range r.MultipartForm.File {
log.Println(k)
}
I was getting 'uploadFile
as the field name, I removed the single quotes in the curl command and now it uploaded the file perfectly
But it doesn't end here, I now knew the server was working correctly because I could upload a file using curl
but when I tried uploading it through the hosted web page I got an error: no multipart boundary param in Content-Type
.
So I found out I was suppose to include the boundary in the header, I changed fetch to something like this:
fetch('/submit', {
method: 'post',
headers: {
"Content-Type": "multipart/form-data; boundary=------------------------" + boundary
}, body: formData})
I calculate the boundary like this:
var boundary = Math.random().toString().substr(2);
But I still got an error: multipart: NextPart: EOF
So how do you calculate the boundary? I read the spec https://html.spec.whatwg.org/multipage/forms.html#multipart/form-data-encoding-algorithm and found out the boundary is calculated by the algorithm that encodes the file, which in my case is FormData, the FormData API doesn't expose a way to get that boundary but I found out that the browser adds the Content-Type with multipart/form-data
and the boundary automatically if you don't specify it so I removed the headers object from the fetch
call and now it finally works!