mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-11-23 04:30:19 +01:00
updated readme & go formatted code
This commit is contained in:
parent
16ad1833d2
commit
b8eaf23805
4 changed files with 92 additions and 91 deletions
|
@ -1,6 +1,8 @@
|
|||
# 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)
|
||||
|
||||
|
|
|
@ -38,19 +38,19 @@ import (
|
|||
"github.com/golang/gddo/httputil/header"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/kennygrant/sanitize"
|
||||
html_template "html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"log"
|
||||
"math/rand"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
html_template "html/template"
|
||||
text_template "text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
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) {
|
||||
http.Error(w, http.StatusText(404), 404)
|
||||
http.Error(w, http.StatusText(404), 404)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
|
@ -275,7 +275,7 @@ func putHandler(w http.ResponseWriter, r *http.Request) {
|
|||
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)
|
||||
|
||||
|
@ -307,8 +307,8 @@ func zipHandler(w http.ResponseWriter, r *http.Request) {
|
|||
zw := zip.NewWriter(w)
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
|
@ -322,7 +322,7 @@ func zipHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
defer reader.Close()
|
||||
defer reader.Close()
|
||||
|
||||
header := &zip.FileHeader{
|
||||
Name: strings.Split(key, "/")[1],
|
||||
|
@ -371,8 +371,8 @@ func tarGzHandler(w http.ResponseWriter, r *http.Request) {
|
|||
defer zw.Close()
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
|
@ -386,7 +386,7 @@ func tarGzHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
defer reader.Close()
|
||||
defer reader.Close()
|
||||
|
||||
header := &tar.Header{
|
||||
Name: strings.Split(key, "/")[1],
|
||||
|
@ -423,8 +423,8 @@ func tarHandler(w http.ResponseWriter, r *http.Request) {
|
|||
defer zw.Close()
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
|
@ -438,7 +438,7 @@ func tarHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
defer reader.Close()
|
||||
defer reader.Close()
|
||||
|
||||
header := &tar.Header{
|
||||
Name: strings.Split(key, "/")[1],
|
||||
|
@ -466,7 +466,7 @@ func getHandler(w http.ResponseWriter, r *http.Request) {
|
|||
token := vars["token"]
|
||||
filename := vars["filename"]
|
||||
|
||||
reader, contentType, contentLength, err := storage.Get(token, filename)
|
||||
reader, contentType, contentLength, err := storage.Get(token, filename)
|
||||
if err != nil {
|
||||
if err.Error() == "The specified key does not exist." {
|
||||
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-Length", strconv.FormatUint(contentLength, 10))
|
||||
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10))
|
||||
|
||||
mediaType, _, _ := mime.ParseMediaType(contentType)
|
||||
|
||||
|
|
|
@ -131,23 +131,23 @@ func main() {
|
|||
}
|
||||
|
||||
config.Temp = *temp
|
||||
|
||||
var err error
|
||||
|
||||
switch *provider {
|
||||
case "s3":
|
||||
storage, err = NewS3Storage()
|
||||
case "local":
|
||||
if *basedir == "" {
|
||||
log.Panic("basedir not set")
|
||||
}
|
||||
var err error
|
||||
|
||||
storage, err = NewLocalStorage(*basedir)
|
||||
}
|
||||
switch *provider {
|
||||
case "s3":
|
||||
storage, err = NewS3Storage()
|
||||
case "local":
|
||||
if *basedir == "" {
|
||||
log.Panic("basedir not set")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Panic("Error while creating storage.")
|
||||
}
|
||||
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("---------------------------")
|
||||
|
|
|
@ -1,100 +1,99 @@
|
|||
package main
|
||||
|
||||
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 {
|
||||
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 {
|
||||
Storage
|
||||
basedir string
|
||||
Storage
|
||||
basedir string
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
Storage
|
||||
bucket *s3.Bucket
|
||||
Storage
|
||||
bucket *s3.Bucket
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
reader = response.Body
|
||||
return
|
||||
// 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
|
||||
}
|
||||
|
||||
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…
Reference in a new issue