download.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "io"
  7. "path"
  8. "github.com/G-Node/git-module"
  9. "bufio"
  10. "github.com/G-Node/go-annex"
  11. "github.com/G-Node/gogs/pkg/context"
  12. "github.com/G-Node/gogs/pkg/setting"
  13. "github.com/G-Node/gogs/pkg/tool"
  14. "os"
  15. "github.com/go-macaron/captcha"
  16. )
  17. func ServeData(c *context.Context, name string, reader io.Reader, cpt *captcha.Captcha) error {
  18. buf := make([]byte, 1024)
  19. n, _ := reader.Read(buf)
  20. if n >= 0 {
  21. buf = buf[:n]
  22. }
  23. isannex := tool.IsAnnexedFile(buf)
  24. var afpR *bufio.Reader
  25. var afp *os.File
  26. if isannex == true {
  27. af, err := gannex.NewAFile(c.Repo.Repository.RepoPath(), "annex", name, buf)
  28. if err != nil {
  29. }
  30. if cpt!=nil && af.Info.Size() > gannex.MEGABYTE*setting.Repository.RawCaptchaMinFileSize && !cpt.VerifyReq(c.Req) &&
  31. !c.IsLogged {
  32. c.Data["EnableCaptcha"] = true
  33. c.HTML(200, "repo/download")
  34. return nil
  35. }
  36. afp, err = af.Open()
  37. defer afp.Close()
  38. if err != nil {
  39. }
  40. afpR = bufio.NewReader(afp)
  41. buf, _ = afpR.Peek(1024)
  42. }
  43. if !tool.IsTextFile(buf) {
  44. if !tool.IsImageFile(buf) {
  45. c.Resp.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
  46. c.Resp.Header().Set("Content-Transfer-Encoding", "binary")
  47. }
  48. } else if !setting.Repository.EnableRawFileRenderMode || !c.QueryBool("render") {
  49. c.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
  50. }
  51. if isannex {
  52. _, err := io.Copy(c.Resp, afpR)
  53. return err
  54. }
  55. c.Resp.Write(buf)
  56. _, err := io.Copy(c.Resp, reader)
  57. return err
  58. }
  59. func ServeBlob(c *context.Context, blob *git.Blob, cpt *captcha.Captcha) error {
  60. r, w := io.Pipe()
  61. defer r.Close()
  62. defer w.Close()
  63. go blob.DataPipeline(w, w)
  64. return ServeData(c, path.Base(c.Repo.TreePath), io.LimitReader(r, blob.Size()), cpt)
  65. }
  66. func SingleDownload(c *context.Context, cpt *captcha.Captcha) {
  67. blob, err := c.Repo.Commit.GetBlobByPath(c.Repo.TreePath)
  68. if err != nil {
  69. if git.IsErrNotExist(err) {
  70. c.Handle(404, "GetBlobByPath", nil)
  71. } else {
  72. c.Handle(500, "GetBlobByPath", err)
  73. }
  74. return
  75. }
  76. // reallow direct download independent of size
  77. if err = ServeBlob(c, blob, nil); err != nil {
  78. c.Handle(500, "ServeBlob", err)
  79. }
  80. }