forked from TrueCloudLab/rclone
serve restic: add http2 server on stdin/stdout
This commit is contained in:
parent
f832433fa5
commit
5114b11d6f
4 changed files with 130 additions and 0 deletions
|
@ -3,9 +3,11 @@ package restic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -21,10 +23,17 @@ import (
|
||||||
"github.com/ncw/rclone/fs/operations"
|
"github.com/ncw/rclone/fs/operations"
|
||||||
"github.com/ncw/rclone/fs/walk"
|
"github.com/ncw/rclone/fs/walk"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
stdio bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
httpflags.AddFlags(Command.Flags())
|
httpflags.AddFlags(Command.Flags())
|
||||||
|
Command.Flags().BoolVar(&stdio, "stdio", false, "run an HTTP2 server on stdin/stdout")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command definition for cobra
|
// Command definition for cobra
|
||||||
|
@ -110,6 +119,24 @@ these **must** end with /. Eg
|
||||||
f := cmd.NewFsSrc(args)
|
f := cmd.NewFsSrc(args)
|
||||||
cmd.Run(false, true, command, func() error {
|
cmd.Run(false, true, command, func() error {
|
||||||
s := newServer(f, &httpflags.Opt)
|
s := newServer(f, &httpflags.Opt)
|
||||||
|
if stdio {
|
||||||
|
if terminal.IsTerminal(int(os.Stdout.Fd())) {
|
||||||
|
return errors.New("Refusing to run HTTP2 server directly on a terminal, please let restic start rclone")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := &StdioConn{
|
||||||
|
stdin: os.Stdin,
|
||||||
|
stdout: os.Stdout,
|
||||||
|
}
|
||||||
|
|
||||||
|
httpSrv := &http2.Server{}
|
||||||
|
opts := &http2.ServeConnOpts{
|
||||||
|
Handler: http.HandlerFunc(s.handler),
|
||||||
|
}
|
||||||
|
httpSrv.ServeConn(conn, opts)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
s.serve()
|
s.serve()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
54
cmd/serve/restic/stdio_conn.go
Normal file
54
cmd/serve/restic/stdio_conn.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package restic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Addr implements net.Addr for stdin/stdout.
|
||||||
|
type Addr struct{}
|
||||||
|
|
||||||
|
// Network returns the network type as a string.
|
||||||
|
func (a Addr) Network() string {
|
||||||
|
return "stdio"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Addr) String() string {
|
||||||
|
return "stdio"
|
||||||
|
}
|
||||||
|
|
||||||
|
// StdioConn implements a net.Conn via stdin/stdout.
|
||||||
|
type StdioConn struct {
|
||||||
|
stdin *os.File
|
||||||
|
stdout *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StdioConn) Read(p []byte) (int, error) {
|
||||||
|
return s.stdin.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StdioConn) Write(p []byte) (int, error) {
|
||||||
|
return s.stdout.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes both streams.
|
||||||
|
func (s *StdioConn) Close() error {
|
||||||
|
log.Printf("Server.Close()\n")
|
||||||
|
err1 := s.stdin.Close()
|
||||||
|
err2 := s.stdout.Close()
|
||||||
|
if err1 != nil {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalAddr returns nil.
|
||||||
|
func (s *StdioConn) LocalAddr() net.Addr {
|
||||||
|
return Addr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteAddr returns nil.
|
||||||
|
func (s *StdioConn) RemoteAddr() net.Addr {
|
||||||
|
return Addr{}
|
||||||
|
}
|
27
cmd/serve/restic/stdio_conn_go1.10.go
Normal file
27
cmd/serve/restic/stdio_conn_go1.10.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//+build go1.10
|
||||||
|
|
||||||
|
// Deadline setting for go1.10+
|
||||||
|
|
||||||
|
package restic
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// SetDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetDeadline(t time.Time) error {
|
||||||
|
err1 := s.stdin.SetReadDeadline(t)
|
||||||
|
err2 := s.stdout.SetWriteDeadline(t)
|
||||||
|
if err1 != nil {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReadDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetReadDeadline(t time.Time) error {
|
||||||
|
return s.stdin.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetWriteDeadline(t time.Time) error {
|
||||||
|
return s.stdout.SetWriteDeadline(t)
|
||||||
|
}
|
22
cmd/serve/restic/stdio_conn_pre_go1.10.go
Normal file
22
cmd/serve/restic/stdio_conn_pre_go1.10.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//+build !go1.10
|
||||||
|
|
||||||
|
// Fallback deadline setting for pre go1.10
|
||||||
|
|
||||||
|
package restic
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// SetDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReadDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetReadDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline sets the read/write deadline.
|
||||||
|
func (s *StdioConn) SetWriteDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue