diff --git a/go.mod b/go.mod index 444d657..5b9a2b4 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,28 @@ module github.com/Luzifer/share -go 1.20 +go 1.22.1 require ( - github.com/Luzifer/rconfig/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.44.275 - github.com/cheggaaa/pb v1.0.29 + github.com/Luzifer/rconfig/v2 v2.5.0 + github.com/aws/aws-sdk-go v1.51.1 + github.com/cheggaaa/pb/v3 v3.1.5 github.com/gofrs/uuid v4.4.0+incompatible - github.com/gosimple/slug v1.13.1 + github.com/gosimple/slug v1.14.0 github.com/pkg/errors v0.9.1 - github.com/rivo/uniseg v0.4.4 // indirect github.com/sirupsen/logrus v1.9.3 ) require ( + github.com/VividCortex/ewma v1.2.0 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect gopkg.in/validator.v2 v2.0.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c44f856..92f1ef6 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,20 @@ -github.com/Luzifer/rconfig/v2 v2.4.0 h1:MAdymTlExAZ8mx5VG8xOFAtFQSpWBipKYQHPOmYTn9o= -github.com/Luzifer/rconfig/v2 v2.4.0/go.mod h1:hWF3ZVSusbYlg5bEvCwalEyUSY+0JPJWUiIu7rBmav8= -github.com/aws/aws-sdk-go v1.44.275 h1:VqRULgqrigvQLll4e4hXuc568EQAtZQ6jmBzLlQHzSI= -github.com/aws/aws-sdk-go v1.44.275/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= -github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= +github.com/Luzifer/rconfig/v2 v2.5.0 h1:zx5lfQbNX3za4VegID97IeY+M+BmfgHxWJTYA94sxok= +github.com/Luzifer/rconfig/v2 v2.5.0/go.mod h1:eGWUPQeCPv/Pr/p0hjmwFgI20uqvwi/Szen69hUzGzU= +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/aws/aws-sdk-go v1.51.1 h1:AFvTihcDPanvptoKS09a4yYmNtPm3+pXlk6uYHmZiFk= +github.com/aws/aws-sdk-go v1.51.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= +github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= -github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= +github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -20,69 +22,45 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/validator.v2 v2.0.1 h1:xF0KWyGWXm/LM2G1TrEjqOu4pa6coO9AlWSf3msVfDY= gopkg.in/validator.v2 v2.0.1/go.mod h1:lIUZBlB3Im4s/eYp39Ry/wkR02yOPhZ9IwIRBjuPuG8= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/http.go b/http.go index 88bafee..abc4383 100644 --- a/http.go +++ b/http.go @@ -1,32 +1,51 @@ package main import ( + "fmt" "net/http" + "time" - log "github.com/sirupsen/logrus" + "github.com/gofrs/uuid" + "github.com/sirupsen/logrus" ) -func doListen() error { +func doListen() (err error) { http.HandleFunc("/post", simpleFilePost) - return http.ListenAndServe(cfg.Listen, nil) + + server := &http.Server{ + Addr: cfg.Listen, + Handler: http.DefaultServeMux, + ReadHeaderTimeout: time.Second, + } + + if err = server.ListenAndServe(); err != nil { + return fmt.Errorf("listening for HTTP traffic: %w", err) + } + + return nil } -func simpleFilePost(res http.ResponseWriter, r *http.Request) { +func simpleFilePost(w http.ResponseWriter, r *http.Request) { + var ( + reqUUID = uuid.Must(uuid.NewV4()).String() + logger = logrus.WithField("req-id", reqUUID) + errStr = fmt.Sprintf("something went wrong: %s", reqUUID) + ) + f, fh, err := r.FormFile("file") if err != nil { - log.WithError(err).Error("Unable to retrieve file from request") - http.Error(res, "Could not retrieve your file", http.StatusBadRequest) + logger.WithError(err).Error("retrieving file from request") + http.Error(w, errStr, http.StatusBadRequest) return } url, err := executeUpload(fh.Filename, f, true, "", false) if err != nil { - log.WithError(err).Error("Uploading file from HTTP request failed") - http.Error(res, "Failed to upload file. For details see the log.", http.StatusInternalServerError) + logger.WithError(err).Error("uploading file from HTTP request") + http.Error(w, errStr, http.StatusInternalServerError) return } - res.Header().Set("Content-Type", "text/plain") - res.WriteHeader(http.StatusOK) - res.Write([]byte(url)) + w.Header().Set("Content-Type", "text/plain") + http.Error(w, url, http.StatusOK) } diff --git a/main.go b/main.go index 6f37759..9f94dbe 100644 --- a/main.go +++ b/main.go @@ -3,14 +3,13 @@ package main import ( "bytes" "embed" - _ "embed" "fmt" "io" "os" "strings" "github.com/pkg/errors" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" "github.com/Luzifer/rconfig/v2" ) @@ -18,7 +17,6 @@ import ( var ( cfg = struct { BaseURL string `flag:"base-url" default:"" description:"URL to prepend before filename"` - BasePath string `flag:"base-path" default:"" description:"DEPRECATED: Path to upload the file to"` Bootstrap bool `flag:"bootstrap" default:"false" description:"Upload frontend files into bucket"` Bucket string `flag:"bucket" default:"" description:"S3 bucket to upload files to" validate:"nonzero"` ContentType string `flag:"content-type,c" default:"" description:"Force content-type to be set to this value"` @@ -36,54 +34,56 @@ var ( version = "dev" ) -func initApp() { +func initApp() (err error) { rconfig.AutoEnv(true) rconfig.SetVariableDefaults(map[string]string{ "file_template": `file/{{ printf "%.6s" .Hash }}/{{ .SafeFileName }}`, }) - if err := rconfig.ParseAndValidate(&cfg); err != nil { - log.Fatalf("Unable to parse commandline options: %s", err) + if err = rconfig.ParseAndValidate(&cfg); err != nil { + return fmt.Errorf("parsing CLI options: %w", err) } - if cfg.VersionAndExit { - fmt.Printf("share %s\n", version) - os.Exit(0) + l, err := logrus.ParseLevel(cfg.LogLevel) + if err != nil { + return fmt.Errorf("parsing log-level: %w", err) } + logrus.SetLevel(l) - if l, err := log.ParseLevel(cfg.LogLevel); err != nil { - log.WithError(err).Fatal("Unable to parse log level") - } else { - log.SetLevel(l) - } - - if cfg.BasePath != "" { - cfg.FileTemplate = strings.Join([]string{strings.TrimRight(cfg.BasePath, "/"), `{{ .SafeFileName }}`}, "/") - log.WithField("file-template", cfg.FileTemplate).Warn("Using deprecated base-path parameter! Using update file-template...") - } + return nil } func main() { - initApp() + var err error + if err = initApp(); err != nil { + logrus.WithError(err).Fatal("initializing app") + } + + if cfg.VersionAndExit { + fmt.Printf("share %s\n", version) //nolint:forbidigo // Fine for version info + os.Exit(0) + } switch { - case cfg.Bootstrap: if err := doBootstrap(); err != nil { - log.WithError(err).Fatal("Bootstrap failed") + logrus.WithError(err).Fatal("bootstrapping resources") } - log.Info("Bucket bootstrap finished: Frontend uploaded") + logrus.Info("Bucket bootstrap finished: Frontend uploaded") case cfg.Listen != "": + logrus.WithFields(logrus.Fields{ + "addr": cfg.Listen, + "version": version, + }).Info("share HTTP server started") if err := doListen(); err != nil { - log.WithError(err).Fatal("HTTP server ended unclean") + logrus.WithError(err).Fatal("running HTTP server") } default: if err := doCLIUpload(); err != nil { - log.WithError(err).Fatal("Upload failed") + logrus.WithError(err).Fatal("uploading file") } - } } @@ -93,7 +93,7 @@ func doCLIUpload() error { } if cfg.BaseURL == "" { - log.Warn("No BaseURL configured, output will be no complete URL") + logrus.Warn("No BaseURL configured, output will be no complete URL") } var inFile io.ReadSeeker @@ -112,16 +112,16 @@ func doCLIUpload() error { // Stdin is not seekable, so we need to buffer it buf := new(bytes.Buffer) if _, err := io.Copy(buf, os.Stdin); err != nil { - log.WithError(err).Fatal("Could not read stdin") + logrus.WithError(err).Fatal("reading stdin") } inFile = bytes.NewReader(buf.Bytes()) } else { - inFileHandle, err := os.Open(inFileName) + inFileHandle, err := os.Open(inFileName) //#nosec:G304 // Inentional read of arbitrary file if err != nil { return errors.Wrap(err, "opening source file") } - defer inFileHandle.Close() + defer inFileHandle.Close() //nolint:errcheck // Irrelevant, file is closed by process exit inFile = inFileHandle } @@ -130,7 +130,7 @@ func doCLIUpload() error { return errors.Wrap(err, "uploading file") } - fmt.Println(url) + fmt.Println(url) //nolint:forbidigo // Intended as programmatic payload return nil } diff --git a/mime.go b/mime.go index ce9dc0e..d1584eb 100644 --- a/mime.go +++ b/mime.go @@ -1,10 +1,9 @@ package main import ( + "fmt" "mime" "strings" - - "github.com/pkg/errors" ) type mimeDB map[string]string @@ -23,7 +22,7 @@ func (m mimeDB) ExtensionsByType(t string) (string, error) { exts, err := mime.ExtensionsByType(t) if err != nil { - return "", err + return "", fmt.Errorf("getting mime extension: %w", err) } for _, ext := range exts { @@ -33,5 +32,5 @@ func (m mimeDB) ExtensionsByType(t string) (string, error) { return ext, nil } - return "", errors.New("no extension found") + return "", fmt.Errorf("no extension found") } diff --git a/progress.go b/progress.go index e4837a9..9824311 100644 --- a/progress.go +++ b/progress.go @@ -1,54 +1,54 @@ package main import ( + "errors" + "fmt" "io" - "io/ioutil" ) type progressSeeker struct { Size int64 Progress int64 - o io.ReadSeeker + next io.ReadSeeker } -func newProgressSeeker(o io.ReadSeeker) (*progressSeeker, error) { - if _, err := o.Seek(0, io.SeekStart); err != nil { - return nil, err - } - - data, err := ioutil.ReadAll(o) +func newProgressSeeker(next io.ReadSeeker) (*progressSeeker, error) { + lastByte, err := next.Seek(0, io.SeekEnd) if err != nil { - return nil, err + return nil, fmt.Errorf("seeking end of reader: %w", err) } - if _, err := o.Seek(0, io.SeekStart); err != nil { - return nil, err + if _, err := next.Seek(0, io.SeekStart); err != nil { + return nil, fmt.Errorf("seeking start of reader: %w", err) } return &progressSeeker{ - o: o, - Size: int64(len(data)), + next: next, + Size: lastByte, }, nil } func (p *progressSeeker) Read(o []byte) (n int, err error) { - i, err := p.o.Read(o) + i, err := p.next.Read(o) + if err != nil { + if errors.Is(err, io.EOF) { + return i, io.EOF + } + return i, fmt.Errorf("reading next reader: %w", err) + } p.Progress += int64(i) - return i, err + return i, nil } func (p *progressSeeker) Seek(offset int64, whence int) (int64, error) { - switch whence { - case io.SeekStart: - p.Progress = offset - case io.SeekCurrent: - p.Progress = p.Progress + offset - case io.SeekEnd: - p.Progress = p.Size + offset + pos, err := p.next.Seek(offset, whence) + if err != nil { + return pos, fmt.Errorf("seeking next reader: %w", err) } - return p.o.Seek(offset, whence) + p.Progress = pos + return pos, nil } diff --git a/upload.go b/upload.go index 6b80af5..fbac7ec 100644 --- a/upload.go +++ b/upload.go @@ -3,13 +3,11 @@ package main import ( "bytes" "compress/gzip" - "crypto/sha1" + "crypto/sha256" "fmt" "html/template" "io" - "io/ioutil" "mime" - "os" "path" "strings" "time" @@ -17,13 +15,16 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" - "github.com/cheggaaa/pb" + "github.com/cheggaaa/pb/v3" "github.com/gofrs/uuid" "github.com/gosimple/slug" "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) +const barUpdateInterval = 100 * time.Millisecond + +//revive:disable-next-line:flag-parameter // Fine in this case func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedFilename bool, overrideMimeType string, forceGzip bool) (string, error) { var ( upFile = inFileName @@ -78,15 +79,16 @@ func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedF } if cfg.Progress { - bar := pb.New64(ps.Size).Prefix(inFileName).SetUnits(pb.U_BYTES) - bar.Output = os.Stderr + bar := pb.New64(ps.Size) + bar.Set(pb.Bytes, true) + bar.Set("prefix", inFileName) bar.Start() barUpdate := true go func() { for barUpdate { - bar.Set64(ps.Progress) - <-time.After(100 * time.Millisecond) + bar.SetCurrent(ps.Progress) + time.Sleep(barUpdateInterval) } }() @@ -96,14 +98,14 @@ func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedF }() } - if _, err := svc.PutObject(&s3.PutObjectInput{ + if _, err = svc.PutObject(&s3.PutObjectInput{ Body: ps, Bucket: aws.String(cfg.Bucket), ContentEncoding: contentEncoding, ContentType: aws.String(mimeType), Key: aws.String(upFile), }); err != nil { - return "", err + return "", fmt.Errorf("putting object to S3: %w", err) } return fmt.Sprintf("%s%s", cfg.BaseURL, upFile), nil @@ -129,26 +131,29 @@ func calculateUploadFilename(inFile string, inFileHandle io.ReadSeeker) (string, }) } -func hashFile(inFileHandle io.ReadSeeker) (string, error) { - if _, err := inFileHandle.Seek(0, io.SeekStart); err != nil { - return "", err +func hashFile(inFileHandle io.ReadSeeker) (hexHash string, err error) { + if _, err = inFileHandle.Seek(0, io.SeekStart); err != nil { + return "", fmt.Errorf("resetting reader: %w", err) } - data, err := ioutil.ReadAll(inFileHandle) - if err != nil { - return "", err + shaHash := sha256.New() + if _, err = io.Copy(shaHash, inFileHandle); err != nil { + return "", fmt.Errorf("reading data into hash: %w", err) } - sum1 := sha1.Sum(data) - return fmt.Sprintf("%x", sum1), nil + + return fmt.Sprintf("%x", shaHash.Sum(nil)), nil } func executeTemplate(tplStr string, vars map[string]interface{}) (string, error) { tpl, err := template.New("filename").Parse(tplStr) if err != nil { - return "", err + return "", fmt.Errorf("parsing filename template: %w", err) } buf := new(bytes.Buffer) - err = tpl.Execute(buf, vars) - return buf.String(), err + if err = tpl.Execute(buf, vars); err != nil { + return "", fmt.Errorf("executing filename template: %w", err) + } + + return buf.String(), nil }