Browse Source

Merge 62e917da6b into d0c7241b31

pull/114/merge
Marko Rizvic 6 years ago
committed by GitHub
parent
commit
5337bf288a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 12 deletions
  1. +9
    -8
      README.md
  2. +10
    -0
      cmd/cmd.go
  3. +55
    -0
      server/handlers.go
  4. +13
    -4
      server/server.go
  5. +23
    -0
      server/storage.go

+ 9
- 8
README.md View File

@@ -42,7 +42,7 @@ listener | port to use for http (:80) | |
profile-listener | port to use for profiler (:6060)| |
force-https | redirect to https | false |
tls-listener | port to use for https (:443) | |
tls-cert-file | path to tls certificate | |
tls-cert-file | path to tls certificate | |
tls-private-key | path to tls private key | |
temp-path | path to temp folder | system temp |
web-path | path to static web files (for development) | |
@@ -50,9 +50,10 @@ provider | which storage provider to use | (s3 or local) |
aws-access-key | aws access key | | AWS_ACCESS_KEY
aws-secret-key | aws access key | | AWS_SECRET_KEY
bucket | aws bucket | | BUCKET
basedir | path storage for local provider| |
lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | |
log | path to log file| |
basedir | path storage for local provider| |
auth-key | key to use for authentication (must be supplied in 'Authorization' header with each request)| |
lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | |
log | path to log file| |

If you want to use TLS using lets encrypt certificates, set lets-encrypt-hosts to your domain, set tls-listener to :443 and enable force-https.

@@ -63,7 +64,7 @@ If you want to use TLS using your own certificates, set tls-listener to :443, fo
Make sure your GOPATH is set correctly.

```
go run main.go -provider=local --listener :8080 --temp-path=/tmp/ --basedir=/tmp/
go run main.go -provider=local --listener :8080 --temp-path=/tmp/ --basedir=/tmp/
```

## Build
@@ -84,7 +85,7 @@ docker run --publish 8080:8080 dutchcoders/transfer.sh:latest --provider local -

Contributions are welcome.

## Creators
## Creators

**Remco Verhoef**
- <https://twitter.com/remco_verhoef>
@@ -94,5 +95,5 @@ Contributions are welcome.

## Copyright and license

Code and documentation copyright 2011-2014 Remco Verhoef.
Code released under [the MIT license](LICENSE).
Code and documentation copyright 2011-2014 Remco Verhoef.
Code released under [the MIT license](LICENSE).

+ 10
- 0
cmd/cmd.go View File

@@ -139,6 +139,12 @@ var globalFlags = []cli.Flag{
Name: "profiler",
Usage: "enable profiling",
},
cli.StringFlag{
Name: "auth-key",
Usage: "auth-key",
Value: "",
EnvVar: "AUTH_KEY",
},
}

type Cmd struct {
@@ -198,6 +204,10 @@ func New() *Cmd {
options = append(options, server.VirustotalKey(v))
}

if v := c.String("auth-key"); v != "" {
options = append(options, server.AuthenticateUploads(v))
}

if v := c.String("clamav-host"); v != "" {
options = append(options, server.ClamavHost(v))
}


+ 55
- 0
server/handlers.go View File

@@ -729,6 +729,47 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) {
}
}

func (s *Server) deleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)

token := vars["token"]
filename := vars["filename"]

var metadata Metadata

reader, _, _, err := s.storage.Get(token, fmt.Sprintf("%s.metadata", filename))
if s.storage.IsNotExist(err) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
} else if err != nil {
log.Printf("%s", err.Error())
http.Error(w, "Could not delete file.", 500)
return
}

defer reader.Close()

if err := json.NewDecoder(reader).Decode(&metadata); err != nil {
log.Printf("%s", err.Error())
http.Error(w, "Could not delete file.", 500)
return
}
if metadata.Downloads >= metadata.MaxDownloads || time.Now().After(metadata.MaxDate) {
// DELETE FILE AND METADATA
if err := s.storage.Delete(token, filename); err != nil {
log.Printf("%s", err.Error())
http.Error(w, "Could not delete file.", 500)
return
}
} else {
http.Error(w, "MaxDownloads or MaxDays not exceeded yet.", 500)
return
}

return

}

func (s *Server) RedirectHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !s.forceHTTPs {
@@ -760,3 +801,17 @@ func LoveHandler(h http.Handler) http.HandlerFunc {
h.ServeHTTP(w, r)
}
}

func (s *Server) AuthenticatedHandler (h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
authKey := r.Header.Get ("Authorization")

if s.AuthKey != "" && authKey != s.AuthKey {
log.Printf("Recieved: Bad Auth Token: %s", authKey)
http.Error(w, errors.New("Bad Auth Token").Error(), 403)
return
}

h.ServeHTTP(w, r)
}
}

+ 13
- 4
server/server.go View File

@@ -75,6 +75,12 @@ func VirustotalKey(s string) OptionFn {
}
}

func AuthenticateUploads(key string) OptionFn {
return func(srvr *Server) {
srvr.AuthKey = key
}
}

func Listener(s string) OptionFn {
return func(srvr *Server) {
srvr.ListenerString = s
@@ -189,6 +195,7 @@ type Server struct {
locks map[string]*sync.Mutex

rateLimitRequests int
AuthKey string

storage Storage

@@ -311,16 +318,18 @@ func (s *Server) Run() {
getHandlerFn = ratelimit.Request(ratelimit.IP).Rate(s.rateLimitRequests, 60*time.Second).LimitBy(memory.New())(http.HandlerFunc(getHandlerFn)).ServeHTTP
}

r.HandleFunc("/{token}/{filename}", s.AuthenticatedHandler (http.HandlerFunc (s.deleteHandler))).Methods("DELETE")

r.HandleFunc("/{token}/{filename}", getHandlerFn).Methods("GET")
r.HandleFunc("/get/{token}/{filename}", getHandlerFn).Methods("GET")
r.HandleFunc("/download/{token}/{filename}", getHandlerFn).Methods("GET")

r.HandleFunc("/{filename}/virustotal", s.virusTotalHandler).Methods("PUT")
r.HandleFunc("/{filename}/scan", s.scanHandler).Methods("PUT")
r.HandleFunc("/put/{filename}", s.putHandler).Methods("PUT")
r.HandleFunc("/upload/{filename}", s.putHandler).Methods("PUT")
r.HandleFunc("/{filename}", s.putHandler).Methods("PUT")
r.HandleFunc("/", s.postHandler).Methods("POST")
r.HandleFunc("/put/{filename}", s.AuthenticatedHandler (http.HandlerFunc (s.putHandler))).Methods("PUT")
r.HandleFunc("/upload/{filename}", s.AuthenticatedHandler (http.HandlerFunc (s.putHandler))).Methods("PUT")
r.HandleFunc("/{filename}", s.AuthenticatedHandler (http.HandlerFunc (s.putHandler))).Methods("PUT")
r.HandleFunc("/", s.AuthenticatedHandler (http.HandlerFunc (s.postHandler))).Methods("POST")
// r.HandleFunc("/{page}", viewHandler).Methods("GET")

r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler)


+ 23
- 0
server/storage.go View File

@@ -10,6 +10,7 @@ import (
"path/filepath"
"strconv"
"sync"
"errors"

"github.com/goamz/goamz/s3"
)
@@ -18,6 +19,7 @@ type Storage interface {
Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error)
Head(token string, filename string) (contentType string, contentLength uint64, err error)
Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
Delete(token string, filename string) error
IsNotExist(err error) bool

Type() string
@@ -103,6 +105,27 @@ func (s *LocalStorage) Put(token string, filename string, reader io.Reader, cont
return nil
}

func (s *LocalStorage) Delete(token string, filename string) error {
var err error

userdatafile := filepath.Join(s.basedir, token, filename)
metadatafile := filepath.Join(s.basedir, token, fmt.Sprintf("%s.metadata", filename))

if err = os.Remove(userdatafile); err != nil {
return err
}

if err = os.Remove(metadatafile); err != nil {
return err
}

return nil
}

func (s *S3Storage) Delete(token string, filename string) error {
return errors.New("Delete function for S3Storage not yet implemented")
}

type S3Storage struct {
Storage
bucket *s3.Bucket


Loading…
Cancel
Save