package mainimport ( "TestProject/filelistingserver/filelisting" "log" "net/http" "os")type appHandler func(writer http.ResponseWriter, request *http.Request) errorfunc errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) { return func(writer http.ResponseWriter, request *http.Request) { defer func() { if r := recover(); r != nil { log.Printf("Panic: %v", r) http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } }() err := handler(writer, request) if err != nil { log.Printf("Error occurred handling request: %s", err.Error()) if userErr, ok := err.(userError); ok { http.Error(writer, userErr.Message(), http.StatusBadRequest) return } code := http.StatusOK switch { case os.IsNotExist(err): code = http.StatusNotFound case os.IsPermission(err): code = http.StatusForbidden default: code = http.StatusInternalServerError } http.Error( writer, http.StatusText(code), code) } }}type userError interface { error Message() string}func main() { http.HandleFunc("/", errWrapper(filelisting.HandleFileList)) err := http.ListenAndServe(":8888", nil) if err != nil { panic(err) }}
package filelistingimport ( "fmt" "io/ioutil" "net/http" "os" "strings")const prefix = "/list/"type userError stringfunc (e userError) Error() string { return e.Message()}func (e userError) Message() string { return string(e)}func HandleFileList(writer http.ResponseWriter, request *http.Request) error { if strings.Index(request.URL.Path, prefix) != 0 { return userError(fmt.Sprintf("path %s must start "+ "with %s", request.URL.Path, prefix)) } path := request.URL.Path[len(prefix):] file, err := os.Open(path) if err != nil { return err } defer file.Close() all, err := ioutil.ReadAll(file) if err != nil { return err } writer.Write(all) return nil}