updated readme & go formatted code

This commit is contained in:
Remco 2014-10-20 14:54:42 +02:00
parent 16ad1833d2
commit b8eaf23805
4 changed files with 92 additions and 91 deletions

View file

@ -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)

View file

@ -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)

View file

@ -132,22 +132,22 @@ func main() {
config.Temp = *temp
var err error
var err error
switch *provider {
case "s3":
storage, err = NewS3Storage()
case "local":
if *basedir == "" {
log.Panic("basedir not set")
}
switch *provider {
case "s3":
storage, err = NewS3Storage()
case "local":
if *basedir == "" {
log.Panic("basedir not set")
}
storage, err = NewLocalStorage(*basedir)
}
storage, err = NewLocalStorage(*basedir)
}
if err != nil {
log.Panic("Error while creating storage.")
}
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("---------------------------")

View file

@ -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)
// 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 {
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
}