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.

96 lines
1.7 KiB

  1. package main
  2. import (
  3. "bytes"
  4. "crypto/sha1"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "path"
  10. "time"
  11. "github.com/zeebo/bencode"
  12. "github.com/zenazn/goji/web"
  13. )
  14. const (
  15. TORRENT_PIECE_LENGTH = 262144
  16. )
  17. func check(e error) {
  18. if e != nil {
  19. panic(e)
  20. }
  21. }
  22. type TorrentInfo struct {
  23. PieceLength int `bencode:"piece length"`
  24. Pieces []byte `bencode:"pieces"`
  25. Name string `bencode:"name"`
  26. Length int `bencode:"length"`
  27. }
  28. type Torrent struct {
  29. Encoding string `bencode:"encoding"`
  30. Info TorrentInfo `bencode:"info"`
  31. UrlList []string `bencode:"url-list"`
  32. }
  33. func CreateTorrent(fileName string, filePath string) []byte {
  34. chunk := make([]byte, TORRENT_PIECE_LENGTH)
  35. var pieces []byte
  36. length := 0
  37. f, err := os.Open(filePath)
  38. check(err)
  39. for {
  40. n, err := f.Read(chunk)
  41. if err == io.EOF {
  42. break
  43. }
  44. check(err)
  45. length += n
  46. h := sha1.New()
  47. h.Write(chunk)
  48. pieces = append(pieces, h.Sum(nil)...)
  49. }
  50. f.Close()
  51. torrent := &Torrent{
  52. Encoding: "UTF-8",
  53. Info: TorrentInfo{
  54. PieceLength: TORRENT_PIECE_LENGTH,
  55. Pieces: pieces,
  56. Name: fileName,
  57. Length: length,
  58. },
  59. UrlList: []string{fmt.Sprintf("%sselif/%s", Config.siteURL, fileName)},
  60. }
  61. data, err := bencode.EncodeBytes(torrent)
  62. check(err)
  63. return data
  64. }
  65. func fileTorrentHandler(c web.C, w http.ResponseWriter, r *http.Request) {
  66. fileName := c.URLParams["name"]
  67. filePath := path.Join(Config.filesDir, fileName)
  68. if !fileExistsAndNotExpired(fileName) {
  69. notFoundHandler(c, w, r)
  70. return
  71. }
  72. encoded := CreateTorrent(fileName, filePath)
  73. w.Header().Set(`Content-Disposition`, fmt.Sprintf(`attachment; filename="%s.torrent"`, fileName))
  74. http.ServeContent(w, r, "", time.Now(), bytes.NewReader(encoded))
  75. }
  76. // vim:set ts=8 sw=8 noet: