瀏覽代碼

updated readme & go formatted code

tags/v1.0.0
Remco 9 年之前
父節點
當前提交
b8eaf23805
共有 4 個檔案被更改,包括 95 行新增94 行删除
  1. +3
    -1
      README.md
  2. +18
    -18
      transfersh-server/handlers.go
  3. +17
    -17
      transfersh-server/main.go
  4. +57
    -58
      transfersh-server/storage.go

+ 3
- 1
README.md 查看文件

@@ -1,6 +1,8 @@
# transfer.sh # transfer.sh


Easy and fast file sharing from the command-line. This code contains the server with everything you need to create your own instance. Transfer.sh currently runs on top of Amazon S3. Other storage types will be added shortly.
Easy and fast file sharing from the command-line. This code contains the server with everything you need to create your own instance.

Transfer.sh support currently the s3 (Amazon S3) provider and local file system (local).


[![Build Status](https://travis-ci.org/dutchcoders/transfer.sh.svg?branch=master)](https://travis-ci.org/dutchcoders/transfer.sh) [![Build Status](https://travis-ci.org/dutchcoders/transfer.sh.svg?branch=master)](https://travis-ci.org/dutchcoders/transfer.sh)




+ 18
- 18
transfersh-server/handlers.go 查看文件

@@ -38,19 +38,19 @@ import (
"github.com/golang/gddo/httputil/header" "github.com/golang/gddo/httputil/header"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/kennygrant/sanitize" "github.com/kennygrant/sanitize"
html_template "html/template"
"io" "io"
"io/ioutil" "io/ioutil"
"strconv"
"log" "log"
"math/rand" "math/rand"
"mime" "mime"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"time"
html_template "html/template"
text_template "text/template" text_template "text/template"
"time"
) )


func healthHandler(w http.ResponseWriter, r *http.Request) { func healthHandler(w http.ResponseWriter, r *http.Request) {
@@ -101,7 +101,7 @@ func viewHandler(w http.ResponseWriter, r *http.Request) {
} }


func notFoundHandler(w http.ResponseWriter, r *http.Request) { func notFoundHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(404), 404)
http.Error(w, http.StatusText(404), 404)
} }


func postHandler(w http.ResponseWriter, r *http.Request) { func postHandler(w http.ResponseWriter, r *http.Request) {
@@ -169,7 +169,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {


log.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType) log.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType)


if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil {
if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil {
log.Print(err) log.Print(err)
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)
return return
@@ -275,7 +275,7 @@ func putHandler(w http.ResponseWriter, r *http.Request) {
contentType = mime.TypeByExtension(filepath.Ext(vars["filename"])) contentType = mime.TypeByExtension(filepath.Ext(vars["filename"]))
} }


token := Encode(10000000+int64(rand.Intn(1000000000)))
token := Encode(10000000 + int64(rand.Intn(1000000000)))


log.Printf("Uploading %s %d %s", token, filename, contentLength, contentType) log.Printf("Uploading %s %d %s", token, filename, contentLength, contentType)


@@ -307,8 +307,8 @@ func zipHandler(w http.ResponseWriter, r *http.Request) {
zw := zip.NewWriter(w) zw := zip.NewWriter(w)


for _, key := range strings.Split(files, ",") { for _, key := range strings.Split(files, ",") {
token := sanitize.Path(strings.Split(key, "/")[0])
filename := sanitize.Path(strings.Split(key, "/")[1])
token := sanitize.Path(strings.Split(key, "/")[0])
filename := sanitize.Path(strings.Split(key, "/")[1])


reader, _, _, err := storage.Get(token, filename) reader, _, _, err := storage.Get(token, filename)
if err != nil { if err != nil {
@@ -322,7 +322,7 @@ func zipHandler(w http.ResponseWriter, r *http.Request) {
} }
} }


defer reader.Close()
defer reader.Close()


header := &zip.FileHeader{ header := &zip.FileHeader{
Name: strings.Split(key, "/")[1], Name: strings.Split(key, "/")[1],
@@ -371,8 +371,8 @@ func tarGzHandler(w http.ResponseWriter, r *http.Request) {
defer zw.Close() defer zw.Close()


for _, key := range strings.Split(files, ",") { for _, key := range strings.Split(files, ",") {
token := strings.Split(key, "/")[0]
filename := strings.Split(key, "/")[1]
token := strings.Split(key, "/")[0]
filename := strings.Split(key, "/")[1]


reader, _, contentLength, err := storage.Get(token, filename) reader, _, contentLength, err := storage.Get(token, filename)
if err != nil { if err != nil {
@@ -386,7 +386,7 @@ func tarGzHandler(w http.ResponseWriter, r *http.Request) {
} }
} }


defer reader.Close()
defer reader.Close()


header := &tar.Header{ header := &tar.Header{
Name: strings.Split(key, "/")[1], Name: strings.Split(key, "/")[1],
@@ -423,8 +423,8 @@ func tarHandler(w http.ResponseWriter, r *http.Request) {
defer zw.Close() defer zw.Close()


for _, key := range strings.Split(files, ",") { for _, key := range strings.Split(files, ",") {
token := strings.Split(key, "/")[0]
filename := strings.Split(key, "/")[1]
token := strings.Split(key, "/")[0]
filename := strings.Split(key, "/")[1]


reader, _, contentLength, err := storage.Get(token, filename) reader, _, contentLength, err := storage.Get(token, filename)
if err != nil { if err != nil {
@@ -438,7 +438,7 @@ func tarHandler(w http.ResponseWriter, r *http.Request) {
} }
} }


defer reader.Close()
defer reader.Close()


header := &tar.Header{ header := &tar.Header{
Name: strings.Split(key, "/")[1], Name: strings.Split(key, "/")[1],
@@ -466,7 +466,7 @@ func getHandler(w http.ResponseWriter, r *http.Request) {
token := vars["token"] token := vars["token"]
filename := vars["filename"] filename := vars["filename"]


reader, contentType, contentLength, err := storage.Get(token, filename)
reader, contentType, contentLength, err := storage.Get(token, filename)
if err != nil { if err != nil {
if err.Error() == "The specified key does not exist." { if err.Error() == "The specified key does not exist." {
http.Error(w, "File not found", 404) http.Error(w, "File not found", 404)
@@ -478,10 +478,10 @@ func getHandler(w http.ResponseWriter, r *http.Request) {
} }
} }


defer reader.Close()
defer reader.Close()


w.Header().Set("Content-Type", contentType) w.Header().Set("Content-Type", contentType)
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10))
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10))


mediaType, _, _ := mime.ParseMediaType(contentType) mediaType, _, _ := mime.ParseMediaType(contentType)




+ 17
- 17
transfersh-server/main.go 查看文件

@@ -131,23 +131,23 @@ func main() {
} }


config.Temp = *temp config.Temp = *temp
var err error
switch *provider {
case "s3":
storage, err = NewS3Storage()
case "local":
if *basedir == "" {
log.Panic("basedir not set")
}
storage, err = NewLocalStorage(*basedir)
}
if err != nil {
log.Panic("Error while creating storage.")
}
var err error
switch *provider {
case "s3":
storage, err = NewS3Storage()
case "local":
if *basedir == "" {
log.Panic("basedir not set")
}
storage, err = NewLocalStorage(*basedir)
}
if err != nil {
log.Panic("Error while creating storage.")
}


log.Printf("Transfer.sh server started. :%v using temp folder: %s", *port, config.Temp) log.Printf("Transfer.sh server started. :%v using temp folder: %s", *port, config.Temp)
log.Printf("---------------------------") log.Printf("---------------------------")


+ 57
- 58
transfersh-server/storage.go 查看文件

@@ -1,100 +1,99 @@
package main package main


import ( import (
"io"
"github.com/goamz/goamz/s3"
"strconv"
"fmt"
"os"
"path/filepath"
"fmt"
"github.com/goamz/goamz/s3"
"io"
"os"
"path/filepath"
"strconv"
) )


type Storage interface { type Storage interface {
Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error)
Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error)
Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
} }


type LocalStorage struct { type LocalStorage struct {
Storage
basedir string
Storage
basedir string
} }


func NewLocalStorage(basedir string) (*LocalStorage, error) { func NewLocalStorage(basedir string) (*LocalStorage, error) {
return &LocalStorage {basedir: basedir}, nil
return &LocalStorage{basedir: basedir}, nil
} }


func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
path := filepath.Join(s.basedir, token, filename)


func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
path := filepath.Join(s.basedir, token, filename)
// content type , content length
if reader, err = os.Open(path); err != nil {
return
}


// content type , content length
if reader, err = os.Open(path); err != nil {
return
}
var fi os.FileInfo
if fi, err = os.Lstat(path); err != nil {
}


var fi os.FileInfo
if fi, err = os.Lstat(path); err != nil {
}
contentLength = uint64(fi.Size())


contentLength = uint64(fi.Size())
contentType = ""


contentType = ""

return
return
} }


func (s *LocalStorage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error { func (s *LocalStorage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error {
var f io.WriteCloser
var err error
var f io.WriteCloser
var err error


path := filepath.Join(s.basedir, token)
path := filepath.Join(s.basedir, token)


if err = os.Mkdir(path, 0700); err != nil && !os.IsExist(err) {
return err
}
if err = os.Mkdir(path, 0700); err != nil && !os.IsExist(err) {
return err
}


if f, err = os.OpenFile(filepath.Join(path, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
fmt.Printf("%s", err)
return err
}
if f, err = os.OpenFile(filepath.Join(path, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
fmt.Printf("%s", err)
return err
}


defer f.Close()
defer f.Close()


if _, err = io.Copy(f, reader); err != nil {
return err
}
if _, err = io.Copy(f, reader); err != nil {
return err
}


return nil
return nil
} }


type S3Storage struct { type S3Storage struct {
Storage
bucket *s3.Bucket
Storage
bucket *s3.Bucket
} }


func NewS3Storage() (*S3Storage, error) { func NewS3Storage() (*S3Storage, error) {
bucket, err := getBucket()
if err != nil {
return nil, err
}
bucket, err := getBucket()
if err != nil {
return nil, err
}


return &S3Storage {bucket: bucket}, nil
return &S3Storage{bucket: bucket}, nil
} }


func (s *S3Storage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
key := fmt.Sprintf("%s/%s", token, filename)
func (s *S3Storage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
key := fmt.Sprintf("%s/%s", token, filename)

// content type , content length
response, err := s.bucket.GetResponse(key)
contentType = ""
contentLength, err = strconv.ParseUint(response.Header.Get("Content-Length"), 10, 0)


// content type , content length
response, err := s.bucket.GetResponse(key)
contentType = ""
contentLength, err = strconv.ParseUint(response.Header.Get("Content-Length"), 10, 0)
reader = response.Body
return
reader = response.Body
return
} }


func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error { func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error {
key := fmt.Sprintf("%s/%s", token, filename)
err := s.bucket.PutReader(key, reader, int64(contentLength), contentType, s3.Private, s3.Options{})
return err
key := fmt.Sprintf("%s/%s", token, filename)
err := s.bucket.PutReader(key, reader, int64(contentLength), contentType, s3.Private, s3.Options{})
return err
} }

Loading…
取消
儲存