1
0
mirror of https://github.com/IceWhaleTech/CasaOS.git synced 2025-07-03 23:30:39 +02:00

feat: migrate gin to echo (#1854)

This commit is contained in:
Ns2Kracy
2024-06-04 14:14:55 +08:00
committed by GitHub
parent 0883f5f3aa
commit 8f7c99779f
18 changed files with 475 additions and 545 deletions

15
go.mod
View File

@ -11,8 +11,6 @@ require (
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/dsoprea/go-exif/v3 v3.0.1 github.com/dsoprea/go-exif/v3 v3.0.1
github.com/getkin/kin-openapi v0.117.0 github.com/getkin/kin-openapi v0.117.0
github.com/gin-contrib/gzip v0.0.6
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.8.0 github.com/glebarez/sqlite v1.8.0
github.com/go-ini/ini v1.67.0 github.com/go-ini/ini v1.67.0
github.com/go-resty/resty/v2 v2.7.0 github.com/go-resty/resty/v2 v2.7.0
@ -41,10 +39,10 @@ require (
github.com/tidwall/gjson v1.14.4 github.com/tidwall/gjson v1.14.4
go.uber.org/goleak v1.2.1 go.uber.org/goleak v1.2.1
go.uber.org/zap v1.24.0 go.uber.org/zap v1.24.0
golang.org/x/crypto v0.14.0 golang.org/x/crypto v0.22.0
golang.org/x/oauth2 v0.7.0 golang.org/x/oauth2 v0.7.0
golang.org/x/sync v0.3.0 golang.org/x/sync v0.3.0
golang.org/x/sys v0.14.0 golang.org/x/sys v0.19.0
gorm.io/gorm v1.25.0 gorm.io/gorm v1.25.0
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
) )
@ -64,6 +62,7 @@ require (
github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/geoffgarside/ber v1.1.0 // indirect github.com/geoffgarside/ber v1.1.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/glebarez/go-sqlite v1.21.1 // indirect github.com/glebarez/go-sqlite v1.21.1 // indirect
github.com/go-errors/errors v1.4.2 // indirect github.com/go-errors/errors v1.4.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
@ -91,7 +90,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
@ -124,9 +123,9 @@ require (
golang.org/x/arch v0.3.0 // indirect golang.org/x/arch v0.3.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/image v0.6.0 // indirect golang.org/x/image v0.6.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect
golang.org/x/text v0.13.0 // indirect golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect

51
go.sum
View File

@ -59,11 +59,8 @@ github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc= github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDcUFE8A= github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDcUFE8A=
github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY= github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY=
@ -85,22 +82,17 @@ github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaL
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@ -182,7 +174,6 @@ github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -191,9 +182,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
@ -205,10 +195,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ= github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ=
github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ= github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 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-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
@ -232,7 +220,6 @@ github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9l
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
@ -253,8 +240,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
@ -270,7 +255,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -302,7 +286,6 @@ github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
@ -325,10 +308,9 @@ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@ -351,8 +333,8 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
@ -373,10 +355,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -387,12 +365,12 @@ golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -400,10 +378,10 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@ -418,14 +396,12 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@ -435,7 +411,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,11 @@
package utils
import "github.com/labstack/echo/v4"
func DefaultPostForm(ctx echo.Context, key, defaultValue string) string {
value := ctx.Request().Form.Get(key)
if value == "" {
return defaultValue
}
return value
}

View File

@ -0,0 +1,11 @@
package utils
import "github.com/labstack/echo/v4"
func DefaultQuery(ctx echo.Context, key string, defaultValue string) string {
if value := ctx.QueryParam(key); value != "" {
return value
}
return defaultValue
}

View File

@ -2,50 +2,68 @@ package route
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"os" "net/http"
"strconv"
"github.com/IceWhaleTech/CasaOS-Common/external" "github.com/IceWhaleTech/CasaOS-Common/external"
"github.com/IceWhaleTech/CasaOS-Common/middleware"
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt" "github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
"github.com/IceWhaleTech/CasaOS/common" "github.com/IceWhaleTech/CasaOS/common"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
v1 "github.com/IceWhaleTech/CasaOS/route/v1" v1 "github.com/IceWhaleTech/CasaOS/route/v1"
"github.com/labstack/echo/v4"
"github.com/gin-contrib/gzip" echo_middleware "github.com/labstack/echo/v4/middleware"
"github.com/gin-gonic/gin"
) )
func InitV1Router() *gin.Engine { func InitV1Router() http.Handler {
ginMode := gin.ReleaseMode e := echo.New()
if config.ServerInfo.RunMode != "" {
ginMode = config.ServerInfo.RunMode
}
if os.Getenv(gin.EnvGinMode) != "" {
ginMode = os.Getenv(gin.EnvGinMode)
}
gin.SetMode(ginMode)
r := gin.New() e.Use((echo_middleware.CORSWithConfig(echo_middleware.CORSConfig{
r.Use(gin.Recovery()) AllowOrigins: []string{"*"},
r.Use(middleware.Cors()) AllowMethods: []string{echo.POST, echo.GET, echo.OPTIONS, echo.PUT, echo.DELETE},
r.Use(gzip.Gzip(gzip.DefaultCompression)) AllowHeaders: []string{echo.HeaderAuthorization, echo.HeaderContentLength, echo.HeaderXCSRFToken, echo.HeaderContentType, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders, echo.HeaderAccessControlAllowMethods, echo.HeaderConnection, echo.HeaderOrigin, echo.HeaderXRequestedWith},
if ginMode != gin.ReleaseMode { ExposeHeaders: []string{echo.HeaderContentLength, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders},
r.Use(middleware.WriteLog()) MaxAge: 172800,
} AllowCredentials: true,
})))
e.Use(echo_middleware.Gzip())
e.Use(echo_middleware.Recover())
e.Use(echo_middleware.Logger())
r.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug e.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug
r.GET("/v1/sys/version/check", v1.GetSystemCheckVersion) e.GET("/v1/sys/version/check", v1.GetSystemCheckVersion)
r.GET("/v1/sys/version/current", func(ctx *gin.Context) { e.GET("/v1/sys/version/current", func(ctx echo.Context) error {
ctx.String(200, common.VERSION) return ctx.String(200, common.VERSION)
}) })
r.GET("/ping", func(ctx *gin.Context) { e.GET("/ping", func(ctx echo.Context) error {
ctx.String(200, "pong") return ctx.String(200, "pong")
}) })
r.GET("/v1/recover/:type", v1.GetRecoverStorage) e.GET("/v1/recover/:type", v1.GetRecoverStorage)
v1Group := r.Group("/v1") v1Group := e.Group("/v1")
// r.Any("/v1/test", v1.CheckNetwork) // e.Any("/v1/test", v1.CheckNetwork)
v1Group.Use(jwt.ExceptLocalhost(func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })) v1Group.Use(echo_middleware.JWTWithConfig(echo_middleware.JWTConfig{
Skipper: func(c echo.Context) bool {
return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1"
},
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
if err != nil || !valid {
return nil, echo.ErrUnauthorized
}
c.Request().Header.Set("user_id", strconv.Itoa(claims.ID))
return claims, nil
},
TokenLookupFuncs: []echo_middleware.ValuesExtractor{
func(ctx echo.Context) ([]string, error) {
if len(ctx.Request().Header.Get(echo.HeaderAuthorization)) > 0 {
return []string{ctx.Request().Header.Get(echo.HeaderAuthorization)}, nil
}
return []string{ctx.QueryParam("token")}, nil
},
},
}))
{ {
v1SysGroup := v1Group.Group("/sys") v1SysGroup := v1Group.Group("/sys")
@ -171,7 +189,6 @@ func InitV1Router() *gin.Engine {
v1OtherGroup.Use() v1OtherGroup.Use()
{ {
v1OtherGroup.GET("/search", v1.GetSearchResult) v1OtherGroup.GET("/search", v1.GetSearchResult)
} }
v1ZerotierGroup := v1Group.Group("/zt") v1ZerotierGroup := v1Group.Group("/zt")
v1ZerotierGroup.Use() v1ZerotierGroup.Use()
@ -180,5 +197,5 @@ func InitV1Router() *gin.Engine {
} }
} }
return r return e
} }

View File

@ -11,14 +11,14 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper" "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
"go.uber.org/zap" "go.uber.org/zap"
) )
func ListStorages(c *gin.Context) { func ListStorages(ctx echo.Context) error {
// var req model.PageReq // var req model.PageReq
// if err := c.ShouldBind(&req); err != nil { // if err := ctx.Bind(&req); err != nil {
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()}) // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
// return // return
// } // }
// req.Validate() // req.Validate()
@ -26,18 +26,16 @@ func ListStorages(c *gin.Context) {
// logger.Info("ListStorages", zap.Any("req", req)) // logger.Info("ListStorages", zap.Any("req", req))
// storages, total, err := service.MyService.Storage().GetStorages(req.Page, req.PerPage) // storages, total, err := service.MyService.Storage().GetStorages(req.Page, req.PerPage)
// if err != nil { // if err != nil {
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
// return // return
// } // }
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: model.PageResp{ // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: model.PageResp{
// Content: storages, // Content: storages,
// Total: total, // Total: total,
// }}) // }})
r, err := service.MyService.Storage().GetStorages() r, err := service.MyService.Storage().GetStorages()
if err != nil { if err != nil {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
for i := 0; i < len(r.MountPoints); i++ { for i := 0; i < len(r.MountPoints); i++ {
@ -53,7 +51,6 @@ func ListStorages(c *gin.Context) {
r.MountPoints[i].Icon = dropbox.ICONURL r.MountPoints[i].Icon = dropbox.ICONURL
} }
if dataMap["type"] == "onedrive" { if dataMap["type"] == "onedrive" {
r.MountPoints[i].Icon = onedrive.ICONURL r.MountPoints[i].Icon = onedrive.ICONURL
} }
r.MountPoints[i].Name = dataMap["username"] r.MountPoints[i].Name = dataMap["username"]
@ -69,38 +66,36 @@ func ListStorages(c *gin.Context) {
}) })
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
} }
func UmountStorage(c *gin.Context) { func UmountStorage(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
mountPoint := json["mount_point"] mountPoint := json["mount_point"]
if mountPoint == "" { if mountPoint == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "mount_point is empty"}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "mount_point is empty"})
return
} }
err := service.MyService.Storage().UnmountStorage(mountPoint) err := service.MyService.Storage().UnmountStorage(mountPoint)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
service.MyService.Storage().DeleteConfigByName(strings.ReplaceAll(mountPoint, "/mnt/", "")) service.MyService.Storage().DeleteConfigByName(strings.ReplaceAll(mountPoint, "/mnt/", ""))
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "success"}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "success"})
} }
func GetStorage(c *gin.Context) { func GetStorage(ctx echo.Context) error {
// idStr := ctx.QueryParam("id")
// idStr := c.Query("id")
// id, err := strconv.Atoi(idStr) // id, err := strconv.Atoi(idStr)
// if err != nil { // if err != nil {
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()}) // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
// return // return
// } // }
// storage, err := service.MyService.Storage().GetStorageById(uint(id)) // storage, err := service.MyService.Storage().GetStorageById(uint(id))
// if err != nil { // if err != nil {
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
// return // return
// } // }
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storage}) // return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storage})
return nil
} }

View File

@ -6,10 +6,10 @@ import (
"github.com/IceWhaleTech/CasaOS/drivers/google_drive" "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
"github.com/IceWhaleTech/CasaOS/drivers/onedrive" "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
) )
func ListDriverInfo(c *gin.Context) { func ListDriverInfo(ctx echo.Context) error {
list := []model.Drive{} list := []model.Drive{}
google := google_drive.GetConfig() google := google_drive.GetConfig()
@ -30,5 +30,5 @@ func ListDriverInfo(c *gin.Context) {
Icon: od.Icon, Icon: od.Icon,
AuthUrl: od.AuthUrl, AuthUrl: od.AuthUrl,
}) })
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
} }

View File

@ -20,15 +20,16 @@ import (
"github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/IceWhaleTech/CasaOS/pkg/utils"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/gin-gonic/gin"
"github.com/google/uuid" "github.com/google/uuid"
"go.uber.org/zap" "go.uber.org/zap"
@ -40,6 +41,7 @@ type ListReq struct {
Path string `json:"path" form:"path"` Path string `json:"path" form:"path"`
// Refresh bool `json:"refresh"` // Refresh bool `json:"refresh"`
} }
type ObjResp struct { type ObjResp struct {
Name string `json:"name"` Name string `json:"name"`
Size int64 `json:"size"` Size int64 `json:"size"`
@ -82,58 +84,53 @@ var (
// @Param path query string true "路径" // @Param path query string true "路径"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/read [get] // @Router /file/read [get]
func GetFilerContent(c *gin.Context) { func GetFilerContent(ctx echo.Context) error {
filePath := c.Query("path") filePath := ctx.QueryParam("path")
if len(filePath) == 0 { if len(filePath) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{ return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
Success: common_err.INVALID_PARAMS, Success: common_err.INVALID_PARAMS,
Message: common_err.GetMsg(common_err.INVALID_PARAMS), Message: common_err.GetMsg(common_err.INVALID_PARAMS),
}) })
return
} }
if !file.Exists(filePath) { if !file.Exists(filePath) {
c.JSON(common_err.SERVICE_ERROR, model.Result{ return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.FILE_DOES_NOT_EXIST, Success: common_err.FILE_DOES_NOT_EXIST,
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
}) })
return
} }
// 文件读取任务是将文件内容读取到内存中。 // 文件读取任务是将文件内容读取到内存中。
info, err := ioutil.ReadFile(filePath) info, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{ return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.FILE_READ_ERROR, Success: common_err.FILE_READ_ERROR,
Message: common_err.GetMsg(common_err.FILE_READ_ERROR), Message: common_err.GetMsg(common_err.FILE_READ_ERROR),
Data: err.Error(), Data: err.Error(),
}) })
return
} }
result := string(info) result := string(info)
c.JSON(common_err.SUCCESS, model.Result{ return ctx.JSON(common_err.SUCCESS, model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS), Message: common_err.GetMsg(common_err.SUCCESS),
Data: result, Data: result,
}) })
} }
func GetLocalFile(c *gin.Context) { func GetLocalFile(ctx echo.Context) error {
path := c.Query("path") path := ctx.QueryParam("path")
if len(path) == 0 { if len(path) == 0 {
c.JSON(http.StatusOK, model.Result{ return ctx.JSON(http.StatusOK, model.Result{
Success: common_err.INVALID_PARAMS, Success: common_err.INVALID_PARAMS,
Message: common_err.GetMsg(common_err.INVALID_PARAMS), Message: common_err.GetMsg(common_err.INVALID_PARAMS),
}) })
return
} }
if !file.Exists(path) { if !file.Exists(path) {
c.JSON(http.StatusOK, model.Result{ return ctx.JSON(http.StatusOK, model.Result{
Success: common_err.FILE_DOES_NOT_EXIST, Success: common_err.FILE_DOES_NOT_EXIST,
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
}) })
return
} }
c.File(path) return ctx.File(path)
} }
// @Summary download // @Summary download
@ -145,42 +142,39 @@ func GetLocalFile(c *gin.Context) {
// @Param files query string true "file list eg: filename1,filename2,filename3 " // @Param files query string true "file list eg: filename1,filename2,filename3 "
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/download [get] // @Router /file/download [get]
func GetDownloadFile(c *gin.Context) { func GetDownloadFile(ctx echo.Context) error {
t := c.Query("format") t := ctx.QueryParam("format")
files := c.Query("files") files := ctx.QueryParam("files")
if len(files) == 0 { if len(files) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{ return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
Success: common_err.INVALID_PARAMS, Success: common_err.INVALID_PARAMS,
Message: common_err.GetMsg(common_err.INVALID_PARAMS), Message: common_err.GetMsg(common_err.INVALID_PARAMS),
}) })
return
} }
list := strings.Split(files, ",") list := strings.Split(files, ",")
for _, v := range list { for _, v := range list {
if !file.Exists(v) { if !file.Exists(v) {
c.JSON(common_err.SERVICE_ERROR, model.Result{ return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.FILE_DOES_NOT_EXIST, Success: common_err.FILE_DOES_NOT_EXIST,
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
}) })
return
} }
} }
c.Header("Content-Type", "application/octet-stream") ctx.Request().Header.Add("Content-Type", "application/octet-stream")
c.Header("Content-Transfer-Encoding", "binary") ctx.Request().Header.Add("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache") ctx.Request().Header.Add("Cache-Control", "no-cache")
// handles only single files not folders and multiple files // handles only single files not folders and multiple files
if len(list) == 1 { if len(list) == 1 {
filePath := list[0] filePath := list[0]
info, err := os.Stat(filePath) info, err := os.Stat(filePath)
if err != nil { if err != nil {
c.JSON(http.StatusOK, model.Result{ return ctx.JSON(http.StatusOK, model.Result{
Success: common_err.FILE_DOES_NOT_EXIST, Success: common_err.FILE_DOES_NOT_EXIST,
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
}) })
return
} }
if !info.IsDir() { if !info.IsDir() {
@ -190,29 +184,26 @@ func GetDownloadFile(c *gin.Context) {
// 获取文件的名称 // 获取文件的名称
fileName := path.Base(filePath) fileName := path.Base(filePath)
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) ctx.Response().Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
c.File(filePath) ctx.File(filePath)
return
} }
} }
extension, ar, err := file.GetCompressionAlgorithm(t) extension, ar, err := file.GetCompressionAlgorithm(t)
if err != nil { if err != nil {
c.JSON(common_err.CLIENT_ERROR, model.Result{ return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
Success: common_err.INVALID_PARAMS, Success: common_err.INVALID_PARAMS,
Message: common_err.GetMsg(common_err.INVALID_PARAMS), Message: common_err.GetMsg(common_err.INVALID_PARAMS),
}) })
return
} }
err = ar.Create(c.Writer) err = ar.Create(ctx.Response().Writer)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{ return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.SERVICE_ERROR, Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR), Message: common_err.GetMsg(common_err.SERVICE_ERROR),
Data: err.Error(), Data: err.Error(),
}) })
return
} }
defer ar.Close() defer ar.Close()
commonDir := file.CommonPrefix(filepath.Separator, list...) commonDir := file.CommonPrefix(filepath.Separator, list...)
@ -221,27 +212,27 @@ func GetDownloadFile(c *gin.Context) {
name := "_" + currentPath name := "_" + currentPath
name += extension name += extension
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name)) ctx.Request().Header.Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
for _, fname := range list { for _, fname := range list {
err = file.AddFile(ar, fname, commonDir) err = file.AddFile(ar, fname, commonDir)
if err != nil { if err != nil {
log.Printf("Failed to archive %s: %v", fname, err) log.Printf("Failed to archive %s: %v", fname, err)
} }
} }
return nil
} }
func GetDownloadSingleFile(c *gin.Context) { func GetDownloadSingleFile(ctx echo.Context) error {
filePath := c.Query("path") filePath := ctx.QueryParam("path")
if len(filePath) == 0 { if len(filePath) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{ return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
Success: common_err.INVALID_PARAMS, Success: common_err.INVALID_PARAMS,
Message: common_err.GetMsg(common_err.INVALID_PARAMS), Message: common_err.GetMsg(common_err.INVALID_PARAMS),
}) })
return
} }
fileName := path.Base(filePath) fileName := path.Base(filePath)
// c.Header("Content-Disposition", "inline") // c.Header("Content-Disposition", "inline")
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) ctx.Request().Header.Add("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
fi, err := os.Open(filePath) fi, err := os.Open(filePath)
if err != nil { if err != nil {
@ -255,31 +246,29 @@ func GetDownloadSingleFile(c *gin.Context) {
kind, _ := filetype.Match(buffer) kind, _ := filetype.Match(buffer)
if kind != filetype.Unknown { if kind != filetype.Unknown {
c.Header("Content-Type", kind.MIME.Value) ctx.Request().Header.Add("Content-Type", kind.MIME.Value)
} }
node, err := os.Stat(filePath) node, err := os.Stat(filePath)
// Set the Last-Modified header to the timestamp // Set the Last-Modified header to the timestamp
c.Header("Last-Modified", node.ModTime().UTC().Format(http.TimeFormat)) ctx.Request().Header.Add("Last-Modified", node.ModTime().UTC().Format(http.TimeFormat))
knownSize := node.Size() >= 0 knownSize := node.Size() >= 0
if knownSize { if knownSize {
c.Header("Content-Length", strconv.FormatInt(node.Size(), 10)) ctx.Request().Header.Add("Content-Length", strconv.FormatInt(node.Size(), 10))
} }
http.ServeContent(c.Writer, c.Request, fileName, node.ModTime(), fi) http.ServeContent(ctx.Response().Writer, ctx.Request(), fileName, node.ModTime(), fi)
//http.ServeFile(c.Writer, c.Request, filePath) // http.ServeFile(c.Writer, ctx.Request(), filePath)
defer fi.Close() defer fi.Close()
return
fileTmp, err := os.Open(filePath) fileTmp, err := os.Open(filePath)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{ return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.FILE_DOES_NOT_EXIST, Success: common_err.FILE_DOES_NOT_EXIST,
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
}) })
return
} }
defer fileTmp.Close() defer fileTmp.Close()
c.File(filePath) return ctx.File(filePath)
} }
// @Summary 获取目录列表 // @Summary 获取目录列表
@ -290,17 +279,14 @@ func GetDownloadSingleFile(c *gin.Context) {
// @Param path query string false "路径" // @Param path query string false "路径"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/dirpath [get] // @Router /file/dirpath [get]
func DirPath(c *gin.Context) { func DirPath(ctx echo.Context) error {
var req ListReq var req ListReq
if err := c.ShouldBind(&req); err != nil { path := ctx.QueryParam("path")
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()}) req.Path = path
return
}
req.Validate() req.Validate()
info, err := service.MyService.System().GetDirPath(req.Path) info, err := service.MyService.System().GetDirPath(req.Path)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
shares := service.MyService.Shares().GetSharesList() shares := service.MyService.Shares().GetSharesList()
sharesMap := make(map[string]string) sharesMap := make(map[string]string)
@ -308,7 +294,7 @@ func DirPath(c *gin.Context) {
sharesMap[v.Path] = fmt.Sprint(v.ID) sharesMap[v.Path] = fmt.Sprint(v.ID)
} }
// if len(info) <= (req.Page-1)*req.Size { // if len(info) <= (req.Page-1)*req.Size {
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "page out of range"}) // return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "page out of range"})
// return // return
// } // }
forEnd := req.Index * req.Size forEnd := req.Index * req.Size
@ -380,7 +366,7 @@ func DirPath(c *gin.Context) {
Index: req.Index, Index: req.Index,
Size: req.Size, Size: req.Size,
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: flist}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: flist})
} }
// @Summary rename file or dir // @Summary rename file or dir
@ -392,23 +378,21 @@ func DirPath(c *gin.Context) {
// @Param newpath body string true "path of new" // @Param newpath body string true "path of new"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/rename [put] // @Router /file/rename [put]
func RenamePath(c *gin.Context) { func RenamePath(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
op := json["old_path"] op := json["old_path"]
np := json["new_path"] np := json["new_path"]
if len(op) == 0 || len(np) == 0 { if len(op) == 0 || len(np) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
mounted := service.IsMounted(op) mounted := service.IsMounted(op)
if mounted { if mounted {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
return
} }
success, err := service.MyService.System().RenameFile(op, np) success, err := service.MyService.System().RenameFile(op, np)
c.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
} }
// @Summary create folder // @Summary create folder
@ -419,22 +403,21 @@ func RenamePath(c *gin.Context) {
// @Param path body string true "path of folder" // @Param path body string true "path of folder"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/mkdir [post] // @Router /file/mkdir [post]
func MkdirAll(c *gin.Context) { func MkdirAll(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
path := json["path"] path := json["path"]
var code int var code int
if len(path) == 0 { if len(path) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
// decodedPath, err := url.QueryUnescape(path) // decodedPath, err := url.QueryUnescape(path)
// if err != nil { // if err != nil {
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return ctx.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
// return // return
// } // }
code, _ = service.MyService.System().MkdirAll(path) code, _ = service.MyService.System().MkdirAll(path)
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
} }
// @Summary create file // @Summary create file
@ -445,22 +428,21 @@ func MkdirAll(c *gin.Context) {
// @Param path body string true "path of folder (path need to url encode)" // @Param path body string true "path of folder (path need to url encode)"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/create [post] // @Router /file/create [post]
func PostCreateFile(c *gin.Context) { func PostCreateFile(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
path := json["path"] path := json["path"]
var code int var code int
if len(path) == 0 { if len(path) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
// decodedPath, err := url.QueryUnescape(path) // decodedPath, err := url.QueryUnescape(path)
// if err != nil { // if err != nil {
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return ctx.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
// return // return
// } // }
code, _ = service.MyService.System().CreateFile(path) code, _ = service.MyService.System().CreateFile(path)
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
} }
// @Summary upload file // @Summary upload file
@ -472,17 +454,16 @@ func PostCreateFile(c *gin.Context) {
// @Param file formData file true "file" // @Param file formData file true "file"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/upload [get] // @Router /file/upload [get]
func GetFileUpload(c *gin.Context) { func GetFileUpload(ctx echo.Context) error {
relative := c.Query("relativePath") relative := ctx.QueryParam("relativePath")
fileName := c.Query("filename") fileName := ctx.QueryParam("filename")
chunkNumber := c.Query("chunkNumber") chunkNumber := ctx.QueryParam("chunkNumber")
totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0")) totalChunks, _ := strconv.Atoi(utils.DefaultQuery(ctx, "totalChunks", "0"))
path := c.Query("path") path := ctx.QueryParam("path")
dirPath := "" dirPath := ""
hash := file.GetHashByContent([]byte(fileName)) hash := file.GetHashByContent([]byte(fileName))
if file.Exists(path + "/" + relative) { if file.Exists(path + "/" + relative) {
c.JSON(http.StatusConflict, model.Result{Success: http.StatusConflict, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return ctx.JSON(http.StatusConflict, model.Result{Success: http.StatusConflict, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
return
} }
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/" tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
if fileName != relative { if fileName != relative {
@ -492,11 +473,10 @@ func GetFileUpload(c *gin.Context) {
} }
tempDir += chunkNumber tempDir += chunkNumber
if !file.CheckNotExist(tempDir) { if !file.CheckNotExist(tempDir) {
c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return ctx.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
return
} }
c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary upload file // @Summary upload file
@ -508,21 +488,20 @@ func GetFileUpload(c *gin.Context) {
// @Param file formData file true "file" // @Param file formData file true "file"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/upload [post] // @Router /file/upload [post]
func PostFileUpload(c *gin.Context) { func PostFileUpload(ctx echo.Context) error {
f, _, _ := c.Request.FormFile("file") f, _, _ := ctx.Request().FormFile("file")
relative := c.PostForm("relativePath") relative := ctx.FormValue("relativePath")
fileName := c.PostForm("filename") fileName := ctx.FormValue("filename")
totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0")) totalChunks, _ := strconv.Atoi(utils.DefaultPostForm(ctx, "totalChunks", "0"))
chunkNumber := c.PostForm("chunkNumber") chunkNumber := ctx.FormValue("chunkNumber")
dirPath := "" dirPath := ""
path := c.PostForm("path") path := ctx.FormValue("path")
hash := file.GetHashByContent([]byte(fileName)) hash := file.GetHashByContent([]byte(fileName))
if len(path) == 0 { if len(path) == 0 {
logger.Error("path should not be empty") logger.Error("path should not be empty")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/" tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
@ -531,8 +510,7 @@ func PostFileUpload(c *gin.Context) {
tempDir += dirPath tempDir += dirPath
if err := file.MkDir(path + "/" + dirPath); err != nil { if err := file.MkDir(path + "/" + dirPath); err != nil {
logger.Error("error when trying to create `"+path+"/"+dirPath+"`", zap.Error(err)) logger.Error("error when trying to create `"+path+"/"+dirPath+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
} }
@ -541,48 +519,41 @@ func PostFileUpload(c *gin.Context) {
if !file.CheckNotExist(tempDir + chunkNumber) { if !file.CheckNotExist(tempDir + chunkNumber) {
if err := file.RMDir(tempDir + chunkNumber); err != nil { if err := file.RMDir(tempDir + chunkNumber); err != nil {
logger.Error("error when trying to remove existing `"+tempDir+chunkNumber+"`", zap.Error(err)) logger.Error("error when trying to remove existing `"+tempDir+chunkNumber+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
} }
if totalChunks > 1 { if totalChunks > 1 {
if err := file.IsNotExistMkDir(tempDir); err != nil { if err := file.IsNotExistMkDir(tempDir); err != nil {
logger.Error("error when trying to create `"+tempDir+"`", zap.Error(err)) logger.Error("error when trying to create `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
out, err := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0o644) out, err := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil { if err != nil {
logger.Error("error when trying to open `"+tempDir+chunkNumber+"` for creation", zap.Error(err)) logger.Error("error when trying to open `"+tempDir+chunkNumber+"` for creation", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
defer out.Close() defer out.Close()
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
logger.Error("error when trying to write to `"+tempDir+chunkNumber+"`", zap.Error(err)) logger.Error("error when trying to write to `"+tempDir+chunkNumber+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
fileNum, err := ioutil.ReadDir(tempDir) fileNum, err := ioutil.ReadDir(tempDir)
if err != nil { if err != nil {
logger.Error("error when trying to read number of files under `"+tempDir+"`", zap.Error(err)) logger.Error("error when trying to read number of files under `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
if totalChunks == len(fileNum) { if totalChunks == len(fileNum) {
if err := file.SpliceFiles(tempDir, path, totalChunks, 1); err != nil { if err := file.SpliceFiles(tempDir, path, totalChunks, 1); err != nil {
logger.Error("error when trying to splice files under `"+tempDir+"`", zap.Error(err)) logger.Error("error when trying to splice files under `"+tempDir+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
go func() { go func() {
time.Sleep(11 * time.Second) time.Sleep(11 * time.Second)
if err := file.RMDir(tempDir); err != nil { if err := file.RMDir(tempDir); err != nil {
logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err)) logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
@ -593,57 +564,49 @@ func PostFileUpload(c *gin.Context) {
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644) out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil { if err != nil {
logger.Error("error when trying to open `"+path+"` for creation", zap.Error(err)) logger.Error("error when trying to open `"+path+"` for creation", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
} }
defer out.Close() defer out.Close()
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
logger.Error("error when trying to write to `"+path+"`", zap.Error(err)) logger.Error("error when trying to write to `"+path+"`", zap.Error(err))
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
} }
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
func PostFileOctet(c *gin.Context) { func PostFileOctet(ctx echo.Context) error {
content_length := ctx.Request().ContentLength
content_length := c.Request.ContentLength
if content_length <= 0 || content_length > 1024*1024*1024*2*1024 { if content_length <= 0 || content_length > 1024*1024*1024*2*1024 {
log.Printf("content_length error\n") log.Printf("content_length error\n")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "content_length error"}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "content_length error"})
return
} }
content_type_, has_key := c.Request.Header["Content-Type"] content_type_, has_key := ctx.Request().Header["Content-Type"]
if !has_key { if !has_key {
log.Printf("Content-Type error\n") log.Printf("Content-Type error\n")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error"}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error"})
return
} }
if len(content_type_) != 1 { if len(content_type_) != 1 {
log.Printf("Content-Type count error\n") log.Printf("Content-Type count error\n")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type count error"}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type count error"})
return
} }
content_type := content_type_[0] content_type := content_type_[0]
const BOUNDARY string = "; boundary=" const BOUNDARY string = "; boundary="
loc := strings.Index(content_type, BOUNDARY) loc := strings.Index(content_type, BOUNDARY)
if loc == -1 { if loc == -1 {
log.Printf("Content-Type error, no boundary\n") log.Printf("Content-Type error, no boundary\n")
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error, no boundary"}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error, no boundary"})
return
} }
boundary := []byte(content_type[(loc + len(BOUNDARY)):]) boundary := []byte(content_type[(loc + len(BOUNDARY)):])
log.Printf("[%s]\n\n", boundary) log.Printf("[%s]\n\n", boundary)
read_data := make([]byte, 1024*24) read_data := make([]byte, 1024*24)
var read_total int = 0 var read_total int = 0
for { for {
file_header, file_data, err := file.ParseFromHead(read_data, read_total, append(boundary, []byte("\r\n")...), c.Request.Body) file_header, file_data, err := file.ParseFromHead(read_data, read_total, append(boundary, []byte("\r\n")...), ctx.Request().Body)
if err != nil { if err != nil {
log.Printf("%v", err) log.Printf("%v", err)
return
} }
log.Printf("file :%s\n", file_header) log.Printf("file :%s\n", file_header)
// //
@ -651,16 +614,14 @@ func PostFileOctet(c *gin.Context) {
f, err := os.OpenFile(file_header["path"]+"/"+file_header["filename"], os.O_WRONLY|os.O_CREATE, 0o644) f, err := os.OpenFile(file_header["path"]+"/"+file_header["filename"], os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil { if err != nil {
log.Printf("create file fail:%v\n", err) log.Printf("create file fail:%v\n", err)
return
} }
f.Write(file_data) f.Write(file_data)
file_data = nil file_data = nil
temp_data, reach_end, err := file.ReadToBoundary(boundary, c.Request.Body, f) temp_data, reach_end, err := file.ReadToBoundary(boundary, ctx.Request().Body, f)
f.Close() f.Close()
if err != nil { if err != nil {
log.Printf("%v\n", err) log.Printf("%v\n", err)
return
} }
if reach_end { if reach_end {
break break
@ -670,7 +631,7 @@ func PostFileOctet(c *gin.Context) {
continue continue
} }
} }
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary copy or move file // @Summary copy or move file
@ -681,17 +642,15 @@ func PostFileOctet(c *gin.Context) {
// @Param body body model.FileOperate true "type:move,copy" // @Param body body model.FileOperate true "type:move,copy"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/operate [post] // @Router /file/operate [post]
func PostOperateFileOrDir(c *gin.Context) { func PostOperateFileOrDir(ctx echo.Context) error {
list := model.FileOperate{} list := model.FileOperate{}
c.ShouldBind(&list) ctx.Bind(&list)
if len(list.Item) == 0 { if len(list.Item) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] { if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)})
return
} }
var total int64 = 0 var total int64 = 0
@ -706,8 +665,7 @@ func PostOperateFileOrDir(c *gin.Context) {
if list.Type == "move" { if list.Type == "move" {
mounted := service.IsMounted(list.Item[i].From) mounted := service.IsMounted(list.Item[i].From)
if mounted { if mounted {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
return
} }
} }
} }
@ -726,7 +684,7 @@ func PostOperateFileOrDir(c *gin.Context) {
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary delete file // @Summary delete file
@ -737,33 +695,30 @@ func PostOperateFileOrDir(c *gin.Context) {
// @Param body body string true "paths eg ["/a/b/c","/d/e/f"]" // @Param body body string true "paths eg ["/a/b/c","/d/e/f"]"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/delete [delete] // @Router /file/delete [delete]
func DeleteFile(c *gin.Context) { func DeleteFile(ctx echo.Context) error {
paths := []string{} paths := []string{}
c.ShouldBind(&paths) ctx.Bind(&paths)
if len(paths) == 0 { if len(paths) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
} }
// path := c.Query("path") // path := ctx.QueryParam("path")
// paths := strings.Split(path, ",") // paths := strings.Split(path, ",")
for _, v := range paths { for _, v := range paths {
mounted := service.IsMounted(v) mounted := service.IsMounted(v)
if mounted { if mounted {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
return
} }
} }
for _, v := range paths { for _, v := range paths {
err := os.RemoveAll(v) err := os.RemoveAll(v)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
return
} }
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary update file // @Summary update file
@ -775,34 +730,30 @@ func DeleteFile(c *gin.Context) {
// @Param content body string true "content" // @Param content body string true "content"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/update [put] // @Router /file/update [put]
func PutFileContent(c *gin.Context) { func PutFileContent(ctx echo.Context) error {
fi := model.FileUpdate{} fi := model.FileUpdate{}
c.ShouldBind(&fi) ctx.Bind(&fi)
// path := c.PostForm("path") // path := ctx.FormValue("path")
// content := c.PostForm("content") // content := ctx.FormValue("content")
if !file.Exists(fi.FilePath) { if !file.Exists(fi.FilePath) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
return
} }
// err := os.Remove(path) // err := os.Remove(path)
f, err := os.Stat(fi.FilePath) f, err := os.Stat(fi.FilePath)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
return
} }
fm := f.Mode() fm := f.Mode()
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
return
} }
os.OpenFile(fi.FilePath, os.O_CREATE, fm) os.OpenFile(fi.FilePath, os.O_CREATE, fm)
err = file.WriteToFullPath([]byte(fi.FileContent), fi.FilePath, fm) err = file.WriteToFullPath([]byte(fi.FileContent), fi.FilePath, fm)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary image thumbnail/original image // @Summary image thumbnail/original image
@ -814,38 +765,34 @@ func PutFileContent(c *gin.Context) {
// @Param type query string false "original,thumbnail" Enums(original,thumbnail) // @Param type query string false "original,thumbnail" Enums(original,thumbnail)
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /file/image [get] // @Router /file/image [get]
func GetFileImage(c *gin.Context) { func GetFileImage(ctx echo.Context) error {
t := c.Query("type") t := ctx.QueryParam("type")
path := c.Query("path") path := ctx.QueryParam("path")
if !file.Exists(path) { if !file.Exists(path) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
return
} }
if t == "thumbnail" { if t == "thumbnail" {
f, err := file.GetImage(path, 100, 0) f, err := file.GetImage(path, 100, 0)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.Writer.WriteString(string(f)) ctx.Response().Writer.Write(f)
return
} }
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
defer f.Close() defer f.Close()
data, err := ioutil.ReadAll(f) data, err := ioutil.ReadAll(f)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.Writer.WriteString(string(data)) ctx.Response().Writer.Write(data)
return nil
} }
func DeleteOperateFileOrDir(c *gin.Context) { func DeleteOperateFileOrDir(ctx echo.Context) error {
id := c.Param("id") id := ctx.Param("id")
if id == "0" { if id == "0" {
service.FileQueue = sync.Map{} service.FileQueue = sync.Map{}
service.OpStrArr = []string{} service.OpStrArr = []string{}
@ -863,30 +810,29 @@ func DeleteOperateFileOrDir(c *gin.Context) {
} }
go service.MyService.Notify().SendFileOperateNotify(true) go service.MyService.Notify().SendFileOperateNotify(true)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
func GetSize(c *gin.Context) {
func GetSize(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
path := json["path"] path := json["path"]
size, err := file.GetFileOrDirSize(path) size, err := file.GetFileOrDirSize(path)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: size}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: size})
} }
func GetFileCount(c *gin.Context) { func GetFileCount(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
path := json["path"] path := json["path"]
list, err := ioutil.ReadDir(path) list, err := ioutil.ReadDir(path)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: len(list)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: len(list)})
} }
type CenterHandler struct { type CenterHandler struct {
@ -919,17 +865,16 @@ type PeerModel struct {
RtcSupported bool `json:"rtcSupported"` RtcSupported bool `json:"rtcSupported"`
} }
func ConnectWebSocket(c *gin.Context) { func ConnectWebSocket(ctx echo.Context) error {
peerId := c.Query("peer") peerId := ctx.QueryParam("peer")
writer := c.Writer writer := ctx.Response().Writer
request := c.Request request := ctx.Request()
key := uuid.NewString() key := uuid.NewString()
//peerModel := service.MyService.Peer().GetPeerByUserAgent(c.Request.UserAgent()) // peerModel := service.MyService.Peer().GetPeerByUserAgent(ctx.Request().UserAgent())
peerModel := model2.PeerDriveDBModel{} peerModel := model2.PeerDriveDBModel{}
name := service.GetName(request) name := service.GetName(request)
if conn, err = upgraderFile.Upgrade(writer, request, writer.Header()); err != nil { if conn, err = upgraderFile.Upgrade(writer, request, writer.Header()); err != nil {
log.Println(err) log.Println(err)
return
} }
client := &Client{handler: &handler, conn: conn, send: make(chan []byte, 256), ID: service.GetPeerId(request, key), IP: service.GetIP(request), Name: name, RtcSupported: true, TimerId: 0, LastBeat: time.Now()} client := &Client{handler: &handler, conn: conn, send: make(chan []byte, 256), ID: service.GetPeerId(request, key), IP: service.GetIP(request), Name: name, RtcSupported: true, TimerId: 0, LastBeat: time.Now()}
if peerId != "" || len(peerModel.ID) > 0 { if peerId != "" || len(peerModel.ID) > 0 {
@ -942,7 +887,7 @@ func ConnectWebSocket(c *gin.Context) {
client.Name = service.GetNameByDB(peerModel) client.Name = service.GetNameByDB(peerModel)
} }
} }
var list = service.MyService.Peer().GetPeers() list := service.MyService.Peer().GetPeers()
if len(peerModel.ID) == 0 { if len(peerModel.ID) == 0 {
peerModel.ID = key peerModel.ID = key
peerModel.DisplayName = name.DisplayName peerModel.DisplayName = name.DisplayName
@ -950,7 +895,7 @@ func ConnectWebSocket(c *gin.Context) {
peerModel.Model = name.Model peerModel.Model = name.Model
peerModel.OS = name.OS peerModel.OS = name.OS
peerModel.Browser = name.Browser peerModel.Browser = name.Browser
peerModel.UserAgent = c.Request.UserAgent() peerModel.UserAgent = ctx.Request().UserAgent()
peerModel.IP = client.IP peerModel.IP = client.IP
service.MyService.Peer().CreatePeer(&peerModel) service.MyService.Peer().CreatePeer(&peerModel)
list = append(list, peerModel) list = append(list, peerModel)
@ -1027,13 +972,15 @@ func ConnectWebSocket(c *gin.Context) {
// 每个 client 都挂起 2 个新的协程,监控读、写状态 // 每个 client 都挂起 2 个新的协程,监控读、写状态
go client.writePump() go client.writePump()
go client.readPump() go client.readPump()
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
var handler = CenterHandler{broadcast: make(chan []byte), var handler = CenterHandler{
broadcast: make(chan []byte),
register: make(chan *Client), register: make(chan *Client),
unregister: make(chan *Client), unregister: make(chan *Client),
clients: make(map[string]*Client)} clients: make(map[string]*Client),
}
func init() { func init() {
// 起个协程跑起来,监听注册、注销、消息 3 个 channel // 起个协程跑起来,监听注册、注销、消息 3 个 channel
@ -1052,6 +999,7 @@ func init() {
// 启动定时器 // 启动定时器
crontab.Start() crontab.Start()
} }
func (c *Client) writePump() { func (c *Client) writePump() {
defer func() { defer func() {
c.handler.unregister <- c c.handler.unregister <- c
@ -1131,6 +1079,7 @@ func (c *Client) readPump() {
c.handler.broadcast <- message c.handler.broadcast <- message
} }
} }
func (ch *CenterHandler) monitoring() { func (ch *CenterHandler) monitoring() {
for { for {
select { select {
@ -1150,12 +1099,13 @@ func (ch *CenterHandler) monitoring() {
} }
} }
} }
func GetPeers(c *gin.Context) {
func GetPeers(ctx echo.Context) error {
peers := service.MyService.Peer().GetPeers() peers := service.MyService.Peer().GetPeers()
for i := 0; i < len(peers); i++ { for i := 0; i < len(peers); i++ {
if _, ok := handler.clients[peers[i].ID]; ok { if _, ok := handler.clients[peers[i].ID]; ok {
peers[i].Online = true peers[i].Online = true
} }
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: peers}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: peers})
} }

View File

@ -6,28 +6,26 @@ import (
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
) )
func PostNotifyMessage(c *gin.Context) { func PostNotifyMessage(ctx echo.Context) error {
name := c.Param("name") name := ctx.Param("name")
message := make(map[string]interface{}) message := make(map[string]interface{})
if err := c.ShouldBind(&message); err != nil { if err := ctx.Bind(&message); err != nil {
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
return
} }
service.MyService.Notify().SendNotify(name, message) service.MyService.Notify().SendNotify(name, message)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
func PostSystemStatusNotify(c *gin.Context) { func PostSystemStatusNotify(ctx echo.Context) error {
message := make(map[string]interface{}) message := make(map[string]interface{})
if err := c.ShouldBind(&message); err != nil { if err := ctx.Bind(&message); err != nil {
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()}) return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
return
} }
service.MyService.Notify().SettingSystemTempData(message) service.MyService.Notify().SettingSystemTempData(message)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }

View File

@ -6,8 +6,8 @@ import (
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/IceWhaleTech/CasaOS/types" "github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
) )
var upGrader = websocket.Upgrader{ var upGrader = websocket.Upgrader{
@ -24,11 +24,11 @@ var upGrader = websocket.Upgrader{
// @Param token path string true "token" // @Param token path string true "token"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /notify/ws [get] // @Router /notify/ws [get]
func NotifyWS(c *gin.Context) { func NotifyWS(ctx echo.Context) error {
// 升级get请求为webSocket协议 // 升级get请求为webSocket协议
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) ws, err := upGrader.Upgrade(ctx.Response().Writer, ctx.Request(), nil)
if err != nil { if err != nil {
return return nil
} }
defer ws.Close() defer ws.Close()
service.WebSocketConns = append(service.WebSocketConns, ws) service.WebSocketConns = append(service.WebSocketConns, ws)
@ -41,7 +41,6 @@ func NotifyWS(c *gin.Context) {
mt, message, err := ws.ReadMessage() mt, message, err := ws.ReadMessage()
fmt.Println(mt, message, err) fmt.Println(mt, message, err)
} }
} }
// @Summary 标记notify已读 // @Summary 标记notify已读
@ -51,12 +50,13 @@ func NotifyWS(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /notify/read/{id} [put] // @Router /notify/read/{id} [put]
func PutNotifyRead(c *gin.Context) { func PutNotifyRead(ctx echo.Context) error {
id := c.Param("id") id := ctx.Param("id")
// if len(id) == 0 { // if len(id) == 0 {
// c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)}) // return ctx.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
// return // return
// } // }
fmt.Println(id) fmt.Println(id)
service.MyService.Notify().MarkRead(id, types.NOTIFY_READ) service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
return nil
} }

View File

@ -6,25 +6,23 @@ import (
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
) )
func GetSearchResult(c *gin.Context) { func GetSearchResult(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
url := json["url"] url := json["url"]
if url == "" { if url == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "key is empty"}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "key is empty"})
return
} }
// data, err := service.MyService.Other().Search(key) // data, err := service.MyService.Other().Search(key)
data, err := service.MyService.Other().AgentSearch(url) data, err := service.MyService.Other().AgentSearch(url)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }

View File

@ -10,57 +10,54 @@ import (
"github.com/IceWhaleTech/CasaOS/drivers/google_drive" "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
"github.com/IceWhaleTech/CasaOS/drivers/onedrive" "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
"go.uber.org/zap" "go.uber.org/zap"
) )
func GetRecoverStorage(c *gin.Context) { func GetRecoverStorage(ctx echo.Context) error {
c.Header("Content-Type", "text/html; charset=utf-8") ctx.Request().Header.Add("Content-Type", "text/html; charset=utf-8")
t := c.Param("type") t := ctx.Param("type")
currentTime := time.Now().UTC() currentTime := time.Now().UTC()
currentDate := time.Now().UTC().Format("2006-01-02") currentDate := time.Now().UTC().Format("2006-01-02")
notify := make(map[string]interface{}) notify := make(map[string]interface{})
if t == "GoogleDrive" { if t == "GoogleDrive" {
google_drive := google_drive.GetConfig() google_drive := google_drive.GetConfig()
google_drive.Code = c.Query("code") google_drive.Code = ctx.QueryParam("code")
if len(google_drive.Code) == 0 { if len(google_drive.Code) == 0 {
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`) ctx.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Code cannot be empty" notify["message"] = "Code cannot be empty"
logger.Error("Then code is empty: ", zap.String("code", google_drive.Code), zap.Any("name", "google_drive")) logger.Error("Then code is empty: ", zap.String("code", google_drive.Code), zap.Any("name", "google_drive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
err := google_drive.Init(c) err := google_drive.Init(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Initialization failure" notify["message"] = "Initialization failure"
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "google_drive")) logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "google_drive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
username, err := google_drive.GetUserInfo(c) username, err := google_drive.GetUserInfo(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get user information" notify["message"] = "Failed to get user information"
logger.Error("Then get user info error: ", zap.Error(err), zap.Any("name", "google_drive")) logger.Error("Then get user info error: ", zap.Error(err), zap.Any("name", "google_drive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
dmap := make(map[string]string) dmap := make(map[string]string)
dmap["username"] = username dmap["username"] = username
configs, err := service.MyService.Storage().GetConfig() configs, err := service.MyService.Storage().GetConfig()
if err != nil { if err != nil {
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get rclone config" notify["message"] = "Failed to get rclone config"
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "google_drive")) logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "google_drive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
for _, v := range configs.Remotes { for _, v := range configs.Remotes {
cf, err := service.MyService.Storage().GetConfigByName(v) cf, err := service.MyService.Storage().GetConfigByName(v)
@ -69,7 +66,7 @@ func GetRecoverStorage(c *gin.Context) {
continue continue
} }
if cf["type"] == "drive" && cf["username"] == dmap["username"] { if cf["type"] == "drive" && cf["username"] == dmap["username"] {
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`) ctx.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
err := service.MyService.Storage().CheckAndMountByName(v) err := service.MyService.Storage().CheckAndMountByName(v)
if err != nil { if err != nil {
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"])) logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
@ -77,7 +74,6 @@ func GetRecoverStorage(c *gin.Context) {
notify["status"] = "warn" notify["status"] = "warn"
notify["message"] = "The same configuration has been added" notify["message"] = "The same configuration has been added"
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
} }
if len(username) > 0 { if len(username) > 0 {
@ -102,45 +98,41 @@ func GetRecoverStorage(c *gin.Context) {
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
} else if t == "Dropbox" { } else if t == "Dropbox" {
dropbox := dropbox.GetConfig() dropbox := dropbox.GetConfig()
dropbox.Code = c.Query("code") dropbox.Code = ctx.QueryParam("code")
if len(dropbox.Code) == 0 { if len(dropbox.Code) == 0 {
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`) ctx.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Code cannot be empty" notify["message"] = "Code cannot be empty"
logger.Error("Then code is empty error: ", zap.String("code", dropbox.Code), zap.Any("name", "dropbox")) logger.Error("Then code is empty error: ", zap.String("code", dropbox.Code), zap.Any("name", "dropbox"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
err := dropbox.Init(c) err := dropbox.Init(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Initialization failure" notify["message"] = "Initialization failure"
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "dropbox")) logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "dropbox"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
username, err := dropbox.GetUserInfo(c) username, err := dropbox.GetUserInfo(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get user information" notify["message"] = "Failed to get user information"
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "dropbox")) logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "dropbox"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
dmap := make(map[string]string) dmap := make(map[string]string)
dmap["username"] = username dmap["username"] = username
configs, err := service.MyService.Storage().GetConfig() configs, err := service.MyService.Storage().GetConfig()
if err != nil { if err != nil {
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get rclone config" notify["message"] = "Failed to get rclone config"
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "dropbox")) logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "dropbox"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
for _, v := range configs.Remotes { for _, v := range configs.Remotes {
cf, err := service.MyService.Storage().GetConfigByName(v) cf, err := service.MyService.Storage().GetConfigByName(v)
@ -149,7 +141,7 @@ func GetRecoverStorage(c *gin.Context) {
continue continue
} }
if cf["type"] == "dropbox" && cf["username"] == dmap["username"] { if cf["type"] == "dropbox" && cf["username"] == dmap["username"] {
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`) ctx.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
err := service.MyService.Storage().CheckAndMountByName(v) err := service.MyService.Storage().CheckAndMountByName(v)
if err != nil { if err != nil {
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"])) logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
@ -158,7 +150,6 @@ func GetRecoverStorage(c *gin.Context) {
notify["status"] = "warn" notify["status"] = "warn"
notify["message"] = "The same configuration has been added" notify["message"] = "The same configuration has been added"
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
} }
if len(username) > 0 { if len(username) > 0 {
@ -179,7 +170,7 @@ func GetRecoverStorage(c *gin.Context) {
// data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`) // data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`)
// e = data.Save() // e = data.Save()
// if e != nil { // if e != nil {
// c.String(200, `<p>保存配置失败:`+e.Error()+`</p>`) // return ctx.String(200, `<p>保存配置失败:`+e.Error()+`</p>`)
// return // return
// } // }
@ -192,45 +183,41 @@ func GetRecoverStorage(c *gin.Context) {
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
} else if t == "Onedrive" { } else if t == "Onedrive" {
onedrive := onedrive.GetConfig() onedrive := onedrive.GetConfig()
onedrive.Code = c.Query("code") onedrive.Code = ctx.QueryParam("code")
if len(onedrive.Code) == 0 { if len(onedrive.Code) == 0 {
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`) ctx.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Code cannot be empty" notify["message"] = "Code cannot be empty"
logger.Error("Then code is empty error: ", zap.String("code", onedrive.Code), zap.Any("name", "onedrive")) logger.Error("Then code is empty error: ", zap.String("code", onedrive.Code), zap.Any("name", "onedrive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
err := onedrive.Init(c) err := onedrive.Init(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Initialization failure" notify["message"] = "Initialization failure"
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "onedrive")) logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "onedrive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
username, driveId, driveType, err := onedrive.GetInfo(c) username, driveId, driveType, err := onedrive.GetInfo(ctx.Request().Context())
if err != nil { if err != nil {
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get user information" notify["message"] = "Failed to get user information"
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "onedrive")) logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "onedrive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
dmap := make(map[string]string) dmap := make(map[string]string)
dmap["username"] = username dmap["username"] = username
configs, err := service.MyService.Storage().GetConfig() configs, err := service.MyService.Storage().GetConfig()
if err != nil { if err != nil {
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`) ctx.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
notify["status"] = "fail" notify["status"] = "fail"
notify["message"] = "Failed to get rclone config" notify["message"] = "Failed to get rclone config"
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "onedrive")) logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "onedrive"))
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
for _, v := range configs.Remotes { for _, v := range configs.Remotes {
cf, err := service.MyService.Storage().GetConfigByName(v) cf, err := service.MyService.Storage().GetConfigByName(v)
@ -239,7 +226,7 @@ func GetRecoverStorage(c *gin.Context) {
continue continue
} }
if cf["type"] == "onedrive" && cf["username"] == dmap["username"] { if cf["type"] == "onedrive" && cf["username"] == dmap["username"] {
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`) ctx.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
err := service.MyService.Storage().CheckAndMountByName(v) err := service.MyService.Storage().CheckAndMountByName(v)
if err != nil { if err != nil {
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"])) logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
@ -248,7 +235,6 @@ func GetRecoverStorage(c *gin.Context) {
notify["status"] = "warn" notify["status"] = "warn"
notify["message"] = "The same configuration has been added" notify["message"] = "The same configuration has been added"
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
return
} }
} }
if len(username) > 0 { if len(username) > 0 {
@ -271,7 +257,7 @@ func GetRecoverStorage(c *gin.Context) {
// data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`) // data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`)
// e = data.Save() // e = data.Save()
// if e != nil { // if e != nil {
// c.String(200, `<p>保存配置失败:`+e.Error()+`</p>`) // return ctx.String(200, `<p>保存配置失败:`+e.Error()+`</p>`)
// return // return
// } // }
@ -284,5 +270,5 @@ func GetRecoverStorage(c *gin.Context) {
service.MyService.Notify().SendNotify("casaos:file:recover", notify) service.MyService.Notify().SendNotify("casaos:file:recover", notify)
} }
c.String(200, `<p>Just close the page</p><script>window.close()</script>`) return ctx.String(200, `<p>Just close the page</p><script>window.close()</script>`)
} }

View File

@ -20,6 +20,7 @@ import (
"github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
"github.com/IceWhaleTech/CasaOS-Common/utils/systemctl" "github.com/IceWhaleTech/CasaOS-Common/utils/systemctl"
"github.com/labstack/echo/v4"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
@ -28,18 +29,16 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/gin-gonic/gin"
) )
// service // service
func GetSambaStatus(c *gin.Context) { func GetSambaStatus(ctx echo.Context) error {
if status, err := systemctl.IsServiceRunning("smbd"); err != nil || !status { if status, err := systemctl.IsServiceRunning("smbd"); err != nil || !status {
c.JSON(http.StatusInternalServerError, model.Result{ return ctx.JSON(http.StatusInternalServerError, model.Result{
Success: common_err.SERVICE_NOT_RUNNING, Success: common_err.SERVICE_NOT_RUNNING,
Message: common_err.GetMsg(common_err.SERVICE_NOT_RUNNING), Message: common_err.GetMsg(common_err.SERVICE_NOT_RUNNING),
}) })
return
} }
needInit := true needInit := true
@ -51,10 +50,10 @@ func GetSambaStatus(c *gin.Context) {
} }
data := make(map[string]string, 1) data := make(map[string]string, 1)
data["need_init"] = fmt.Sprintf("%v", needInit) data["need_init"] = fmt.Sprintf("%v", needInit)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }
func GetSambaSharesList(c *gin.Context) { func GetSambaSharesList(ctx echo.Context) error {
shares := service.MyService.Shares().GetSharesList() shares := service.MyService.Shares().GetSharesList()
shareList := []model.Shares{} shareList := []model.Shares{}
for _, v := range shares { for _, v := range shares {
@ -64,28 +63,24 @@ func GetSambaSharesList(c *gin.Context) {
ID: v.ID, ID: v.ID,
}) })
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList})
} }
func PostSambaSharesCreate(c *gin.Context) { func PostSambaSharesCreate(ctx echo.Context) error {
shares := []model.Shares{} shares := []model.Shares{}
c.ShouldBindJSON(&shares) ctx.Bind(&shares)
for _, v := range shares { for _, v := range shares {
if v.Path == "" { if v.Path == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
} }
if !file.Exists(v.Path) { if !file.Exists(v.Path) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
return
} }
if len(service.MyService.Shares().GetSharesByPath(v.Path)) > 0 { if len(service.MyService.Shares().GetSharesByPath(v.Path)) > 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)})
return
} }
if len(service.MyService.Shares().GetSharesByPath(filepath.Base(v.Path))) > 0 { if len(service.MyService.Shares().GetSharesByPath(filepath.Base(v.Path))) > 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_NAME_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_NAME_ALREADY_EXISTS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_NAME_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_NAME_ALREADY_EXISTS)})
return
} }
} }
for _, v := range shares { for _, v := range shares {
@ -97,21 +92,20 @@ func PostSambaSharesCreate(c *gin.Context) {
service.MyService.Shares().CreateShare(shareDBModel) service.MyService.Shares().CreateShare(shareDBModel)
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares})
} }
func DeleteSambaShares(c *gin.Context) { func DeleteSambaShares(ctx echo.Context) error {
id := c.Param("id") id := ctx.Param("id")
if id == "" { if id == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
} }
service.MyService.Shares().DeleteShare(id) service.MyService.Shares().DeleteShare(id)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
} }
// client // client
func GetSambaConnectionsList(c *gin.Context) { func GetSambaConnectionsList(ctx echo.Context) error {
connections := service.MyService.Connections().GetConnectionsList() connections := service.MyService.Connections().GetConnectionsList()
connectionList := []model.Connections{} connectionList := []model.Connections{}
for _, v := range connections { for _, v := range connections {
@ -123,34 +117,33 @@ func GetSambaConnectionsList(c *gin.Context) {
MountPoint: v.MountPoint, MountPoint: v.MountPoint,
}) })
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
} }
func PostSambaConnectionsCreate(c *gin.Context) { func PostSambaConnectionsCreate(ctx echo.Context) error {
connection := model.Connections{} connection := model.Connections{}
c.ShouldBindJSON(&connection) ctx.Bind(&connection)
if connection.Port == "" { if connection.Port == "" {
connection.Port = "445" connection.Port = "445"
} }
if connection.Username == "" || connection.Host == "" { if connection.Username == "" || connection.Host == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
return
} }
// if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Password); !ok { // if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Password); !ok {
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)}) // return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
// return // return
// } // }
// if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Username); !ok { // if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Username); !ok {
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
// return // return
// } // }
// if !ip_helper.IsIPv4(connection.Host) && !ip_helper.IsIPv6(connection.Host) { // if !ip_helper.IsIPv4(connection.Host) && !ip_helper.IsIPv6(connection.Host) {
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
// return // return
// } // }
// if ok, _ := regexp.MatchString("^[0-9]{1,6}$", connection.Port); !ok { // if ok, _ := regexp.MatchString("^[0-9]{1,6}$", connection.Port); !ok {
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
// return // return
// } // }
@ -158,14 +151,12 @@ func PostSambaConnectionsCreate(c *gin.Context) {
// check is exists // check is exists
connections := service.MyService.Connections().GetConnectionByHost(connection.Host) connections := service.MyService.Connections().GetConnectionByHost(connection.Host)
if len(connections) > 0 { if len(connections) > 0 {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)})
return
} }
// check connect is ok // check connect is ok
directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password) directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
connectionDBModel := model2.ConnectionsDBModel{} connectionDBModel := model2.ConnectionsDBModel{}
@ -187,21 +178,19 @@ func PostSambaConnectionsCreate(c *gin.Context) {
service.MyService.Connections().CreateConnection(&connectionDBModel) service.MyService.Connections().CreateConnection(&connectionDBModel)
connection.ID = connectionDBModel.ID connection.ID = connectionDBModel.ID
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection})
} }
func DeleteSambaConnections(c *gin.Context) { func DeleteSambaConnections(ctx echo.Context) error {
id := c.Param("id") id := ctx.Param("id")
connection := service.MyService.Connections().GetConnectionByID(id) connection := service.MyService.Connections().GetConnectionByID(id)
if connection.Username == "" { if connection.Username == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)}) return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)})
return
} }
mountPointList, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password) mountPointList, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
// mountPointList, err := service.MyService.System().GetDirPath(connection.MountPoint) // mountPointList, err := service.MyService.System().GetDirPath(connection.MountPoint)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
baseHostPath := "/mnt/" + connection.Host baseHostPath := "/mnt/" + connection.Host
for _, v := range mountPointList { for _, v := range mountPointList {
@ -209,16 +198,14 @@ func DeleteSambaConnections(c *gin.Context) {
err := service.MyService.Connections().UnmountSmaba(baseHostPath + "/" + v) err := service.MyService.Connections().UnmountSmaba(baseHostPath + "/" + v)
if err != nil { if err != nil {
logger.Error("unmount smaba error", zap.Error(err), zap.Any("path", baseHostPath+"/"+v)) logger.Error("unmount smaba error", zap.Error(err), zap.Any("path", baseHostPath+"/"+v))
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
return
} }
} }
} }
dir, _ := ioutil.ReadDir(connection.MountPoint) dir, _ := ioutil.ReadDir(connection.MountPoint)
if len(dir) == 0 { if len(dir) == 0 {
os.RemoveAll(connection.MountPoint) os.RemoveAll(connection.MountPoint)
} }
service.MyService.Connections().DeleteConnection(id) service.MyService.Connections().DeleteConnection(id)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
} }

View File

@ -16,8 +16,8 @@ import (
"testing" "testing"
v1 "github.com/IceWhaleTech/CasaOS/route/v1" v1 "github.com/IceWhaleTech/CasaOS/route/v1"
"github.com/gin-gonic/gin"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/labstack/echo/v4"
"gotest.tools/assert" "gotest.tools/assert"
) )
@ -54,17 +54,22 @@ func performRequest(r http.Handler, method, path string) *httptest.ResponseRecor
func TestGetSambaSharesList(t *testing.T) { func TestGetSambaSharesList(t *testing.T) {
t.Skip("This test is always failing. Skipped to unblock releasing - MUST FIX!") t.Skip("This test is always failing. Skipped to unblock releasing - MUST FIX!")
gin.SetMode(gin.TestMode)
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
defer ctrl.Finish() defer ctrl.Finish()
executeWithContext := func() *httptest.ResponseRecorder { executeWithContext := func() *httptest.ResponseRecorder {
response := httptest.NewRecorder() response := httptest.NewRecorder()
con, ginEngine := gin.CreateTestContext(response) // con, ginEngine := gin.CreateTestContext(response)
e := echo.New()
requestUrl := "/v1/samba/shares" requestUrl := "/v1/samba/shares"
httpRequest, _ := http.NewRequest("GET", requestUrl, nil) httpRequest, _ := http.NewRequest("GET", requestUrl, nil)
con := e.NewContext(httpRequest, response)
v1.GetSambaSharesList(con) v1.GetSambaSharesList(con)
ginEngine.ServeHTTP(response, httpRequest) e.ServeHTTP(response, httpRequest)
return response return response
} }

View File

@ -10,8 +10,9 @@ import (
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err" "github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
"github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
sshHelper "github.com/IceWhaleTech/CasaOS-Common/utils/ssh" sshHelper "github.com/IceWhaleTech/CasaOS-Common/utils/ssh"
"github.com/IceWhaleTech/CasaOS/pkg/utils"
"github.com/labstack/echo/v4"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -26,44 +27,41 @@ var upgrader = websocket.Upgrader{
HandshakeTimeout: time.Duration(time.Second * 5), HandshakeTimeout: time.Duration(time.Second * 5),
} }
func PostSshLogin(c *gin.Context) { func PostSshLogin(ctx echo.Context) error {
j := make(map[string]string) j := make(map[string]string)
c.ShouldBind(&j) ctx.Bind(&j)
userName := j["username"] userName := j["username"]
password := j["password"] password := j["password"]
port := j["port"] port := j["port"]
if userName == "" || password == "" || port == "" { if userName == "" || password == "" || port == "" {
c.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"}) return ctx.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"})
return
} }
_, err := sshHelper.NewSshClient(userName, password, port) _, err := sshHelper.NewSshClient(userName, password, port)
if err != nil { if err != nil {
c.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."}) return ctx.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."})
logger.Error("connect ssh error", zap.Any("error", err)) logger.Error("connect ssh error", zap.Any("error", err))
return
} }
c.JSON(common_err.SUCCESS, modelCommon.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, modelCommon.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
func WsSsh(c *gin.Context) { func WsSsh(ctx echo.Context) error {
_, e := exec.LookPath("ssh") _, e := exec.LookPath("ssh")
if e != nil { if e != nil {
c.JSON(common_err.SERVICE_ERROR, modelCommon.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"}) return ctx.JSON(common_err.SERVICE_ERROR, modelCommon.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"})
return
} }
userName := c.Query("username") userName := ctx.QueryParam("username")
password := c.Query("password") password := ctx.QueryParam("password")
port := c.Query("port") port := ctx.QueryParam("port")
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil) wsConn, _ := upgrader.Upgrade(ctx.Response().Writer, ctx.Request(), nil)
logBuff := new(bytes.Buffer) logBuff := new(bytes.Buffer)
quitChan := make(chan bool, 3) quitChan := make(chan bool, 3)
// user := "" // user := ""
// password := "" // password := ""
var login int = 1 var login int = 1
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200")) cols, _ := strconv.Atoi(utils.DefaultQuery(ctx, "cols", "200"))
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32")) rows, _ := strconv.Atoi(utils.DefaultQuery(ctx, "rows", "32"))
var client *ssh.Client var client *ssh.Client
for login != 0 { for login != 0 {
@ -93,4 +91,5 @@ func WsSsh(c *gin.Context) {
go ssConn.SessionWait(quitChan) go ssConn.SessionWait(quitChan)
<-quitChan <-quitChan
return nil
} }

View File

@ -19,12 +19,13 @@ import (
"github.com/IceWhaleTech/CasaOS/common" "github.com/IceWhaleTech/CasaOS/common"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/version" "github.com/IceWhaleTech/CasaOS/pkg/utils/version"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model" model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types" "github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
) )
@ -35,7 +36,7 @@ import (
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/version/check [get] // @Router /sys/version/check [get]
func GetSystemCheckVersion(c *gin.Context) { func GetSystemCheckVersion(ctx echo.Context) error {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion()) need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
if need { if need {
installLog := model2.AppNotify{} installLog := model2.AppNotify{}
@ -51,7 +52,7 @@ func GetSystemCheckVersion(c *gin.Context) {
data["need_update"] = need data["need_update"] = need
data["version"] = version data["version"] = version
data["current_version"] = common.VERSION data["current_version"] = common.VERSION
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }
// @Summary 系统信息 // @Summary 系统信息
@ -61,12 +62,12 @@ func GetSystemCheckVersion(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/update [post] // @Router /sys/update [post]
func SystemUpdate(c *gin.Context) { func SystemUpdate(ctx echo.Context) error {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion()) need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
if need { if need {
service.MyService.System().UpdateSystemVersion(version.Version) service.MyService.System().UpdateSystemVersion(version.Version)
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
} }
// @Summary get logs // @Summary get logs
@ -76,13 +77,13 @@ func SystemUpdate(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/error/logs [get] // @Router /sys/error/logs [get]
func GetCasaOSErrorLogs(c *gin.Context) { func GetCasaOSErrorLogs(ctx echo.Context) error {
line, _ := strconv.Atoi(c.DefaultQuery("line", "100")) line, _ := strconv.Atoi(utils.DefaultQuery(ctx, "line", "100"))
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
} }
// 系统配置 // 系统配置
func GetSystemConfigDebug(c *gin.Context) { func GetSystemConfigDebug(ctx echo.Context) error {
array := service.MyService.System().GetSystemConfigDebug() array := service.MyService.System().GetSystemConfigDebug()
disk := service.MyService.System().GetDiskInfo() disk := service.MyService.System().GetDiskInfo()
sys := service.MyService.System().GetSysInfo() sys := service.MyService.System().GetSysInfo()
@ -100,7 +101,7 @@ func GetSystemConfigDebug(c *gin.Context) {
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent)) // array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
} }
// @Summary get casaos server port // @Summary get casaos server port
@ -110,8 +111,8 @@ func GetSystemConfigDebug(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/port [get] // @Router /sys/port [get]
func GetCasaOSPort(c *gin.Context) { func GetCasaOSPort(ctx echo.Context) error {
c.JSON(common_err.SUCCESS, return ctx.JSON(common_err.SUCCESS,
model.Result{ model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS), Message: common_err.GetMsg(common_err.SUCCESS),
@ -127,31 +128,29 @@ func GetCasaOSPort(c *gin.Context) {
// @Param port json string true "port" // @Param port json string true "port"
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/port [put] // @Router /sys/port [put]
func PutCasaOSPort(c *gin.Context) { func PutCasaOSPort(ctx echo.Context) error {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) ctx.Bind(&json)
portStr := json["port"] portStr := json["port"]
portNumber, err := strconv.Atoi(portStr) portNumber, err := strconv.Atoi(portStr)
if err != nil { if err != nil {
c.JSON(common_err.SERVICE_ERROR, return ctx.JSON(common_err.SERVICE_ERROR,
model.Result{ model.Result{
Success: common_err.SERVICE_ERROR, Success: common_err.SERVICE_ERROR,
Message: err.Error(), Message: err.Error(),
}) })
return
} }
isAvailable := port.IsPortAvailable(portNumber, "tcp") isAvailable := port.IsPortAvailable(portNumber, "tcp")
if !isAvailable { if !isAvailable {
c.JSON(common_err.SERVICE_ERROR, return ctx.JSON(common_err.SERVICE_ERROR,
model.Result{ model.Result{
Success: common_err.PORT_IS_OCCUPIED, Success: common_err.PORT_IS_OCCUPIED,
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED), Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
}) })
return
} }
service.MyService.System().UpSystemPort(strconv.Itoa(portNumber)) service.MyService.System().UpSystemPort(strconv.Itoa(portNumber))
c.JSON(common_err.SUCCESS, return ctx.JSON(common_err.SUCCESS,
model.Result{ model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS), Message: common_err.GetMsg(common_err.SUCCESS),
@ -165,8 +164,9 @@ func PutCasaOSPort(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/restart [post] // @Router /sys/restart [post]
func PostKillCasaOS(c *gin.Context) { func PostKillCasaOS(ctx echo.Context) error {
os.Exit(0) os.Exit(0)
return nil
} }
// @Summary get system hardware info // @Summary get system hardware info
@ -176,20 +176,20 @@ func PostKillCasaOS(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/hardware/info [get] // @Router /sys/hardware/info [get]
func GetSystemHardwareInfo(c *gin.Context) { func GetSystemHardwareInfo(ctx echo.Context) error {
data := make(map[string]string, 1) data := make(map[string]string, 1)
data["drive_model"] = service.MyService.System().GetDeviceTree() data["drive_model"] = service.MyService.System().GetDeviceTree()
data["arch"] = runtime.GOARCH data["arch"] = runtime.GOARCH
if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 { if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
return ctx.JSON(common_err.SUCCESS,
c.JSON(common_err.SUCCESS,
model.Result{ model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS), Message: common_err.GetMsg(common_err.SUCCESS),
Data: data, Data: data,
}) })
} }
return nil
} }
// @Summary system utilization // @Summary system utilization
@ -199,7 +199,7 @@ func GetSystemHardwareInfo(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/utilization [get] // @Router /sys/utilization [get]
func GetSystemUtilization(c *gin.Context) { func GetSystemUtilization(ctx echo.Context) error {
data := make(map[string]interface{}) data := make(map[string]interface{})
cpu := service.MyService.System().GetCpuPercent() cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum() num := service.MyService.System().GetCpuCoreNum()
@ -243,7 +243,7 @@ func GetSystemUtilization(c *gin.Context) {
data[key.(string)] = value data[key.(string)] = value
return true return true
}) })
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }
// @Summary get cpu info // @Summary get cpu info
@ -253,13 +253,13 @@ func GetSystemUtilization(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/cpu [get] // @Router /sys/cpu [get]
func GetSystemCupInfo(c *gin.Context) { func GetSystemCupInfo(ctx echo.Context) error {
cpu := service.MyService.System().GetCpuPercent() cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum() num := service.MyService.System().GetCpuCoreNum()
data := make(map[string]interface{}) data := make(map[string]interface{})
data["percent"] = cpu data["percent"] = cpu
data["num"] = num data["num"] = num
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }
// @Summary get mem info // @Summary get mem info
@ -269,9 +269,9 @@ func GetSystemCupInfo(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/mem [get] // @Router /sys/mem [get]
func GetSystemMemInfo(c *gin.Context) { func GetSystemMemInfo(ctx echo.Context) error {
mem := service.MyService.System().GetMemInfo() mem := service.MyService.System().GetMemInfo()
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
} }
// @Summary get disk info // @Summary get disk info
@ -281,9 +281,9 @@ func GetSystemMemInfo(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/disk [get] // @Router /sys/disk [get]
func GetSystemDiskInfo(c *gin.Context) { func GetSystemDiskInfo(ctx echo.Context) error {
disk := service.MyService.System().GetDiskInfo() disk := service.MyService.System().GetDiskInfo()
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
} }
// @Summary get Net info // @Summary get Net info
@ -293,7 +293,7 @@ func GetSystemDiskInfo(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /sys/net [get] // @Router /sys/net [get]
func GetSystemNetInfo(c *gin.Context) { func GetSystemNetInfo(ctx echo.Context) error {
netList := service.MyService.System().GetNetInfo() netList := service.MyService.System().GetNetInfo()
newNet := []model.IOCountersStat{} newNet := []model.IOCountersStat{}
for _, n := range netList { for _, n := range netList {
@ -308,35 +308,36 @@ func GetSystemNetInfo(c *gin.Context) {
} }
} }
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
} }
func GetSystemProxy(c *gin.Context) { func GetSystemProxy(ctx echo.Context) error {
url := c.Query("url") url := ctx.QueryParam("url")
resp, err := http2.Get(url, 30*time.Second) resp, err := http2.Get(url, 30*time.Second)
if err != nil { if err != nil {
return return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
} }
defer resp.Body.Close() defer resp.Body.Close()
for k, v := range c.Request.Header { for k, v := range ctx.Request().Header {
c.Header(k, v[0]) ctx.Request().Header.Add(k, v[0])
} }
rda, _ := ioutil.ReadAll(resp.Body) rda, _ := ioutil.ReadAll(resp.Body)
// json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda))) // json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda)))
// 响应状态码 // 响应状态码
c.Writer.WriteHeader(resp.StatusCode) ctx.Response().Writer.WriteHeader(resp.StatusCode)
// 复制转发的响应Body到响应Body // 复制转发的响应Body到响应Body
io.Copy(c.Writer, ioutil.NopCloser(bytes.NewBuffer(rda))) io.Copy(ctx.Response().Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
return nil
} }
func PutSystemState(c *gin.Context) { func PutSystemState(ctx echo.Context) error {
state := c.Param("state") state := ctx.Param("state")
if strings.ToLower(state) == "off" { if strings.ToLower(state) == "off" {
service.MyService.System().SystemShutdown() service.MyService.System().SystemShutdown()
} else if strings.ToLower(state) == "restart" { } else if strings.ToLower(state) == "restart" {
service.MyService.System().SystemReboot() service.MyService.System().SystemReboot()
} }
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
} }
// @Summary 获取一个可用端口 // @Summary 获取一个可用端口
@ -347,8 +348,8 @@ func PutSystemState(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /app/getport [get] // @Router /app/getport [get]
func GetPort(c *gin.Context) { func GetPort(ctx echo.Context) error {
t := c.DefaultQuery("type", "tcp") t := utils.DefaultQuery(ctx, "type", "tcp")
var p int var p int
ok := true ok := true
for ok { for ok {
@ -356,7 +357,7 @@ func GetPort(c *gin.Context) {
ok = !port.IsPortAvailable(p, t) ok = !port.IsPortAvailable(p, t)
} }
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文 // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p}) return ctx.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
} }
// @Summary 检查端口是否可用 // @Summary 检查端口是否可用
@ -368,18 +369,17 @@ func GetPort(c *gin.Context) {
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /app/check/{port} [get] // @Router /app/check/{port} [get]
func PortCheck(c *gin.Context) { func PortCheck(ctx echo.Context) error {
p, _ := strconv.Atoi(c.Param("port")) p, _ := strconv.Atoi(ctx.Param("port"))
t := c.DefaultQuery("type", "tcp") t := utils.DefaultQuery(ctx, "type", "tcp")
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)}) return ctx.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
} }
func GetSystemEntry(c *gin.Context) { func GetSystemEntry(ctx echo.Context) error {
entry := service.MyService.System().GetSystemEntry() entry := service.MyService.System().GetSystemEntry()
str := json.RawMessage(entry) str := json.RawMessage(entry)
if !gjson.ValidBytes(str) { if !gjson.ValidBytes(str) {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")}) return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")})
return
} }
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str}) return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str})
} }

View File

@ -12,19 +12,18 @@ import (
"github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
"github.com/IceWhaleTech/CasaOS/common" "github.com/IceWhaleTech/CasaOS/common"
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper" "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"go.uber.org/zap" "go.uber.org/zap"
) )
func ZerotierProxy(c *gin.Context) { func ZerotierProxy(ctx echo.Context) error {
// Read the port number from the file // Read the port number from the file
w := c.Writer w := ctx.Response().Writer
r := c.Request r := ctx.Request()
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port") port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
// Get the request path and remove "/zt" // Get the request path and remove "/zt"
@ -38,14 +37,12 @@ func ZerotierProxy(c *gin.Context) {
req, err := http.NewRequest(r.Method, targetURL, r.Body) req, err := http.NewRequest(r.Method, targetURL, r.Body)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
// Add the X-ZT1-AUTH header // Add the X-ZT1-AUTH header
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret") authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken))) req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
@ -55,7 +52,6 @@ func ZerotierProxy(c *gin.Context) {
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -64,12 +60,13 @@ func ZerotierProxy(c *gin.Context) {
respBody, err := ioutil.ReadAll(resp.Body) respBody, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
// Return the response to the client // Return the response to the client
w.WriteHeader(resp.StatusCode) w.WriteHeader(resp.StatusCode)
w.Write(respBody) w.Write(respBody)
// TODO
return nil
} }
func copyHeaders(destination, source http.Header) { func copyHeaders(destination, source http.Header) {
@ -130,6 +127,7 @@ func CheckNetwork() {
JoinAndUpdateNet(address, networkId, ip) JoinAndUpdateNet(address, networkId, ip)
} }
} }
func GetAddress() string { func GetAddress() string {
nodeRes, err := httper.ZTGet("/status") nodeRes, err := httper.ZTGet("/status")
if err != nil { if err != nil {
@ -138,6 +136,7 @@ func GetAddress() string {
} }
return gjson.GetBytes(nodeRes, "address").String() return gjson.GetBytes(nodeRes, "address").String()
} }
func JoinAndUpdateNet(address, networkId, ip string) { func JoinAndUpdateNet(address, networkId, ip string) {
logger.Info("start join network", zap.Any("ip", ip)) logger.Info("start join network", zap.Any("ip", ip))
_, err := httper.ZTPost("/network/"+networkId, "") _, err := httper.ZTPost("/network/"+networkId, "")
@ -162,6 +161,7 @@ func JoinAndUpdateNet(address, networkId, ip string) {
return return
} }
} }
func CreateNet(address, s, e, c string) string { func CreateNet(address, s, e, c string) string {
body := `{ body := `{
"name": "` + common.RANW_NAME + `", "name": "` + common.RANW_NAME + `",

View File

@ -72,7 +72,6 @@ func InitV2Router() http.Handler {
Skipper: func(c echo.Context) bool { Skipper: func(c echo.Context) bool {
return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1" return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1"
// return true // return true
}, },
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) { ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) }) valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
@ -84,11 +83,11 @@ func InitV2Router() http.Handler {
return claims, nil return claims, nil
}, },
TokenLookupFuncs: []echo_middleware.ValuesExtractor{ TokenLookupFuncs: []echo_middleware.ValuesExtractor{
func(c echo.Context) ([]string, error) { func(ctx echo.Context) ([]string, error) {
if len(c.Request().Header.Get(echo.HeaderAuthorization)) > 0 { if len(ctx.Request().Header.Get(echo.HeaderAuthorization)) > 0 {
return []string{c.Request().Header.Get(echo.HeaderAuthorization)}, nil return []string{ctx.Request().Header.Get(echo.HeaderAuthorization)}, nil
} }
return []string{c.QueryParam("token")}, nil return []string{ctx.QueryParam("token")}, nil
}, },
}, },
})) }))
@ -202,7 +201,7 @@ func InitDir() http.Handler {
list := strings.Split(files, ",") list := strings.Split(files, ",")
for _, v := range list { for _, v := range list {
if !file.Exists(v) { if !file.Exists(v) {
// c.JSON(common_err.SERVICE_ERROR, model.Result{ // return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
// Success: common_err.FILE_DOES_NOT_EXIST, // Success: common_err.FILE_DOES_NOT_EXIST,
// Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), // Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
// }) // })
@ -238,7 +237,7 @@ func InitDir() http.Handler {
err = ar.Create(w) err = ar.Create(w)
if err != nil { if err != nil {
// c.JSON(common_err.SERVICE_ERROR, model.Result{ // return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
// Success: common_err.SERVICE_ERROR, // Success: common_err.SERVICE_ERROR,
// Message: common_err.GetMsg(common_err.SERVICE_ERROR), // Message: common_err.GetMsg(common_err.SERVICE_ERROR),
// Data: err.Error(), // Data: err.Error(),