repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
97adfeb
parent
ee10b32
author
Antonio Mika
date
2022-08-24 20:03:01 +0000 UTC
Cleanup update logic and update to go 1.19
12 files changed,  +81, -74
M go.mod
M go.sum
M Dockerfile
+1, -1
1@@ -1,4 +1,4 @@
2-FROM --platform=$BUILDPLATFORM golang:1.18-alpine as builder-deps
3+FROM --platform=$BUILDPLATFORM golang:1.19-alpine as builder-deps
4 LABEL maintainer="Pico Maintainers <hello@pico.sh>"
5 
6 ENV CGO_ENABLED 0
M README.md
+2, -2
 1@@ -16,8 +16,8 @@ This repo hosts the following pico services:
 2 
 3 ## development
 4 
 5-- `golang` >= 1.18
 6-- `direnv` to load environment vars 
 7+- `golang` >= 1.19
 8+- `direnv` to load environment vars
 9 
10 ```bash
11 cp ./.env.example .env
M cmd/imgs/ssh/main.go
+7, -16
 1@@ -9,7 +9,7 @@ import (
 2 	"time"
 3 
 4 	"git.sr.ht/~erock/pico/db/postgres"
 5-	"git.sr.ht/~erock/pico/filehandlers/imgs"
 6+	uploadimgs "git.sr.ht/~erock/pico/filehandlers/imgs"
 7 	"git.sr.ht/~erock/pico/imgs"
 8 	"git.sr.ht/~erock/pico/imgs/storage"
 9 	"git.sr.ht/~erock/pico/shared"
10@@ -35,22 +35,13 @@ func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
11 
12 func createRouter(cfg *shared.ConfigSite, handler utils.CopyFromClientHandler) proxy.Router {
13 	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
14-		cmd := s.Command()
15-		mdw := []wish.Middleware{}
16-
17-		if len(cmd) > 0 && cmd[0] == "scp" {
18-			mdw = append(mdw, scp.Middleware(handler))
19-		} else if len(cmd) > 0 && cmd[0] == "rsync" {
20-			mdw = append(mdw, wishrsync.Middleware(handler))
21-		} else {
22-			mdw = append(mdw,
23-				pipe.Middleware(handler, ""),
24-				bm.Middleware(cms.Middleware(&cfg.ConfigCms, cfg)),
25-				lm.Middleware(),
26-			)
27+		return []wish.Middleware{
28+			pipe.Middleware(handler, ""),
29+			scp.Middleware(handler),
30+			wishrsync.Middleware(handler),
31+			bm.Middleware(cms.Middleware(&cfg.ConfigCms, cfg)),
32+			lm.Middleware(),
33 		}
34-
35-		return mdw
36 	}
37 }
38 
M cmd/lists/ssh/main.go
+6, -15
 1@@ -33,22 +33,13 @@ func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 2 
 3 func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 4 	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 5-		cmd := s.Command()
 6-		mdw := []wish.Middleware{}
 7-
 8-		if len(cmd) > 0 && cmd[0] == "scp" {
 9-			mdw = append(mdw, scp.Middleware(handler))
10-		} else if len(cmd) > 0 && cmd[0] == "rsync" {
11-			mdw = append(mdw, wishrsync.Middleware(handler))
12-		} else {
13-			mdw = append(mdw,
14-				pipe.Middleware(handler, ".txt"),
15-				bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
16-				lm.Middleware(),
17-			)
18+		return []wish.Middleware{
19+			pipe.Middleware(handler, ".txt"),
20+			scp.Middleware(handler),
21+			wishrsync.Middleware(handler),
22+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
23+			lm.Middleware(),
24 		}
25-
26-		return mdw
27 	}
28 }
29 
M cmd/pastes/ssh/main.go
+6, -15
 1@@ -33,22 +33,13 @@ func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 2 
 3 func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 4 	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 5-		cmd := s.Command()
 6-		mdw := []wish.Middleware{}
 7-
 8-		if len(cmd) > 0 && cmd[0] == "scp" {
 9-			mdw = append(mdw, scp.Middleware(handler))
10-		} else if len(cmd) > 0 && cmd[0] == "rsync" {
11-			mdw = append(mdw, wishrsync.Middleware(handler))
12-		} else {
13-			mdw = append(mdw,
14-				pipe.Middleware(handler, ""),
15-				bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
16-				lm.Middleware(),
17-			)
18+		return []wish.Middleware{
19+			pipe.Middleware(handler, ""),
20+			scp.Middleware(handler),
21+			wishrsync.Middleware(handler),
22+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
23+			lm.Middleware(),
24 		}
25-
26-		return mdw
27 	}
28 }
29 
M cmd/prose/ssh/main.go
+6, -15
 1@@ -33,22 +33,13 @@ func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 2 
 3 func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 4 	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 5-		cmd := s.Command()
 6-		mdw := []wish.Middleware{}
 7-
 8-		if len(cmd) > 0 && cmd[0] == "scp" {
 9-			mdw = append(mdw, scp.Middleware(handler))
10-		} else if len(cmd) > 0 && cmd[0] == "rsync" {
11-			mdw = append(mdw, wishrsync.Middleware(handler))
12-		} else {
13-			mdw = append(mdw,
14-				pipe.Middleware(handler, ".md"),
15-				bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
16-				lm.Middleware(),
17-			)
18+		return []wish.Middleware{
19+			pipe.Middleware(handler, ".md"),
20+			scp.Middleware(handler),
21+			wishrsync.Middleware(handler),
22+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
23+			lm.Middleware(),
24 		}
25-
26-		return mdw
27 	}
28 }
29 
M go.mod
+9, -7
 1@@ -1,6 +1,6 @@
 2 module git.sr.ht/~erock/pico
 3 
 4-go 1.18
 5+go 1.19
 6 
 7 // replace git.sr.ht/~erock/pico/wish => /home/erock/pico/wish
 8 // replace github.com/antoniomika/go-rsync-receiver => /home/erock/pico/go-rsync-receiver
 9@@ -10,7 +10,7 @@ require (
10 	github.com/antoniomika/go-rsync-receiver v0.0.0-20220817204644-b0fcbb706c46
11 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
12 	github.com/charmbracelet/bubbles v0.13.0
13-	github.com/charmbracelet/bubbletea v0.22.0
14+	github.com/charmbracelet/bubbletea v0.22.1
15 	github.com/charmbracelet/lipgloss v0.5.0
16 	github.com/charmbracelet/promwish v0.2.0
17 	github.com/charmbracelet/wish v0.5.0
18@@ -24,9 +24,9 @@ require (
19 	github.com/yuin/goldmark v1.4.13
20 	github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
21 	github.com/yuin/goldmark-meta v1.1.0
22-	go.uber.org/zap v1.22.0
23-	golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8
24-	golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
25+	go.uber.org/zap v1.23.0
26+	golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503
27+	golang.org/x/exp v0.0.0-20220823124025-807a23277127
28 )
29 
30 require (
31@@ -46,6 +46,7 @@ require (
32 	github.com/kr/fs v0.1.0 // indirect
33 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
34 	github.com/mattn/go-isatty v0.0.16 // indirect
35+	github.com/mattn/go-localereader v0.0.1 // indirect
36 	github.com/mattn/go-runewidth v0.0.13 // indirect
37 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
38 	github.com/mitchellh/go-homedir v1.1.0 // indirect
39@@ -60,9 +61,10 @@ require (
40 	github.com/rivo/uniseg v0.3.4 // indirect
41 	go.uber.org/atomic v1.10.0 // indirect
42 	go.uber.org/multierr v1.8.0 // indirect
43-	golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
44-	golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect
45+	golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c // indirect
46+	golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 // indirect
47 	golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
48+	golang.org/x/text v0.3.7 // indirect
49 	google.golang.org/protobuf v1.28.1 // indirect
50 	gopkg.in/yaml.v2 v2.4.0 // indirect
51 )
M go.sum
+15, -0
 1@@ -68,6 +68,8 @@ github.com/charmbracelet/bubbles v0.13.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWo
 2 github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4=
 3 github.com/charmbracelet/bubbletea v0.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc=
 4 github.com/charmbracelet/bubbletea v0.22.0/go.mod h1:aoVIwlNlr5wbCB26KhxfrqAn0bMp4YpJcoOelbxApjs=
 5+github.com/charmbracelet/bubbletea v0.22.1 h1:z66q0LWdJNOWEH9zadiAIXp2GN1AWrwNXU8obVY9X24=
 6+github.com/charmbracelet/bubbletea v0.22.1/go.mod h1:8/7hVvbPN6ZZPkczLiB8YpLkLJ0n7DMho5Wvfd2X1C0=
 7 github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
 8 github.com/charmbracelet/keygen v0.3.0 h1:mXpsQcH7DDlST5TddmXNXjS0L7ECk4/kLQYyBcsan2Y=
 9 github.com/charmbracelet/keygen v0.3.0/go.mod h1:1ukgO8806O25lUZ5s0IrNur+RlwTBERlezdgW71F5rM=
10@@ -201,6 +203,8 @@ github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwM
11 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
12 github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
13 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
14+github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
15+github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
16 github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
17 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
18 github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
19@@ -307,6 +311,8 @@ go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
20 go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
21 go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
22 go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
23+go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
24+go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
25 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
26 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
27 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
28@@ -317,6 +323,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
29 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
30 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
31 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
32+golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 h1:vJ2V3lFLg+bBhgroYuRfyN583UzVveQmIXjc8T/y3to=
33+golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
34 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
35 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
36 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
37@@ -329,6 +337,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
38 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
39 golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
40 golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
41+golang.org/x/exp v0.0.0-20220823124025-807a23277127 h1:S4NrSKDfihhl3+4jSTgwoIevKxX9p7Iv9x++OEIptDo=
42+golang.org/x/exp v0.0.0-20220823124025-807a23277127/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
43 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
44 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
45 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
46@@ -384,6 +394,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
47 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
48 golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
49 golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
50+golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes=
51+golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
52 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
53 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
54 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
55@@ -445,6 +457,8 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc
56 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
57 golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 h1:fqTvyMIIj+HRzMmnzr9NtpHP6uVpvB5fkHcgPDC4nu8=
58 golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
59+golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 h1:TyKJRhyo17yWxOMCTHKWrc5rddHORMlnZ/j57umaUd8=
60+golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
61 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
62 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
63 golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc=
64@@ -455,6 +469,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
65 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
66 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
67 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
68+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
69 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
70 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
71 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
M wish/cmd/server/main.go
+12, -0
 1@@ -2,7 +2,9 @@ package main
 2 
 3 import (
 4 	"fmt"
 5+	"io"
 6 	"log"
 7+	"strings"
 8 
 9 	"git.sr.ht/~erock/pico/wish/send"
10 	"git.sr.ht/~erock/pico/wish/send/utils"
11@@ -25,6 +27,16 @@ func (h *handler) Validate(session ssh.Session) error {
12 	return nil
13 }
14 
15+func (h *handler) Read(session ssh.Session, file *utils.FileEntry) (io.Reader, error) {
16+	log.Printf("Received validate from session: %+v", session)
17+
18+	return strings.NewReader("lorem ipsum dolor"), nil
19+}
20+
21+func (h *handler) List(session ssh.Session) ([]string, error) {
22+	return nil, nil
23+}
24+
25 func main() {
26 	h := &handler{}
27 
M wish/send/rsync/rsync.go
+6, -0
 1@@ -46,6 +46,12 @@ func (h *handler) Put(fileName string, content io.Reader, fileSize int64, mTime
 2 func Middleware(writeHandler utils.CopyFromClientHandler) wish.Middleware {
 3 	return func(sshHandler ssh.Handler) ssh.Handler {
 4 		return func(session ssh.Session) {
 5+			cmd := session.Command()
 6+			if len(cmd) == 0 || cmd[0] != "rsync" {
 7+				sshHandler(session)
 8+				return
 9+			}
10+
11 			err := writeHandler.Validate(session)
12 			if err != nil {
13 				utils.ErrorHandler(session, err)
M wish/send/scp/scp.go
+8, -2
 1@@ -11,14 +11,20 @@ import (
 2 func Middleware(writeHandler utils.CopyFromClientHandler) wish.Middleware {
 3 	return func(sshHandler ssh.Handler) ssh.Handler {
 4 		return func(session ssh.Session) {
 5-			info := GetInfo(session.Command())
 6+			cmd := session.Command()
 7+			if len(cmd) == 0 || cmd[0] != "scp" {
 8+				sshHandler(session)
 9+				return
10+			}
11+
12+			info := GetInfo(cmd)
13 			if !info.Ok {
14 				sshHandler(session)
15 				return
16 			}
17 
18 			if info.Recursive {
19-				err := fmt.Errorf("recursive not supported.\n")
20+				err := fmt.Errorf("recursive not supported")
21 				utils.ErrorHandler(session, err)
22 				return
23 			}
M wish/send/send.go
+3, -1
 1@@ -1,6 +1,8 @@
 2 package send
 3 
 4 import (
 5+	"git.sr.ht/~erock/pico/wish/pipe"
 6+	"git.sr.ht/~erock/pico/wish/send/rsync"
 7 	"git.sr.ht/~erock/pico/wish/send/scp"
 8 	"git.sr.ht/~erock/pico/wish/send/sftp"
 9 	"git.sr.ht/~erock/pico/wish/send/utils"
10@@ -10,7 +12,7 @@ import (
11 
12 func Middleware(writeHandler utils.CopyFromClientHandler) ssh.Option {
13 	return func(server *ssh.Server) error {
14-		err := wish.WithMiddleware(scp.Middleware(writeHandler))(server)
15+		err := wish.WithMiddleware(pipe.Middleware(writeHandler, ""), scp.Middleware(writeHandler), rsync.Middleware(writeHandler))(server)
16 		if err != nil {
17 			return err
18 		}