I have a file in the folder files
located in the root of my Golang project directory called test.jpg
. So that would be ./files/test.jpg
that I want to serve to my front end and I am having difficulties.
My golang project is in a docker file with the following volume attached. (Basically this says that /go/.../webserver
in the docker container can read and write out of ./
on the server)
volumes:
- ./:/go/src/github.com/patientplatypus/webserver/
I am using gorilla/mux
for routing as defined by:
r := mux.NewRouter()
Here are some of my attempts at trying to get the PathPrefix to be properly formatted:
r.PathPrefix("/files/").Handler(http.StripPrefix("/files/",
http.FileServer(http.Dir("/go/src/github.com/patientplatypus/webserver/files/"))))
or
r.PathPrefix("/files").Handler(http.FileServer(http.Dir("./files/")))
or
r.PathPrefix("/files/").Handler(http.StripPrefix("/files/",
http.FileServer(http.Dir("./"))))
or
r.PathPrefix("/files/").Handler(http.FileServer(
http.Dir("/go/src/github.com/patientplatypus/webserver/")))
I had previously successfully written to the server with the following command:
newPath := filepath.Join("/go/src/github.com/patientplatypus/webserver/files",
"test.jpg")
newFile, err := os.Create(newPath)
So my intuition is that the first of my attempts should be the correct one, specfying the entirety of the /go/.../files/
path.
In any case, each of my attempts successfully returns a 200OK
to my front end with an empty response.data as shown here:
Object { data: "", status: 200, statusText: "OK",
headers: {…}, config: {…}, request: XMLHttpRequest }
which is coming from a simple js frontside http request using the axios
package:
axios({
method: 'get',
url: 'http://localhost:8000/files/test.jpg',
})
.then(response => {
//handle success
console.log("inside return for test.jpg and value
of response: ")
console.log(response);
console.log("value of response.data: ")
console.log(response.data)
this.image = response.data;
})
.catch(function (error) {
//handle error
console.log(error);
});
My only guess as to why this is happening is that it doesn't see the file and so returns nothing.
For such a seemingly trivial problem, I am in the guess and check stage and I don't know how to debug further. If anyone has any ideas please let me know.
Thanks!
EDIT:
In order to be completely clear, here is the entirety of my main.go file (only 150 lines) with all the routing. There is a piece of middleware that handles JWT auth, but in this case it ignores this route, and there is middleware to handle CORS.
Line in question is highlighted: https://gist.github.com/patientplatypus/36230e665051465cd51291e17825f1f5#file-main-go-L122.
Also, here is my docker-compose file that shows what the volumes are (please ignore the sleep command to boot postgres - I understand it's not the ideal implementation)
https://gist.github.com/patientplatypus/2569550f667c0bee51287149d1c49568.
There should be no other information necessary to debug.
Also...some people have wanted me to show that the file exists in the container.
patientplatypus:~/Documents/zennify.me:11:49:09$docker exec
backend_app_1 ls /go/src/github.com/patientplatypus/webserver/files
test.jpg
Shows that it does.
CLARIFICATION:
I was not properly using Axios to buffer the array, and get an image. An example of that working is here:
//working example image
var imageurl = 'https://avatars2.githubusercontent.com/u/5302751?v=3&s=88';
//my empty server response
//var imageurl = 'http://localhost:8000/files/test.jpg';
axios.get(imageurl, {
responseType: 'arraybuffer'
})
.then( response => {
console.log('value of response: ', response);
console.log('value of response.data: ', response.data);
const base64 = btoa(
new Uint8Array(response.data).reduce(
(data, byte) => data + String.fromCharCode(byte),
'',
),
);
console.log('value of base64: ', base64);
this.image = "data:;base64," + base64
});
However, this does not change the underlying problem that it appears that golang is not returning any data (response.data is empty). Just FYI that I have confirmed a working axios and that doesn't fix the issue.