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.

100 lines
2.0 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. type TorrentInfo struct {
  18. PieceLength int `bencode:"piece length"`
  19. Pieces string `bencode:"pieces"`
  20. Name string `bencode:"name"`
  21. Length int `bencode:"length"`
  22. }
  23. type Torrent struct {
  24. Encoding string `bencode:"encoding"`
  25. Info TorrentInfo `bencode:"info"`
  26. UrlList []string `bencode:"url-list"`
  27. }
  28. func hashPiece(piece []byte) []byte {
  29. h := sha1.New()
  30. h.Write(piece)
  31. return h.Sum(nil)
  32. }
  33. func createTorrent(fileName string, filePath string) ([]byte, error) {
  34. chunk := make([]byte, TORRENT_PIECE_LENGTH)
  35. torrent := Torrent{
  36. Encoding: "UTF-8",
  37. Info: TorrentInfo{
  38. PieceLength: TORRENT_PIECE_LENGTH,
  39. Name: fileName,
  40. },
  41. UrlList: []string{fmt.Sprintf("%sselif/%s", Config.siteURL, fileName)},
  42. }
  43. f, err := os.Open(filePath)
  44. if err != nil {
  45. return []byte{}, err
  46. }
  47. for {
  48. n, err := f.Read(chunk)
  49. if err == io.EOF {
  50. break
  51. } else if err != nil {
  52. return []byte{}, err
  53. }
  54. torrent.Info.Length += n
  55. torrent.Info.Pieces += string(hashPiece(chunk[:n]))
  56. }
  57. f.Close()
  58. data, err := bencode.EncodeBytes(&torrent)
  59. if err != nil {
  60. return []byte{}, err
  61. }
  62. return data, nil
  63. }
  64. func fileTorrentHandler(c web.C, w http.ResponseWriter, r *http.Request) {
  65. fileName := c.URLParams["name"]
  66. filePath := path.Join(Config.filesDir, fileName)
  67. err := checkFile(fileName)
  68. if err == NotFoundErr {
  69. notFoundHandler(c, w, r)
  70. return
  71. } else if err == BadMetadata {
  72. oopsHandler(c, w, r, RespAUTO, "Corrupt metadata.")
  73. return
  74. }
  75. encoded, err := createTorrent(fileName, filePath)
  76. if err != nil {
  77. oopsHandler(c, w, r, RespHTML, "Could not create torrent.")
  78. return
  79. }
  80. w.Header().Set(`Content-Disposition`, fmt.Sprintf(`attachment; filename="%s.torrent"`, fileName))
  81. http.ServeContent(w, r, "", time.Now(), bytes.NewReader(encoded))
  82. }