http: Replace httplib with lib/http

This commit is contained in:
Nolan Woods 2021-04-19 22:14:21 -07:00 committed by Nick Craig-Wood
parent 77221d7528
commit 5d2e327b6f
4 changed files with 54 additions and 46 deletions

View File

@ -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 {

View File

@ -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()
} }

View File

@ -1 +1 @@
Method not allowed Method Not Allowed

View File

@ -1 +1 @@
Method not allowed Method Not Allowed