Skip to content

Instantly share code, notes, and snippets.

@guiphh
Last active March 23, 2018 15:18
Show Gist options
  • Save guiphh/784a5510691b4f2e7f986d58b8d2f823 to your computer and use it in GitHub Desktop.
Save guiphh/784a5510691b4f2e7f986d58b8d2f823 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
func main() {
fmt.Println("Starting http file sever")
http.HandleFunc("/", HandleClient)
err := http.ListenAndServe(":80", nil)
if err != nil {
fmt.Println(err)
}
}
func HandleClient(writer http.ResponseWriter, request *http.Request) {
//First of check if Get is set in the URL
Filename := request.URL.Query().Get("file")
if Filename == "" {
//Get not set, send a 400 bad request
http.Error(writer, "Get 'file' not specified in url.", 400)
return
}
fmt.Println("Client requests: " + Filename)
//Check if file exists and open
Openfile, err := os.Open(Filename)
defer Openfile.Close() //Close after function return
if err != nil {
//File not found, send 404
http.Error(writer, "File not found.", 404)
return
}
//File is found, create and send the correct headers
//Get the Content-Type of the file
//Create a buffer to store the header of the file in
FileHeader := make([]byte, 512)
//Copy the headers into the FileHeader buffer
Openfile.Read(FileHeader)
//Get content type of file
FileContentType := http.DetectContentType(FileHeader)
//Get the file size
FileStat, _ := Openfile.Stat() //Get info from file
FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string
//Send the headers
writer.Header().Set("Content-Disposition", "attachment; filename="+Filename)
writer.Header().Set("Content-Type", FileContentType)
writer.Header().Set("Content-Length", FileSize)
//Send the file
//We read 512 bytes from the file already so we reset the offset back to 0
Openfile.Seek(0, 0)
io.Copy(writer, Openfile) //'Copy' the file to the client
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment