mirror of
https://github.com/rclone/rclone.git
synced 2024-12-23 07:29:35 +01:00
http: Replace httplib with lib/http
This commit is contained in:
parent
77221d7528
commit
5d2e327b6f
@ -1,7 +1,9 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -9,19 +11,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/rclone/rclone/cmd"
|
"github.com/rclone/rclone/cmd"
|
||||||
"github.com/rclone/rclone/cmd/serve/httplib"
|
"github.com/rclone/rclone/cmd/serve/http/data"
|
||||||
"github.com/rclone/rclone/cmd/serve/httplib/httpflags"
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/accounting"
|
"github.com/rclone/rclone/fs/accounting"
|
||||||
|
httplib "github.com/rclone/rclone/lib/http"
|
||||||
|
"github.com/rclone/rclone/lib/http/auth"
|
||||||
"github.com/rclone/rclone/lib/http/serve"
|
"github.com/rclone/rclone/lib/http/serve"
|
||||||
"github.com/rclone/rclone/vfs"
|
"github.com/rclone/rclone/vfs"
|
||||||
"github.com/rclone/rclone/vfs/vfsflags"
|
"github.com/rclone/rclone/vfs/vfsflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options required for http server
|
||||||
|
type Options struct {
|
||||||
|
data.Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultOpt is the default values used for Options
|
||||||
|
var DefaultOpt = Options{}
|
||||||
|
|
||||||
|
// Opt is options set by command line flags
|
||||||
|
var Opt = DefaultOpt
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
httpflags.AddFlags(Command.Flags())
|
data.AddFlags(Command.Flags(), "", &Opt.Options)
|
||||||
|
httplib.AddFlags(Command.Flags())
|
||||||
|
auth.AddFlags(Command.Flags())
|
||||||
vfsflags.AddFlags(Command.Flags())
|
vfsflags.AddFlags(Command.Flags())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,17 +57,17 @@ The server will log errors. Use -v to see access logs.
|
|||||||
|
|
||||||
--bwlimit will be respected for file transfers. Use --stats to
|
--bwlimit will be respected for file transfers. Use --stats to
|
||||||
control the stats printing.
|
control the stats printing.
|
||||||
` + httplib.Help + vfs.Help,
|
` + httplib.Help + data.Help + auth.Help + vfs.Help,
|
||||||
Run: func(command *cobra.Command, args []string) {
|
Run: func(command *cobra.Command, args []string) {
|
||||||
cmd.CheckArgs(1, 1, command, args)
|
cmd.CheckArgs(1, 1, command, args)
|
||||||
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, Opt.Template)
|
||||||
err := s.Serve()
|
router, err := httplib.Router()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Wait()
|
s.Bind("/*", router)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -58,49 +75,38 @@ control the stats printing.
|
|||||||
|
|
||||||
// server contains everything to run the server
|
// server contains everything to run the server
|
||||||
type server struct {
|
type server struct {
|
||||||
*httplib.Server
|
f fs.Fs
|
||||||
f fs.Fs
|
vfs *vfs.VFS
|
||||||
vfs *vfs.VFS
|
HTMLTemplate *template.Template // HTML template for web interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(f fs.Fs, opt *httplib.Options) *server {
|
func newServer(f fs.Fs, templatePath string) *server {
|
||||||
mux := http.NewServeMux()
|
htmlTemplate, templateErr := data.GetTemplate(templatePath)
|
||||||
s := &server{
|
if templateErr != nil {
|
||||||
Server: httplib.NewServer(mux, opt),
|
log.Fatalf(templateErr.Error())
|
||||||
f: f,
|
}
|
||||||
vfs: vfs.New(f, &vfsflags.Opt),
|
s := &server{
|
||||||
|
f: f,
|
||||||
|
vfs: vfs.New(f, &vfsflags.Opt),
|
||||||
|
HTMLTemplate: htmlTemplate,
|
||||||
}
|
}
|
||||||
mux.HandleFunc(s.Opt.BaseURL+"/", s.handler)
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve runs the http server in the background.
|
func (s *server) Bind(pattern string, router chi.Router) {
|
||||||
//
|
router.Get(pattern, s.handler)
|
||||||
// Use s.Close() and s.Wait() to shutdown server
|
router.Head(pattern, s.handler)
|
||||||
func (s *server) Serve() error {
|
|
||||||
err := s.Server.Serve()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fs.Logf(s.f, "Serving on %s", s.URL())
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handler reads incoming requests and dispatches them
|
// handler reads incoming requests and dispatches them
|
||||||
func (s *server) handler(w http.ResponseWriter, r *http.Request) {
|
func (s *server) handler(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "GET" && r.Method != "HEAD" {
|
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set("Accept-Ranges", "bytes")
|
w.Header().Set("Accept-Ranges", "bytes")
|
||||||
w.Header().Set("Server", "rclone/"+fs.Version)
|
w.Header().Set("Server", "rclone/"+fs.Version)
|
||||||
|
|
||||||
urlPath, ok := s.Path(w, r)
|
//rctx := chi.RouteContext(r.Context())
|
||||||
if !ok {
|
|
||||||
return
|
isDir := strings.HasSuffix(r.URL.Path, "/")
|
||||||
}
|
remote := strings.Trim(r.URL.Path, "/")
|
||||||
isDir := strings.HasSuffix(urlPath, "/")
|
|
||||||
remote := strings.Trim(urlPath, "/")
|
|
||||||
if isDir {
|
if isDir {
|
||||||
s.serveDir(w, r, remote)
|
s.serveDir(w, r, remote)
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,10 +10,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
_ "github.com/rclone/rclone/backend/local"
|
_ "github.com/rclone/rclone/backend/local"
|
||||||
"github.com/rclone/rclone/cmd/serve/httplib"
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/config/configfile"
|
"github.com/rclone/rclone/fs/config/configfile"
|
||||||
"github.com/rclone/rclone/fs/filter"
|
"github.com/rclone/rclone/fs/filter"
|
||||||
|
httplib "github.com/rclone/rclone/lib/http"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -32,10 +32,13 @@ const (
|
|||||||
func startServer(t *testing.T, f fs.Fs) {
|
func startServer(t *testing.T, f fs.Fs) {
|
||||||
opt := httplib.DefaultOpt
|
opt := httplib.DefaultOpt
|
||||||
opt.ListenAddr = testBindAddress
|
opt.ListenAddr = testBindAddress
|
||||||
opt.Template = testTemplate
|
httpServer = newServer(f, testTemplate)
|
||||||
httpServer = newServer(f, &opt)
|
router, err := httplib.Router()
|
||||||
assert.NoError(t, httpServer.Serve())
|
if err != nil {
|
||||||
testURL = httpServer.Server.URL()
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
httpServer.Bind("/*", router)
|
||||||
|
testURL = httplib.URL()
|
||||||
|
|
||||||
// try to connect to the test server
|
// try to connect to the test server
|
||||||
pause := time.Millisecond
|
pause := time.Millisecond
|
||||||
@ -227,6 +230,5 @@ func TestGET(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFinalise(t *testing.T) {
|
func TestFinalise(t *testing.T) {
|
||||||
httpServer.Close()
|
_ = httplib.Shutdown()
|
||||||
httpServer.Wait()
|
|
||||||
}
|
}
|
||||||
|
2
cmd/serve/http/testdata/golden/indexpost.txt
vendored
2
cmd/serve/http/testdata/golden/indexpost.txt
vendored
@ -1 +1 @@
|
|||||||
Method not allowed
|
Method Not Allowed
|
||||||
|
2
cmd/serve/http/testdata/golden/onepost.txt
vendored
2
cmd/serve/http/testdata/golden/onepost.txt
vendored
@ -1 +1 @@
|
|||||||
Method not allowed
|
Method Not Allowed
|
||||||
|
Loading…
Reference in New Issue
Block a user