From 964e8c92d733d1c23c0457705cf5446f514b5c9d Mon Sep 17 00:00:00 2001 From: Remco Date: Thu, 23 Mar 2017 00:03:32 +0100 Subject: [PATCH] Remove bak files --- server/codec.go.bak | 65 ---- server/handlers.go.bak | 620 --------------------------------------- server/server.go.bak | 239 --------------- server/storage.go.bak | 268 ----------------- server/utils.go.bak | 276 ----------------- server/virustotal.go.bak | 67 ----- 6 files changed, 1535 deletions(-) delete mode 100644 server/codec.go.bak delete mode 100644 server/handlers.go.bak delete mode 100644 server/server.go.bak delete mode 100644 server/storage.go.bak delete mode 100644 server/utils.go.bak delete mode 100644 server/virustotal.go.bak diff --git a/server/codec.go.bak b/server/codec.go.bak deleted file mode 100644 index 4c8d30b..0000000 --- a/server/codec.go.bak +++ /dev/null @@ -1,65 +0,0 @@ -/* -https://github.com/fs111/kurz.go/blob/master/src/codec.go - -Originally written and Copyright (c) 2011 André Kelpe -Modifications Copyright (c) 2015 John Ko - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package main - -import ( - "math" - "strings" -) - -const ( - // characters used for short-urls - SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - - // someone set us up the bomb !! - BASE = int64(len(SYMBOLS)) -) - -// encodes a number into our *base* representation -// TODO can this be made better with some bitshifting? -func Encode(number int64) string { - rest := number % BASE - // strings are a bit weird in go... - result := string(SYMBOLS[rest]) - if number-rest != 0 { - newnumber := (number - rest) / BASE - result = Encode(newnumber) + result - } - return result -} - -// Decodes a string given in our encoding and returns the decimal -// integer. -func Decode(input string) int64 { - const floatbase = float64(BASE) - l := len(input) - var sum int = 0 - for index := l - 1; index > -1; index -= 1 { - current := string(input[index]) - pos := strings.Index(SYMBOLS, current) - sum = sum + (pos * int(math.Pow(floatbase, float64((l-index-1))))) - } - return int64(sum) -} diff --git a/server/handlers.go.bak b/server/handlers.go.bak deleted file mode 100644 index 6299484..0000000 --- a/server/handlers.go.bak +++ /dev/null @@ -1,620 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2014 DutchCoders [https://github.com/dutchcoders/] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - // _ "transfer.sh/app/handlers" - // _ "transfer.sh/app/utils" - - "archive/tar" - "archive/zip" - "bytes" - "compress/gzip" - "errors" - "fmt" - "html" - html_template "html/template" - "io" - "io/ioutil" - "log" - "math/rand" - "mime" - "net/http" - "os" - "path/filepath" - "strconv" - "strings" - text_template "text/template" - "time" - - clamd "github.com/dutchcoders/go-clamd" - - web "github.com/dutchcoders/transfer.sh-web" - "github.com/gorilla/mux" - "github.com/kennygrant/sanitize" - "github.com/russross/blackfriday" -) - -var ( - html_templates = initHTMLTemplates() - text_templates = initTextTemplates() -) - -func stripPrefix(path string) string { - return strings.Replace(path, web.Prefix+"/", "", -1) -} - -func initTextTemplates() *text_template.Template { - templateMap := text_template.FuncMap{"format": formatNumber} - - // Templates with functions available to them - var templates = text_template.New("").Funcs(templateMap) - return templates -} - -func initHTMLTemplates() *html_template.Template { - templateMap := html_template.FuncMap{"format": formatNumber} - - // Templates with functions available to them - var templates = html_template.New("").Funcs(templateMap) - - return templates -} - -func healthHandler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Approaching Neutral Zone, all systems normal and functioning.") -} - -/* The preview handler will show a preview of the content for browsers (accept type text/html), and referer is not transfer.sh */ -func previewHandler(w http.ResponseWriter, r *http.Request) { - - vars := mux.Vars(r) - - token := vars["token"] - filename := vars["filename"] - - contentType, contentLength, err := storage.Head(token, filename) - if err != nil { - http.Error(w, http.StatusText(404), 404) - return - } - - var templatePath string - var content html_template.HTML - - switch { - case strings.HasPrefix(contentType, "image/"): - templatePath = "download.image.html" - case strings.HasPrefix(contentType, "video/"): - templatePath = "download.video.html" - case strings.HasPrefix(contentType, "audio/"): - templatePath = "download.audio.html" - case strings.HasPrefix(contentType, "text/"): - templatePath = "download.markdown.html" - - var reader io.ReadCloser - if reader, _, _, err = storage.Get(token, filename); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - var data []byte - if data, err = ioutil.ReadAll(reader); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - if strings.HasPrefix(contentType, "text/x-markdown") || strings.HasPrefix(contentType, "text/markdown") { - output := blackfriday.MarkdownCommon(data) - content = html_template.HTML(output) - } else if strings.HasPrefix(contentType, "text/plain") { - content = html_template.HTML(fmt.Sprintf("
%s
", html.EscapeString(string(data)))) - } else { - templatePath = "download.sandbox.html" - } - - default: - templatePath = "download.html" - } - - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - data := struct { - ContentType string - Content html_template.HTML - Filename string - Url string - ContentLength uint64 - }{ - contentType, - content, - filename, - r.URL.String(), - contentLength, - } - - if err := html_templates.ExecuteTemplate(w, templatePath, data); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - -} - -// this handler will output html or text, depending on the -// support of the client (Accept header). - -func viewHandler(w http.ResponseWriter, r *http.Request) { - // vars := mux.Vars(r) - - if acceptsHtml(r.Header) { - if err := html_templates.ExecuteTemplate(w, "index.html", nil); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } else { - if err := text_templates.ExecuteTemplate(w, "index.txt", nil); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } -} - -func notFoundHandler(w http.ResponseWriter, r *http.Request) { - http.Error(w, http.StatusText(404), 404) -} - -func postHandler(w http.ResponseWriter, r *http.Request) { - if err := r.ParseMultipartForm(_24K); nil != err { - log.Printf("%s", err.Error()) - http.Error(w, "Error occurred copying to output stream", 500) - return - } - - token := Encode(10000000 + int64(rand.Intn(1000000000))) - - w.Header().Set("Content-Type", "text/plain") - - for _, fheaders := range r.MultipartForm.File { - for _, fheader := range fheaders { - filename := sanitize.Path(filepath.Base(fheader.Filename)) - contentType := fheader.Header.Get("Content-Type") - - if contentType == "" { - contentType = mime.TypeByExtension(filepath.Ext(fheader.Filename)) - } - - var f io.Reader - var err error - - if f, err = fheader.Open(); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - var b bytes.Buffer - - n, err := io.CopyN(&b, f, _24K+1) - if err != nil && err != io.EOF { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - var reader io.Reader - - if n > _24K { - file, err := ioutil.TempFile(config.Temp, "transfer-") - if err != nil { - log.Fatal(err) - } - defer file.Close() - - n, err = io.Copy(file, io.MultiReader(&b, f)) - if err != nil { - os.Remove(file.Name()) - - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - reader, err = os.Open(file.Name()) - } else { - reader = bytes.NewReader(b.Bytes()) - } - - contentLength := n - - log.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType) - - if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - - } - - fmt.Fprintf(w, "https://%s/%s/%s\n", ipAddrFromRemoteAddr(r.Host), token, filename) - } - } -} - -func scanHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - filename := sanitize.Path(filepath.Base(vars["filename"])) - - contentLength := r.ContentLength - contentType := r.Header.Get("Content-Type") - - log.Printf("Scanning %s %d %s", filename, contentLength, contentType) - - var reader io.Reader - - reader = r.Body - - c := clamd.NewClamd(config.CLAMAV_DAEMON_HOST) - - abort := make(chan bool) - response, err := c.ScanStream(reader, abort) - if err != nil { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - select { - case s := <-response: - w.Write([]byte(fmt.Sprintf("%v\n", s.Status))) - case <-time.After(time.Second * 60): - abort <- true - } - - close(abort) -} - -func putHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - filename := sanitize.Path(filepath.Base(vars["filename"])) - - contentLength := r.ContentLength - - var reader io.Reader - - reader = r.Body - - if contentLength == -1 { - // queue file to disk, because s3 needs content length - var err error - var f io.Reader - - f = reader - - var b bytes.Buffer - - n, err := io.CopyN(&b, f, _24K+1) - if err != nil && err != io.EOF { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - if n > _24K { - file, err := ioutil.TempFile(config.Temp, "transfer-") - if err != nil { - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - defer file.Close() - - n, err = io.Copy(file, io.MultiReader(&b, f)) - if err != nil { - os.Remove(file.Name()) - log.Printf("%s", err.Error()) - http.Error(w, err.Error(), 500) - return - } - - reader, err = os.Open(file.Name()) - } else { - reader = bytes.NewReader(b.Bytes()) - } - - contentLength = n - } - - contentType := r.Header.Get("Content-Type") - - if contentType == "" { - contentType = mime.TypeByExtension(filepath.Ext(vars["filename"])) - } - - token := Encode(10000000 + int64(rand.Intn(1000000000))) - - log.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType) - - var err error - - if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, errors.New("Could not save file").Error(), 500) - return - } - - // w.Statuscode = 200 - - w.Header().Set("Content-Type", "text/plain") - - fmt.Fprintf(w, "https://%s/%s/%s\n", ipAddrFromRemoteAddr(r.Host), token, filename) -} - -func zipHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - files := vars["files"] - - zipfilename := fmt.Sprintf("transfersh-%d.zip", uint16(time.Now().UnixNano())) - - w.Header().Set("Content-Type", "application/zip") - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipfilename)) - w.Header().Set("Connection", "close") - - zw := zip.NewWriter(w) - - for _, key := range strings.Split(files, ",") { - if strings.HasPrefix(key, "/") { - key = key[1:] - } - - key = strings.Replace(key, "\\", "/", -1) - - token := strings.Split(key, "/")[0] - filename := sanitize.Path(strings.Split(key, "/")[1]) - - reader, _, _, err := storage.Get(token, filename) - - if err != nil { - if storage.IsNotExist(err) { - http.Error(w, "File not found", 404) - return - } else { - log.Printf("%s", err.Error()) - http.Error(w, "Could not retrieve file.", 500) - return - } - } - - defer reader.Close() - - header := &zip.FileHeader{ - Name: strings.Split(key, "/")[1], - Method: zip.Store, - ModifiedTime: uint16(time.Now().UnixNano()), - ModifiedDate: uint16(time.Now().UnixNano()), - } - - fw, err := zw.CreateHeader(header) - - if err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - - if _, err = io.Copy(fw, reader); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - } - - if err := zw.Close(); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } -} - -func tarGzHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - files := vars["files"] - - tarfilename := fmt.Sprintf("transfersh-%d.tar.gz", uint16(time.Now().UnixNano())) - - w.Header().Set("Content-Type", "application/x-gzip") - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", tarfilename)) - w.Header().Set("Connection", "close") - - os := gzip.NewWriter(w) - defer os.Close() - - zw := tar.NewWriter(os) - defer zw.Close() - - for _, key := range strings.Split(files, ",") { - if strings.HasPrefix(key, "/") { - key = key[1:] - } - - key = strings.Replace(key, "\\", "/", -1) - - token := strings.Split(key, "/")[0] - filename := sanitize.Path(strings.Split(key, "/")[1]) - - reader, _, contentLength, err := storage.Get(token, filename) - if err != nil { - if storage.IsNotExist(err) { - http.Error(w, "File not found", 404) - return - } else { - log.Printf("%s", err.Error()) - http.Error(w, "Could not retrieve file.", 500) - return - } - } - - defer reader.Close() - - header := &tar.Header{ - Name: strings.Split(key, "/")[1], - Size: int64(contentLength), - } - - err = zw.WriteHeader(header) - if err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - - if _, err = io.Copy(zw, reader); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - } -} - -func tarHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - files := vars["files"] - - tarfilename := fmt.Sprintf("transfersh-%d.tar", uint16(time.Now().UnixNano())) - - w.Header().Set("Content-Type", "application/x-tar") - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", tarfilename)) - w.Header().Set("Connection", "close") - - zw := tar.NewWriter(w) - defer zw.Close() - - for _, key := range strings.Split(files, ",") { - token := strings.Split(key, "/")[0] - filename := strings.Split(key, "/")[1] - - reader, _, contentLength, err := storage.Get(token, filename) - if err != nil { - if storage.IsNotExist(err) { - http.Error(w, "File not found", 404) - return - } else { - log.Printf("%s", err.Error()) - http.Error(w, "Could not retrieve file.", 500) - return - } - } - - defer reader.Close() - - header := &tar.Header{ - Name: strings.Split(key, "/")[1], - Size: int64(contentLength), - } - - err = zw.WriteHeader(header) - if err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - - if _, err = io.Copy(zw, reader); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Internal server error.", 500) - return - } - } -} - -func getHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - token := vars["token"] - filename := vars["filename"] - - reader, contentType, contentLength, err := storage.Get(token, filename) - if err != nil { - if storage.IsNotExist(err) { - http.Error(w, "File not found", 404) - return - } else { - log.Printf("%s", err.Error()) - http.Error(w, "Could not retrieve file.", 500) - return - } - } - - defer reader.Close() - - w.Header().Set("Content-Type", contentType) - w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10)) - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) - w.Header().Set("Connection", "close") - - if _, err = io.Copy(w, reader); err != nil { - log.Printf("%s", err.Error()) - http.Error(w, "Error occurred copying to output stream", 500) - return - } -} - -func RedirectHandler(h http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/health.html" { - } else if ipAddrFromRemoteAddr(r.Host) == "127.0.0.1" { - } else if strings.HasSuffix(ipAddrFromRemoteAddr(r.Host), ".elasticbeanstalk.com") { - } else if ipAddrFromRemoteAddr(r.Host) == "jxm5d6emw5rknovg.onion" { - } else if ipAddrFromRemoteAddr(r.Host) == "transfer.sh" { - if r.Header.Get("X-Forwarded-Proto") != "https" && r.Method == "GET" { - http.Redirect(w, r, "https://transfer.sh"+r.RequestURI, 301) - return - } - } else if ipAddrFromRemoteAddr(r.Host) != "transfer.sh" { - http.Redirect(w, r, "https://transfer.sh"+r.RequestURI, 301) - return - } - - h.ServeHTTP(w, r) - } -} - -// Create a log handler for every request it receives. -func LoveHandler(h http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("x-made-with", "<3 by DutchCoders") - w.Header().Set("x-served-by", "Proudly served by DutchCoders") - w.Header().Set("Server", "Transfer.sh HTTP Server 1.0") - h.ServeHTTP(w, r) - } -} diff --git a/server/server.go.bak b/server/server.go.bak deleted file mode 100644 index eb7c087..0000000 --- a/server/server.go.bak +++ /dev/null @@ -1,239 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2014 DutchCoders [https://github.com/dutchcoders/] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - "flag" - "fmt" - "log" - "math/rand" - "mime" - "net/http" - "net/url" - "os" - "os/signal" - "runtime" - "syscall" - "time" - - "github.com/PuerkitoBio/ghost/handlers" - "github.com/gorilla/mux" - - _ "net/http/pprof" - - web "github.com/dutchcoders/transfer.sh-web" - assetfs "github.com/elazarl/go-bindata-assetfs" -) - -const SERVER_INFO = "transfer.sh" - -// parse request with maximum memory of _24Kilobits -const _24K = (1 << 20) * 24 - -var storage Storage - -type Server struct { - AWS_ACCESS_KEY string - AWS_SECRET_KEY string - BUCKET string - VIRUSTOTAL_KEY string - CLAMAV_DAEMON_HOST string "/tmp/clamd.socket" - Temp string - Path string -} - -func New() *Server { - s := &Server{} - s.AWS_ACCESS_KEY = os.Getenv("AWS_ACCESS_KEY_ID") - s.AWS_SECRET_KEY = os.Getenv("AWS_SECRET_KEY") - s.BUCKET = os.Getenv("BUCKET") - - s.VIRUSTOTAL_KEY = os.Getenv("VIRUSTOTAL_KEY") - - if os.Getenv("CLAMAV_DAEMON_HOST") != "" { - s.CLAMAV_DAEMON_HOST = os.Getenv("CLAMAV_DAEMON_HOST") - } - - s.Temp = os.TempDir() - - s.Path = "" // "../transfer.sh-web/dist/" - - return s -} - -func (s *Server) Run() { - rand.Seed(time.Now().UTC().UnixNano()) - - nCPU := runtime.NumCPU() - runtime.GOMAXPROCS(nCPU) - fmt.Println("Number of CPUs: ", nCPU) - - go func() { - fmt.Println("Profiled listening at: :6060") - http.ListenAndServe(":6060", nil) - }() - - r := mux.NewRouter() - - var fs http.FileSystem - - if config.Path != "" { - log.Println("Using static file path: ", config.Path) - - fs = http.Dir(config.Path) - html_templates, _ = html_templates.ParseGlob(config.Path + "*.html") - text_templates, _ = text_templates.ParseGlob(config.Path + "*.txt") - } else { - fs = &assetfs.AssetFS{ - Asset: web.Asset, - AssetDir: web.AssetDir, - AssetInfo: func(path string) (os.FileInfo, error) { - return os.Stat(path) - }, - Prefix: web.Prefix, - } - - for _, path := range web.AssetNames() { - bytes, err := web.Asset(path) - if err != nil { - log.Panicf("Unable to parse: path=%s, err=%s", path, err) - } - - html_templates.New(stripPrefix(path)).Parse(string(bytes)) - text_templates.New(stripPrefix(path)).Parse(string(bytes)) - } - } - - staticHandler := http.FileServer(fs) - - r.PathPrefix("/images/").Handler(staticHandler) - r.PathPrefix("/styles/").Handler(staticHandler) - r.PathPrefix("/scripts/").Handler(staticHandler) - r.PathPrefix("/fonts/").Handler(staticHandler) - r.PathPrefix("/ico/").Handler(staticHandler) - r.PathPrefix("/favicon.ico").Handler(staticHandler) - r.PathPrefix("/robots.txt").Handler(staticHandler) - - r.HandleFunc("/({files:.*}).zip", zipHandler).Methods("GET") - r.HandleFunc("/({files:.*}).tar", tarHandler).Methods("GET") - r.HandleFunc("/({files:.*}).tar.gz", tarGzHandler).Methods("GET") - r.HandleFunc("/download/{token}/{filename}", getHandler).Methods("GET") - - r.HandleFunc("/{token}/{filename}", previewHandler).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) (match bool) { - match = false - - // The file will show a preview page when opening the link in browser directly or - // from external link. If the referer url path and current path are the same it will be - // downloaded. - if !acceptsHtml(r.Header) { - return false - } - - match = (r.Referer() == "") - - u, err := url.Parse(r.Referer()) - if err != nil { - log.Fatal(err) - return - } - - match = match || (u.Path != r.URL.Path) - return - }).Methods("GET") - - r.HandleFunc("/{token}/{filename}", getHandler).Methods("GET") - r.HandleFunc("/get/{token}/{filename}", getHandler).Methods("GET") - r.HandleFunc("/{filename}/virustotal", virusTotalHandler).Methods("PUT") - r.HandleFunc("/{filename}/scan", scanHandler).Methods("PUT") - r.HandleFunc("/put/{filename}", putHandler).Methods("PUT") - r.HandleFunc("/upload/{filename}", putHandler).Methods("PUT") - r.HandleFunc("/{filename}", putHandler).Methods("PUT") - r.HandleFunc("/health.html", healthHandler).Methods("GET") - r.HandleFunc("/", postHandler).Methods("POST") - // r.HandleFunc("/{page}", viewHandler).Methods("GET") - r.HandleFunc("/", viewHandler).Methods("GET") - - r.NotFoundHandler = http.HandlerFunc(notFoundHandler) - - port := flag.String("port", "8080", "port number, default: 8080") - temp := flag.String("temp", config.Temp, "") - basedir := flag.String("basedir", "", "") - logpath := flag.String("log", "", "") - provider := flag.String("provider", "s3", "") - - flag.Parse() - - if *logpath != "" { - f, err := os.OpenFile(*logpath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - log.Fatalf("error opening file: %v", err) - } - - defer f.Close() - - log.SetOutput(f) - } - - 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.", err) - } - - mime.AddExtensionType(".md", "text/x-markdown") - - log.Printf("Transfer.sh server started. :\nlistening on port: %v\nusing temp folder: %s\nusing storage provider: %s", *port, config.Temp, *provider) - log.Printf("---------------------------") - - s := &http.Server{ - Addr: fmt.Sprintf(":%s", *port), - Handler: handlers.PanicHandler(LoveHandler(RedirectHandler(handlers.LogHandler(r, handlers.NewLogOptions(log.Printf, "_default_")))), nil), - } - - go func() { - s.ListenAndServe() - }() - - term := make(chan os.Signal, 1) - signal.Notify(term, os.Interrupt) - signal.Notify(term, syscall.SIGTERM) - - <-term - - log.Printf("Server stopped.") -} diff --git a/server/storage.go.bak b/server/storage.go.bak deleted file mode 100644 index 74885e9..0000000 --- a/server/storage.go.bak +++ /dev/null @@ -1,268 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "io" - "log" - "mime" - "os" - "path/filepath" - "strconv" - "sync" - - "github.com/goamz/goamz/s3" -) - -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 - IsNotExist(err error) bool -} - -type LocalStorage struct { - Storage - basedir string -} - -func NewLocalStorage(basedir string) (*LocalStorage, error) { - return &LocalStorage{basedir: basedir}, nil -} - -func (s *LocalStorage) Head(token string, filename string) (contentType string, contentLength uint64, err error) { - path := filepath.Join(s.basedir, token, filename) - - var fi os.FileInfo - if fi, err = os.Lstat(path); err != nil { - return - } - - contentLength = uint64(fi.Size()) - - contentType = mime.TypeByExtension(filepath.Ext(filename)) - - return -} - -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 - } - - var fi os.FileInfo - if fi, err = os.Lstat(path); err != nil { - return - } - - contentLength = uint64(fi.Size()) - - contentType = mime.TypeByExtension(filepath.Ext(filename)) - - return -} - -func (s *LocalStorage) IsNotExist(err error) bool { - return os.IsNotExist(err) -} - -func (s *LocalStorage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error { - var f io.WriteCloser - var err error - - path := filepath.Join(s.basedir, token) - - 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 - } - - defer f.Close() - - if _, err = io.Copy(f, reader); err != nil { - return err - } - - return nil -} - -type S3Storage struct { - Storage - bucket *s3.Bucket -} - -func NewS3Storage() (*S3Storage, error) { - bucket, err := getBucket() - if err != nil { - return nil, err - } - - return &S3Storage{bucket: bucket}, nil -} - -func (s *S3Storage) Head(token string, filename string) (contentType string, contentLength uint64, err error) { - key := fmt.Sprintf("%s/%s", token, filename) - - // content type , content length - response, err := s.bucket.Head(key, map[string][]string{}) - if err != nil { - return - } - - contentType = response.Header.Get("Content-Type") - - contentLength, err = strconv.ParseUint(response.Header.Get("Content-Length"), 10, 0) - if err != nil { - return - } - - return -} - -func (s *S3Storage) IsNotExist(err error) bool { - log.Printf("IsNotExist: %s, %#v", err.Error(), err) - - b := (err.Error() == "The specified key does not exist.") - b = b || (err.Error() == "Access Denied") - return b -} - -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) - if err != nil { - return - } - - contentType = response.Header.Get("Content-Type") - contentLength, err = strconv.ParseUint(response.Header.Get("Content-Length"), 10, 0) - if err != nil { - return - } - - reader = response.Body - return -} - -func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) (err error) { - key := fmt.Sprintf("%s/%s", token, filename) - - var ( - multi *s3.Multi - parts []s3.Part - ) - - if multi, err = s.bucket.InitMulti(key, contentType, s3.Private); err != nil { - log.Printf(err.Error()) - return - } - - // 20 mb parts - partsChan := make(chan interface{}) - // partsChan := make(chan s3.Part) - - go func() { - // maximize to 20 threads - sem := make(chan int, 20) - index := 1 - var wg sync.WaitGroup - - for { - // buffered in memory because goamz s3 multi needs seekable reader - var ( - buffer []byte = make([]byte, (1<<20)*10) - count int - err error - ) - - // Amazon expects parts of at least 5MB, except for the last one - if count, err = io.ReadAtLeast(reader, buffer, (1<<20)*5); err != nil && err != io.ErrUnexpectedEOF && err != io.EOF { - log.Printf(err.Error()) - return - } - - // always send minimal 1 part - if err == io.EOF && index > 1 { - log.Printf("Waiting for all parts to finish uploading.") - - // wait for all parts to be finished uploading - wg.Wait() - - // and close the channel - close(partsChan) - - return - } - - wg.Add(1) - - sem <- 1 - - // using goroutines because of retries when upload fails - go func(multi *s3.Multi, buffer []byte, index int) { - log.Printf("Uploading part %d %d", index, len(buffer)) - - defer func() { - log.Printf("Finished part %d %d", index, len(buffer)) - - wg.Done() - - <-sem - }() - - partReader := bytes.NewReader(buffer) - - var part s3.Part - - if part, err = multi.PutPart(index, partReader); err != nil { - log.Printf("Error while uploading part %d %d %s", index, len(buffer), err.Error()) - partsChan <- err - return - } - - log.Printf("Finished uploading part %d %d", index, len(buffer)) - - partsChan <- part - - }(multi, buffer[:count], index) - - index++ - } - }() - - // wait for all parts to be uploaded - for part := range partsChan { - switch part.(type) { - case s3.Part: - parts = append(parts, part.(s3.Part)) - case error: - // abort multi upload - log.Printf("Error during upload, aborting %s.", part.(error).Error()) - err = part.(error) - - multi.Abort() - return - } - - } - - log.Printf("Completing upload %d parts", len(parts)) - - if err = multi.Complete(parts); err != nil { - log.Printf("Error during completing upload %d parts %s", len(parts), err.Error()) - return - } - - log.Printf("Completed uploading %d", len(parts)) - - return -} diff --git a/server/utils.go.bak b/server/utils.go.bak deleted file mode 100644 index 8ce1d98..0000000 --- a/server/utils.go.bak +++ /dev/null @@ -1,276 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2014 DutchCoders [https://github.com/dutchcoders/] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - "math" - "net/http" - "net/mail" - "strconv" - "strings" - "time" - - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/s3" - "github.com/golang/gddo/httputil/header" -) - -func getBucket() (*s3.Bucket, error) { - auth, err := aws.GetAuth(config.AWS_ACCESS_KEY, config.AWS_SECRET_KEY, "", time.Time{}) - if err != nil { - return nil, err - } - - var EUWestWithoutHTTPS = aws.Region{ - "eu-west-1", - "https://ec2.eu-west-1.amazonaws.com", - "http://s3-eu-west-1.amazonaws.com", - "", - true, - true, - "https://sdb.eu-west-1.amazonaws.com", - "https://email.eu-west-1.amazonaws.com", - "https://sns.eu-west-1.amazonaws.com", - "https://sqs.eu-west-1.amazonaws.com", - "https://iam.amazonaws.com", - "https://elasticloadbalancing.eu-west-1.amazonaws.com", - "https://dynamodb.eu-west-1.amazonaws.com", - aws.ServiceInfo{"https://monitoring.eu-west-1.amazonaws.com", aws.V2Signature}, - "https://autoscaling.eu-west-1.amazonaws.com", - aws.ServiceInfo{"https://rds.eu-west-1.amazonaws.com", aws.V2Signature}, - "https://sts.amazonaws.com", - "https://cloudformation.eu-west-1.amazonaws.com", - "https://ecs.eu-west-1.amazonaws.com", - "https://streams.dynamodb.eu-west-1.amazonaws.com", - } - - conn := s3.New(auth, EUWestWithoutHTTPS) - b := conn.Bucket(config.BUCKET) - return b, nil -} - -func formatNumber(format string, s uint64) string { - - return RenderFloat(format, float64(s)) -} - -var renderFloatPrecisionMultipliers = [10]float64{ - 1, - 10, - 100, - 1000, - 10000, - 100000, - 1000000, - 10000000, - 100000000, - 1000000000, -} - -var renderFloatPrecisionRounders = [10]float64{ - 0.5, - 0.05, - 0.005, - 0.0005, - 0.00005, - 0.000005, - 0.0000005, - 0.00000005, - 0.000000005, - 0.0000000005, -} - -func RenderFloat(format string, n float64) string { - // Special cases: - // NaN = "NaN" - // +Inf = "+Infinity" - // -Inf = "-Infinity" - if math.IsNaN(n) { - return "NaN" - } - if n > math.MaxFloat64 { - return "Infinity" - } - if n < -math.MaxFloat64 { - return "-Infinity" - } - - // default format - precision := 2 - decimalStr := "." - thousandStr := "," - positiveStr := "" - negativeStr := "-" - - if len(format) > 0 { - // If there is an explicit format directive, - // then default values are these: - precision = 9 - thousandStr = "" - - // collect indices of meaningful formatting directives - formatDirectiveChars := []rune(format) - formatDirectiveIndices := make([]int, 0) - for i, char := range formatDirectiveChars { - if char != '#' && char != '0' { - formatDirectiveIndices = append(formatDirectiveIndices, i) - } - } - - if len(formatDirectiveIndices) > 0 { - // Directive at index 0: - // Must be a '+' - // Raise an error if not the case - // index: 0123456789 - // +0.000,000 - // +000,000.0 - // +0000.00 - // +0000 - if formatDirectiveIndices[0] == 0 { - if formatDirectiveChars[formatDirectiveIndices[0]] != '+' { - panic("RenderFloat(): invalid positive sign directive") - } - positiveStr = "+" - formatDirectiveIndices = formatDirectiveIndices[1:] - } - - // Two directives: - // First is thousands separator - // Raise an error if not followed by 3-digit - // 0123456789 - // 0.000,000 - // 000,000.00 - if len(formatDirectiveIndices) == 2 { - if (formatDirectiveIndices[1] - formatDirectiveIndices[0]) != 4 { - panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers") - } - thousandStr = string(formatDirectiveChars[formatDirectiveIndices[0]]) - formatDirectiveIndices = formatDirectiveIndices[1:] - } - - // One directive: - // Directive is decimal separator - // The number of digit-specifier following the separator indicates wanted precision - // 0123456789 - // 0.00 - // 000,0000 - if len(formatDirectiveIndices) == 1 { - decimalStr = string(formatDirectiveChars[formatDirectiveIndices[0]]) - precision = len(formatDirectiveChars) - formatDirectiveIndices[0] - 1 - } - } - } - - // generate sign part - var signStr string - if n >= 0.000000001 { - signStr = positiveStr - } else if n <= -0.000000001 { - signStr = negativeStr - n = -n - } else { - signStr = "" - n = 0.0 - } - - // split number into integer and fractional parts - intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision]) - - // generate integer part string - intStr := strconv.Itoa(int(intf)) - - // add thousand separator if required - if len(thousandStr) > 0 { - for i := len(intStr); i > 3; { - i -= 3 - intStr = intStr[:i] + thousandStr + intStr[i:] - } - } - - // no fractional part, we can leave now - if precision == 0 { - return signStr + intStr - } - - // generate fractional part - fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision])) - // may need padding - if len(fracStr) < precision { - fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr - } - - return signStr + intStr + decimalStr + fracStr -} - -func RenderInteger(format string, n int) string { - return RenderFloat(format, float64(n)) -} - -// Request.RemoteAddress contains port, which we want to remove i.e.: -// "[::1]:58292" => "[::1]" -func ipAddrFromRemoteAddr(s string) string { - idx := strings.LastIndex(s, ":") - if idx == -1 { - return s - } - return s[:idx] -} - -func getIpAddress(r *http.Request) string { - hdr := r.Header - hdrRealIp := hdr.Get("X-Real-Ip") - hdrForwardedFor := hdr.Get("X-Forwarded-For") - if hdrRealIp == "" && hdrForwardedFor == "" { - return ipAddrFromRemoteAddr(r.RemoteAddr) - } - if hdrForwardedFor != "" { - // X-Forwarded-For is potentially a list of addresses separated with "," - parts := strings.Split(hdrForwardedFor, ",") - for i, p := range parts { - parts[i] = strings.TrimSpace(p) - } - // TODO: should return first non-local address - return parts[0] - } - return hdrRealIp -} - -func encodeRFC2047(String string) string { - // use mail's rfc2047 to encode any string - addr := mail.Address{String, ""} - return strings.Trim(addr.String(), " <>") -} - -func acceptsHtml(hdr http.Header) bool { - actual := header.ParseAccept(hdr, "Accept") - - for _, s := range actual { - if s.Value == "text/html" { - return (true) - } - } - - return (false) -} diff --git a/server/virustotal.go.bak b/server/virustotal.go.bak deleted file mode 100644 index c8fc4df..0000000 --- a/server/virustotal.go.bak +++ /dev/null @@ -1,67 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2014 DutchCoders [https://github.com/dutchcoders/] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -package main - -import ( - "fmt" - _ "github.com/PuerkitoBio/ghost/handlers" - "github.com/dutchcoders/go-virustotal" - "github.com/gorilla/mux" - "github.com/kennygrant/sanitize" - "io" - "log" - "net/http" - "path/filepath" -) - -func virusTotalHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - filename := sanitize.Path(filepath.Base(vars["filename"])) - - contentLength := r.ContentLength - contentType := r.Header.Get("Content-Type") - - log.Printf("Submitting to VirusTotal: %s %d %s", filename, contentLength, contentType) - - apikey := config.VIRUSTOTAL_KEY - - vt, err := virustotal.NewVirusTotal(apikey) - if err != nil { - http.Error(w, err.Error(), 500) - } - - var reader io.Reader - - reader = r.Body - - result, err := vt.Scan(filename, reader) - if err != nil { - http.Error(w, err.Error(), 500) - } - - log.Println(result) - w.Write([]byte(fmt.Sprintf("%v\n", result.Permalink))) -}