Contains the Concourse pipeline definition for building a line-server container
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.5 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package main
  2. import (
  3. "flag"
  4. "log"
  5. "net"
  6. "net/http"
  7. "net/http/fcgi"
  8. "os"
  9. "regexp"
  10. "strconv"
  11. "time"
  12. "github.com/GeertJohan/go.rice"
  13. "github.com/flosch/pongo2"
  14. "github.com/zenazn/goji"
  15. "github.com/zenazn/goji/graceful"
  16. "github.com/zenazn/goji/web/middleware"
  17. )
  18. var Config struct {
  19. bind string
  20. filesDir string
  21. metaDir string
  22. siteName string
  23. siteURL string
  24. certFile string
  25. keyFile string
  26. contentSecurityPolicy string
  27. fileContentSecurityPolicy string
  28. xFrameOptions string
  29. maxSize int64
  30. noLogs bool
  31. allowHotlink bool
  32. fastcgi bool
  33. remoteUploads bool
  34. }
  35. var Templates = make(map[string]*pongo2.Template)
  36. var TemplateSet *pongo2.TemplateSet
  37. var staticBox *rice.Box
  38. var timeStarted time.Time
  39. var timeStartedStr string
  40. func setup() {
  41. goji.Use(ContentSecurityPolicy(CSPOptions{
  42. policy: Config.contentSecurityPolicy,
  43. frame: Config.xFrameOptions,
  44. }))
  45. if Config.noLogs {
  46. goji.Abandon(middleware.Logger)
  47. }
  48. // make directories if needed
  49. err := os.MkdirAll(Config.filesDir, 0755)
  50. if err != nil {
  51. log.Fatal("Could not create files directory:", err)
  52. }
  53. err = os.MkdirAll(Config.metaDir, 0700)
  54. if err != nil {
  55. log.Fatal("Could not create metadata directory:", err)
  56. }
  57. // ensure siteURL ends wth '/'
  58. if lastChar := Config.siteURL[len(Config.siteURL)-1:]; lastChar != "/" {
  59. Config.siteURL = Config.siteURL + "/"
  60. }
  61. // Template setup
  62. p2l, err := NewPongo2TemplatesLoader()
  63. if err != nil {
  64. log.Fatal("Error: could not load templates", err)
  65. }
  66. TemplateSet := pongo2.NewSet("templates", p2l)
  67. TemplateSet.Globals["sitename"] = Config.siteName
  68. TemplateSet.Globals["siteurl"] = Config.siteURL
  69. err = populateTemplatesMap(TemplateSet, Templates)
  70. if err != nil {
  71. log.Fatal("Error: could not load templates", err)
  72. }
  73. staticBox = rice.MustFindBox("static")
  74. timeStarted = time.Now()
  75. timeStartedStr = strconv.FormatInt(timeStarted.Unix(), 10)
  76. // Routing setup
  77. nameRe := regexp.MustCompile(`^/(?P<name>[a-z0-9-\.]+)$`)
  78. selifRe := regexp.MustCompile(`^/selif/(?P<name>[a-z0-9-\.]+)$`)
  79. selifIndexRe := regexp.MustCompile(`^/selif/$`)
  80. torrentRe := regexp.MustCompile(`^/(?P<name>[a-z0-9-\.]+)/torrent$`)
  81. goji.Get("/", indexHandler)
  82. goji.Get("/paste/", pasteHandler)
  83. goji.Get("/paste", http.RedirectHandler("/paste/", 301))
  84. goji.Get("/API/", apiDocHandler)
  85. goji.Get("/API", http.RedirectHandler("/API/", 301))
  86. if Config.remoteUploads {
  87. goji.Get("/upload", uploadRemote)
  88. goji.Get("/upload/", uploadRemote)
  89. }
  90. goji.Post("/upload", uploadPostHandler)
  91. goji.Post("/upload/", uploadPostHandler)
  92. goji.Put("/upload", uploadPutHandler)
  93. goji.Put("/upload/:name", uploadPutHandler)
  94. goji.Delete("/:name", deleteHandler)
  95. goji.Get("/static/*", staticHandler)
  96. goji.Get("/favicon.ico", staticHandler)
  97. goji.Get("/robots.txt", staticHandler)
  98. goji.Get(nameRe, fileDisplayHandler)
  99. goji.Get(selifRe, fileServeHandler)
  100. goji.Get(selifIndexRe, unauthorizedHandler)
  101. goji.Get(torrentRe, fileTorrentHandler)
  102. goji.NotFound(notFoundHandler)
  103. }
  104. func main() {
  105. flag.StringVar(&Config.bind, "b", "127.0.0.1:8080",
  106. "host to bind to (default: 127.0.0.1:8080)")
  107. flag.StringVar(&Config.filesDir, "filespath", "files/",
  108. "path to files directory")
  109. flag.StringVar(&Config.metaDir, "metapath", "meta/",
  110. "path to metadata directory")
  111. flag.BoolVar(&Config.noLogs, "nologs", false,
  112. "remove stdout output for each request")
  113. flag.BoolVar(&Config.allowHotlink, "allowhotlink", false,
  114. "Allow hotlinking of files")
  115. flag.StringVar(&Config.siteName, "sitename", "linx",
  116. "name of the site")
  117. flag.StringVar(&Config.siteURL, "siteurl", "http://"+Config.bind+"/",
  118. "site base url (including trailing slash)")
  119. flag.Int64Var(&Config.maxSize, "maxsize", 4*1024*1024*1024,
  120. "maximum upload file size in bytes (default 4GB)")
  121. flag.StringVar(&Config.certFile, "certfile", "",
  122. "path to ssl certificate (for https)")
  123. flag.StringVar(&Config.keyFile, "keyfile", "",
  124. "path to ssl key (for https)")
  125. flag.BoolVar(&Config.fastcgi, "fastcgi", false,
  126. "serve through fastcgi")
  127. flag.BoolVar(&Config.remoteUploads, "remoteuploads", false,
  128. "enable remote uploads")
  129. flag.StringVar(&Config.contentSecurityPolicy, "contentsecuritypolicy",
  130. "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; referrer none;",
  131. "value of default Content-Security-Policy header")
  132. flag.StringVar(&Config.fileContentSecurityPolicy, "filecontentsecuritypolicy",
  133. "default-src 'none'; img-src 'self'; object-src 'self'; media-src 'self'; sandbox; referrer none;",
  134. "value of Content-Security-Policy header for file access")
  135. flag.StringVar(&Config.xFrameOptions, "xframeoptions", "SAMEORIGIN",
  136. "value of X-Frame-Options header")
  137. flag.Parse()
  138. setup()
  139. if Config.fastcgi {
  140. listener, err := net.Listen("tcp", Config.bind)
  141. if err != nil {
  142. log.Fatal("Could not bind: ", err)
  143. }
  144. log.Printf("Serving over fastcgi, bound on %s, using siteurl %s", Config.bind, Config.siteURL)
  145. fcgi.Serve(listener, goji.DefaultMux)
  146. } else if Config.certFile != "" {
  147. log.Printf("Serving over https, bound on %s, using siteurl %s", Config.bind, Config.siteURL)
  148. err := graceful.ListenAndServeTLS(Config.bind, Config.certFile, Config.keyFile, goji.DefaultMux)
  149. if err != nil {
  150. log.Fatal(err)
  151. }
  152. } else {
  153. log.Printf("Serving over http, bound on %s, using siteurl %s", Config.bind, Config.siteURL)
  154. err := graceful.ListenAndServe(Config.bind, goji.DefaultMux)
  155. if err != nil {
  156. log.Fatal(err)
  157. }
  158. }
  159. }