1. package main
    2. import (
    3. "TestProject/filelistingserver/filelisting"
    4. "log"
    5. "net/http"
    6. "os"
    7. )
    8. type appHandler func(writer http.ResponseWriter, request *http.Request) error
    9. func errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {
    10. return func(writer http.ResponseWriter, request *http.Request) {
    11. defer func() {
    12. if r := recover(); r != nil {
    13. log.Printf("Panic: %v", r)
    14. http.Error(writer,
    15. http.StatusText(http.StatusInternalServerError),
    16. http.StatusInternalServerError)
    17. }
    18. }()
    19. err := handler(writer, request)
    20. if err != nil {
    21. log.Printf("Error occurred handling request: %s", err.Error())
    22. if userErr, ok := err.(userError); ok {
    23. http.Error(writer,
    24. userErr.Message(),
    25. http.StatusBadRequest)
    26. return
    27. }
    28. code := http.StatusOK
    29. switch {
    30. case os.IsNotExist(err):
    31. code = http.StatusNotFound
    32. case os.IsPermission(err):
    33. code = http.StatusForbidden
    34. default:
    35. code = http.StatusInternalServerError
    36. }
    37. http.Error(
    38. writer,
    39. http.StatusText(code),
    40. code)
    41. }
    42. }
    43. }
    44. type userError interface {
    45. error
    46. Message() string
    47. }
    48. func main() {
    49. http.HandleFunc("/", errWrapper(filelisting.HandleFileList))
    50. err := http.ListenAndServe(":8888", nil)
    51. if err != nil {
    52. panic(err)
    53. }
    54. }
    1. package filelisting
    2. import (
    3. "fmt"
    4. "io/ioutil"
    5. "net/http"
    6. "os"
    7. "strings"
    8. )
    9. const prefix = "/list/"
    10. type userError string
    11. func (e userError) Error() string {
    12. return e.Message()
    13. }
    14. func (e userError) Message() string {
    15. return string(e)
    16. }
    17. func HandleFileList(writer http.ResponseWriter, request *http.Request) error {
    18. if strings.Index(request.URL.Path, prefix) != 0 {
    19. return userError(fmt.Sprintf("path %s must start "+
    20. "with %s",
    21. request.URL.Path, prefix))
    22. }
    23. path := request.URL.Path[len(prefix):]
    24. file, err := os.Open(path)
    25. if err != nil {
    26. return err
    27. }
    28. defer file.Close()
    29. all, err := ioutil.ReadAll(file)
    30. if err != nil {
    31. return err
    32. }
    33. writer.Write(all)
    34. return nil
    35. }