Compare commits

...

15 Commits

Author SHA1 Message Date
Andrea Spacca
3ef3f5c4ef fix storj 2023-03-05 09:47:45 +09:00
Andrea Spacca
7d7e13174b do not write to file by default 2023-03-03 10:03:41 +09:00
Andrea Spacca
41bc6c964b linting 2023-03-02 01:04:01 +09:00
Andrea Spacca
11e64513a2 cr fixes, replace deprecated ioutil.NopCloser 2023-03-02 00:59:51 +09:00
Andrea Spacca
3b3d714def gofmt 2023-03-02 00:56:21 +09:00
Andrea Spacca
7b5f2b4d50 Merge branch 'main' into lint-accept-range 2023-03-02 00:55:07 +09:00
dependabot[bot]
c452bd4719 Bump golang.org/x/net from 0.0.0-20220513224357-95641704303c to 0.7.0 (#534)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.0.0-20220513224357-95641704303c to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/commits/v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-01 16:39:47 +01:00
Andrea Spacca
ace8b94be1 go mod tidy 2023-03-02 00:31:40 +09:00
Andrea Spacca
41456c7f2d Merge branch 'main' into lint-accept-range 2023-03-02 00:30:04 +09:00
dependabot[bot]
a4475513bc Bump golang.org/x/crypto from 0.0.0-20220131195533-30dcbda58838 to 0.1.0 (#533)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20220131195533-30dcbda58838 to 0.1.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/commits/v0.1.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-01 16:07:10 +01:00
Andrea Spacca
c4997097ba bump deps 2023-03-02 00:06:40 +09:00
Andrea Spacca
80a8a47876 lint 2023-03-01 23:17:59 +09:00
Andrea Spacca
9f86af9f68 Merge branch 'main' into main 2023-03-01 22:06:53 +09:00
Andrea Spacca
9f1fe62e05 min go version 1.18, include tip for test (#532)
* min go version 1.18, include tip for test

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint

* lint
2023-03-01 21:51:24 +09:00
Vladislav Grubov
1ac8b1ce26 Merge pull request #1 from dutchcoders/accept-range
Accept range
2023-02-12 12:43:30 +03:00
7 changed files with 224 additions and 1307 deletions

View File

@@ -13,16 +13,27 @@ jobs:
fail-fast: false
matrix:
go_version:
- 1.15.x
- 1.16.x
- 1.17.x
- 1.18.X
- '1.18'
- '1.19'
- '1.20'
- tip
name: Test with ${{ matrix.go_version }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
- name: Install Go ${{ matrix.go_version }}
if: ${{ matrix.go_version != 'tip' }}
uses: actions/setup-go@master
with:
go-version: ${{ matrix.go_version }}
check-latest: true
- name: Install Go ${{ matrix.go_version }}
if: ${{ matrix.go_version == 'tip' }}
run: |
curl -sL https://storage.googleapis.com/go-build-snap/go/linux-amd64/$(git ls-remote https://github.com/golang/go.git HEAD | awk '{print $1;}').tar.gz -o gotip.tar.gz
ls -lah gotip.tar.gz
mkdir -p ~/sdk/gotip
tar -C ~/sdk/gotip -xzf gotip.tar.gz
echo "PATH=$HOME/go/bin:$HOME/sdk/gotip/bin/:$PATH" >> $GITHUB_ENV
- name: Vet and test
run: |
go version
@@ -33,9 +44,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
- uses: actions/setup-go@master
with:
go-version: 1.18
go-version: '1.20'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:

88
go.mod
View File

@@ -1,40 +1,72 @@
module github.com/dutchcoders/transfer.sh
go 1.15
go 1.18
require (
github.com/PuerkitoBio/ghost v0.0.0-20160324114900-206e6e460e14
github.com/VojtechVitek/ratelimit v0.0.0-20160722140851-dc172bc0f6d2
github.com/aws/aws-sdk-go v1.44.211
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/dutchcoders/go-virustotal v0.0.0-20140923143438-24cc8e6fa329
github.com/dutchcoders/transfer.sh-web v0.0.0-20221119114740-ca3a2621d2a6
github.com/elazarl/go-bindata-assetfs v1.0.1
github.com/fatih/color v1.14.1
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/microcosm-cc/bluemonday v1.0.22
github.com/russross/blackfriday/v2 v2.1.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
github.com/urfave/cli v1.22.12
golang.org/x/crypto v0.6.0
golang.org/x/net v0.7.0
golang.org/x/oauth2 v0.5.0
google.golang.org/api v0.111.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
storj.io/common v0.0.0-20230301105927-7f966760c100
storj.io/uplink v1.10.0
)
require (
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/PuerkitoBio/ghost v0.0.0-20160324114900-206e6e460e14
github.com/VojtechVitek/ratelimit v0.0.0-20160722140851-dc172bc0f6d2
github.com/aws/aws-sdk-go v1.37.14
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/dutchcoders/go-virustotal v0.0.0-20140923143438-24cc8e6fa329
github.com/dutchcoders/transfer.sh-web v0.0.0-20220824020025-7240e75c3bb8
github.com/elazarl/go-bindata-assetfs v1.0.1
github.com/fatih/color v1.10.0
github.com/garyburd/redigo v1.6.2 // indirect
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
github.com/aymerick/douceur v0.2.0 // indirect
github.com/calebcase/tmpfile v1.0.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/garyburd/redigo v1.6.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.2 // indirect
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/microcosm-cc/bluemonday v1.0.16
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jtolio/eventkit v0.0.0-20230301123942-0cee1388f16f // indirect
github.com/jtolio/noiseconn v0.0.0-20230227223919-bddcd1327059 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/russross/blackfriday/v2 v2.1.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
github.com/urfave/cli v1.22.5
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838
golang.org/x/net v0.6.0 // indirect
golang.org/x/oauth2 v0.5.0
google.golang.org/api v0.109.0
google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/spacemonkeygo/monkit/v3 v3.0.19 // indirect
github.com/vivint/infectious v0.0.0-20200605153912-25a574ae18a3 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
github.com/zeebo/errs v1.3.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
storj.io/common v0.0.0-20220405183405-ffdc3ab808c6
storj.io/uplink v1.8.2
storj.io/drpc v0.0.33-0.20230204035225-c9649dee8f2a // indirect
storj.io/picobuf v0.0.1 // indirect
)

1283
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,6 @@ import (
"html"
htmlTemplate "html/template"
"io"
"io/ioutil"
"mime"
"net"
"net/http"
@@ -58,8 +57,8 @@ import (
web "github.com/dutchcoders/transfer.sh-web"
"github.com/gorilla/mux"
"github.com/microcosm-cc/bluemonday"
"github.com/russross/blackfriday/v2"
"github.com/skip2/go-qrcode"
blackfriday "github.com/russross/blackfriday/v2"
qrcode "github.com/skip2/go-qrcode"
"golang.org/x/net/idna"
)
@@ -318,7 +317,7 @@ func (s *Server) postHandler(w http.ResponseWriter, r *http.Request) {
return
}
file, err := ioutil.TempFile(s.tempPath, "transfer-")
file, err := os.CreateTemp(s.tempPath, "transfer-")
defer s.cleanTmpFile(file)
if err != nil {
@@ -463,34 +462,53 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
defer storage.CloseCheck(r.Body)
file, err := ioutil.TempFile(s.tempPath, "transfer-")
defer s.cleanTmpFile(file)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
reader := r.Body
// queue file to disk, because s3 needs content length
// and clamav prescan scans a file
n, err := io.Copy(file, r.Body)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
if contentLength < 1 || s.performClamavPrescan {
file, err := os.CreateTemp(s.tempPath, "transfer-")
defer s.cleanTmpFile(file)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
return
}
// queue file to disk, because s3 needs content length
// and clamav prescan scans a file
n, err := io.Copy(file, r.Body)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
_, err = file.Seek(0, io.SeekStart)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, "Cannot reset cache file", http.StatusInternalServerError)
return
}
return
}
_, err = file.Seek(0, io.SeekStart)
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, "Cannot reset cache file", http.StatusInternalServerError)
return
}
if contentLength < 1 {
contentLength = n
if s.performClamavPrescan {
status, err := s.performScan(file.Name())
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, "Could not perform prescan", http.StatusInternalServerError)
return
}
if status != clamavScanStatusOK {
s.logger.Printf("prescan positive: %s", status)
http.Error(w, "Clamav prescan found a virus", http.StatusPreconditionFailed)
return
}
}
reader = file
}
if s.maxUploadSize > 0 && contentLength > s.maxUploadSize {
@@ -505,21 +523,6 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
return
}
if s.performClamavPrescan {
status, err := s.performScan(file.Name())
if err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, "Could not perform prescan", http.StatusInternalServerError)
return
}
if status != clamavScanStatusOK {
s.logger.Printf("prescan positive: %s", status)
http.Error(w, "Clamav prescan found a virus", http.StatusPreconditionFailed)
return
}
}
contentType := mime.TypeByExtension(filepath.Ext(vars["filename"]))
token := token(s.randomTokenLength)
@@ -543,7 +546,7 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
s.logger.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType)
if err = s.storage.Put(r.Context(), token, filename, file, contentType, uint64(contentLength)); err != nil {
if err := s.storage.Put(r.Context(), token, filename, reader, contentType, uint64(contentLength)); err != nil {
s.logger.Printf("Error putting new file: %s", err.Error())
http.Error(w, "Could not save file", http.StatusInternalServerError)
return
@@ -1031,8 +1034,6 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) {
reader, contentLength, err := s.storage.Get(r.Context(), token, filename, rng)
defer storage.CloseCheck(reader)
rdr := io.Reader(reader)
if s.storage.IsNotExist(err) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
@@ -1047,7 +1048,7 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Accept-Ranges", "bytes")
w.Header().Set("Content-Range", cr)
if rng.Limit > 0 {
rdr = io.LimitReader(reader, int64(rng.Limit))
reader = io.NopCloser(io.LimitReader(reader, int64(rng.Limit)))
}
}
}
@@ -1057,8 +1058,6 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) {
if action == "inline" {
disposition = "inline"
/*
metadata.ContentType is unable to determine the type of the content,
metadata.ContentType is unable to determine the type of the content,
metadata.ContentType is unable to determine the type of the content,
So add text/plain in this case to fix XSS related issues/
*/
@@ -1084,10 +1083,10 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) {
}
if disposition == "inline" && canContainsXSS(contentType) {
reader = ioutil.NopCloser(bluemonday.UGCPolicy().SanitizeReader(reader))
reader = io.NopCloser(bluemonday.UGCPolicy().SanitizeReader(reader))
}
if _, err = io.Copy(w, rdr); err != nil {
if _, err = io.Copy(w, reader); err != nil {
s.logger.Printf("%s", err.Error())
http.Error(w, "Error occurred copying to output stream", http.StatusInternalServerError)
return

View File

@@ -21,13 +21,13 @@ import (
"github.com/tomasen/realip"
)
//IPFilterOptions for ipFilter. Allowed takes precedence over Blocked.
//IPs can be IPv4 or IPv6 and can optionally contain subnet
//masks (/24). Note however, determining if a given IP is
//included in a subnet requires a linear scan so is less performant
//than looking up single IPs.
// IPFilterOptions for ipFilter. Allowed takes precedence over Blocked.
// IPs can be IPv4 or IPv6 and can optionally contain subnet
// masks (/24). Note however, determining if a given IP is
// included in a subnet requires a linear scan so is less performant
// than looking up single IPs.
//
//This could be improved with some algorithmic magic.
// This could be improved with some algorithmic magic.
type IPFilterOptions struct {
//explicity allowed IPs
AllowedIPs []string
@@ -127,19 +127,19 @@ func (f *ipFilter) ToggleIP(str string, allowed bool) bool {
return false
}
//ToggleDefault alters the default setting
// ToggleDefault alters the default setting
func (f *ipFilter) ToggleDefault(allowed bool) {
f.mut.Lock()
f.defaultAllowed = allowed
f.mut.Unlock()
}
//Allowed returns if a given IP can pass through the filter
// Allowed returns if a given IP can pass through the filter
func (f *ipFilter) Allowed(ipstr string) bool {
return f.NetAllowed(net.ParseIP(ipstr))
}
//NetAllowed returns if a given net.IP can pass through the filter
// NetAllowed returns if a given net.IP can pass through the filter
func (f *ipFilter) NetAllowed(ip net.IP) bool {
//invalid ip
if ip == nil {
@@ -172,23 +172,23 @@ func (f *ipFilter) NetAllowed(ip net.IP) bool {
return f.defaultAllowed
}
//Blocked returns if a given IP can NOT pass through the filter
// Blocked returns if a given IP can NOT pass through the filter
func (f *ipFilter) Blocked(ip string) bool {
return !f.Allowed(ip)
}
//NetBlocked returns if a given net.IP can NOT pass through the filter
// NetBlocked returns if a given net.IP can NOT pass through the filter
func (f *ipFilter) NetBlocked(ip net.IP) bool {
return !f.NetAllowed(ip)
}
//Wrap the provided handler with simple IP blocking middleware
//using this IP filter and its configuration
// Wrap the provided handler with simple IP blocking middleware
// using this IP filter and its configuration
func (f *ipFilter) Wrap(next http.Handler) http.Handler {
return &ipFilterMiddleware{ipFilter: f, next: next}
}
//WrapIPFilter is equivalent to newIPFilter(opts) then Wrap(next)
// WrapIPFilter is equivalent to newIPFilter(opts) then Wrap(next)
func WrapIPFilter(next http.Handler, opts IPFilterOptions) http.Handler {
return newIPFilter(opts).Wrap(next)
}

View File

@@ -466,8 +466,6 @@ func (s *Server) Run() {
r.HandleFunc("/{action:(?:download|get|inline)}/{token}/{filename}", s.headHandler).Methods("HEAD")
r.HandleFunc("/{token}/{filename}", s.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.

View File

@@ -83,15 +83,18 @@ func (s *StorjStorage) Get(ctx context.Context, token string, filename string, r
s.logger.Printf("Getting file %s from Storj Bucket", filename)
options := uplink.DownloadOptions{}
var options *uplink.DownloadOptions
if rng != nil {
options = new(uplink.DownloadOptions)
options.Offset = int64(rng.Start)
if rng.Limit > 0 {
options.Length = int64(rng.Limit)
} else {
options.Length = -1
}
}
download, err := s.project.DownloadObject(fpath.WithTempData(ctx, "", true), s.bucket.Name, key, &options)
download, err := s.project.DownloadObject(fpath.WithTempData(ctx, "", true), s.bucket.Name, key, options)
if err != nil {
return nil, 0, err
}