main.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Simpliest server
  2. package main
  3. //go:generate folder2go assets binAssets
  4. import (
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "mime"
  9. "net"
  10. "net/http"
  11. "os"
  12. "path/filepath"
  13. "strings"
  14. "dev.hexasoftware.com/hxs/httpServe/binAssets"
  15. "dev.hexasoftware.com/hxs/prettylog"
  16. )
  17. var (
  18. log = prettylog.New("httpServe")
  19. )
  20. func CreateHandleFunc(prefix string) func(http.ResponseWriter, *http.Request) {
  21. return func(w http.ResponseWriter, r *http.Request) {
  22. var solvedPath = r.URL.Path
  23. if solvedPath == prefix {
  24. solvedPath = prefix + "/index.html"
  25. }
  26. log.Printf("%s - (embed)%s", r.Method, r.URL.Path)
  27. if strings.HasPrefix(solvedPath, prefix) {
  28. solvedPath = solvedPath[len(prefix):]
  29. }
  30. data, ok := binAssets.Data[solvedPath]
  31. if !ok {
  32. w.WriteHeader(404)
  33. }
  34. w.Header().Set("Content-type", mime.TypeByExtension(filepath.Ext(solvedPath)))
  35. w.Write(data)
  36. }
  37. }
  38. func HandleMarkDown(w http.ResponseWriter, r *http.Request, path string) error {
  39. log.Println("Handling markdown")
  40. f, err := os.Open(path)
  41. if err != nil {
  42. return err
  43. }
  44. defer f.Close()
  45. /* // Server side markdown2html
  46. data, err := ioutil.ReadAll(f)
  47. if err != nil {
  48. return err
  49. }
  50. w.Write([]byte("<html><head><link rel='stylesheet' href='/.httpServe/strapdown.css'><link rel='stylesheet' href='/.httpServe/themes/united.min.css'></head><body>"))
  51. mdData := blackfriday.MarkdownCommon(data)
  52. w.Write(mdData)
  53. w.Write([]byte("</body></html>"))
  54. return nil
  55. */
  56. w.Write([]byte(
  57. `
  58. <!DOCTYPE html>
  59. <html>
  60. <xmp theme="paper" style="display:none;">
  61. `))
  62. io.Copy(w, f)
  63. w.Write([]byte(
  64. `
  65. </xmp>
  66. <script src=".httpServe/strapdown.js"></script>
  67. </html>`))
  68. return nil
  69. }
  70. func HandleFolder(w http.ResponseWriter, r *http.Request, path string) error {
  71. res, err := ioutil.ReadDir(path)
  72. if err != nil {
  73. return err
  74. }
  75. w.Write([]byte(
  76. `<html>
  77. <body>
  78. <ul>`))
  79. for _, f := range res {
  80. w.Write([]byte(fmt.Sprintf(`<li><a href="/%s">%s</a>`, path+"/"+f.Name(), f.Name())))
  81. }
  82. w.Write([]byte(
  83. `</ul>
  84. </body>
  85. </html>
  86. `))
  87. return nil
  88. }
  89. type FileServer struct {
  90. }
  91. func (FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  92. path := r.URL.Path[1:]
  93. if path == "" {
  94. path = "index.html"
  95. if _, err := os.Stat(path); os.IsNotExist(err) {
  96. path = "."
  97. }
  98. }
  99. if strings.Contains(path, "..") {
  100. http.ServeFile(w, r, path)
  101. }
  102. log.Printf("%s - %s", r.Method, r.URL.Path)
  103. fstat, err := os.Stat(path)
  104. if err != nil {
  105. log.Println("ERR:", err)
  106. http.ServeFile(w, r, path)
  107. return
  108. }
  109. if fstat.IsDir() {
  110. HandleFolder(w, r, path)
  111. return
  112. }
  113. if filepath.Ext(path) == ".md" {
  114. err := HandleMarkDown(w, r, path)
  115. if err != nil {
  116. http.ServeFile(w, r, path)
  117. }
  118. return
  119. }
  120. // Default file server
  121. http.ServeFile(w, r, path)
  122. }
  123. func main() {
  124. mux := http.NewServeMux()
  125. mux.HandleFunc("/.httpServe/", CreateHandleFunc("/.httpServe"))
  126. mux.Handle("/", FileServer{})
  127. var port = 8080
  128. for {
  129. addr := fmt.Sprintf(":%d", port)
  130. listener, err := net.Listen("tcp", addr)
  131. if err != nil {
  132. log.Println("Err opening", port, err)
  133. port++
  134. log.Println("Trying port", port)
  135. continue
  136. }
  137. log.Println("Listening with port:", port)
  138. http.Serve(listener, mux)
  139. }
  140. //http.ListenAndServe(":8080", http.FileServer(http.Dir('.')))
  141. }