Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/mountlib/mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ full new copy of the file.
When mounting with `--read-only`, attempts to write to files will fail *silently*
as opposed to with a clear warning as in macFUSE.

## Mounting on Linux
### Mounting on Linux

On newer versions of Ubuntu, you may encounter the following error when running
`rclone mount`:
Expand Down
Binary file added cmd/serve/http/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions cmd/serve/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package http

import (
"context"
_ "embed"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -57,6 +58,9 @@ var DefaultOpt = Options{
// Opt is options set by command line flags
var Opt = DefaultOpt

//go:embed favicon.png
var faviconData []byte

func init() {
fs.RegisterGlobalOptions(fs.OptionsInfo{Name: "http", Opt: &Opt, Options: OptionsInfo})
}
Expand Down Expand Up @@ -201,6 +205,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
middleware.SetHeader("Accept-Ranges", "bytes"),
middleware.SetHeader("Server", "rclone/"+fs.Version),
)
router.Get("/favicon.ico", s.serveFavicon)
router.Get("/*", s.handler)
router.Head("/*", s.handler)

Expand All @@ -225,6 +230,27 @@ func (s *HTTP) Shutdown() error {
return s.server.Shutdown()
}

// serveFavicon serves the remote's favicon.ico if it exists, otherwise
// the rclone favicon
func (s *HTTP) serveFavicon(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
VFS, err := s.getVFS(ctx)
if err == nil {
node, err := VFS.Stat("favicon.ico")
if err == nil && node.IsFile() {
// Remote has favicon.ico, serve it as a regular file
s.serveFile(w, r, "favicon.ico")
return
}
}
// Serve the embedded rclone favicon
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Cache-Control", "max-age=86400")
if _, err := w.Write(faviconData); err != nil {
fs.Debugf(nil, "Failed to write favicon: %v", err)
}
}

// handler reads incoming requests and dispatches them
func (s *HTTP) handler(w http.ResponseWriter, r *http.Request) {
isDir := strings.HasSuffix(r.URL.Path, "/")
Expand Down
50 changes: 50 additions & 0 deletions cmd/serve/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,56 @@ func TestAuthProxy(t *testing.T) {
testGET(t, true)
}

func TestFavicon(t *testing.T) {
ctx := context.Background()

doGet := func(testURL, path string) *http.Response {
req, err := http.NewRequest("GET", testURL+path, nil)
require.NoError(t, err)
req.SetBasicAuth(testUser, testPass)
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
return resp
}

t.Run("fallback", func(t *testing.T) {
// testdata/files has no favicon.ico, so the embedded fallback is served
f, err := fs.NewFs(ctx, "testdata/files")
require.NoError(t, err)
s, testURL := start(ctx, t, f)
defer func() { assert.NoError(t, s.server.Shutdown()) }()

resp := doGet(testURL, "favicon.ico")
defer func() { _ = resp.Body.Close() }()
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, "image/png", resp.Header.Get("Content-Type"))
assert.Equal(t, "max-age=86400", resp.Header.Get("Cache-Control"))
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, faviconData, body)
})

t.Run("remote override", func(t *testing.T) {
// Start a server on a temp dir that already contains a custom favicon.ico,
// so the VFS sees it at init time and serves it instead of the fallback.
dir := t.TempDir()
customFavicon := []byte("custom favicon data")
require.NoError(t, os.WriteFile(filepath.Join(dir, "favicon.ico"), customFavicon, 0666))

f, err := fs.NewFs(ctx, dir)
require.NoError(t, err)
s, testURL := start(ctx, t, f)
defer func() { assert.NoError(t, s.server.Shutdown()) }()

resp := doGet(testURL, "favicon.ico")
defer func() { _ = resp.Body.Close() }()
assert.Equal(t, http.StatusOK, resp.StatusCode)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, customFavicon, body)
})
}

func TestRc(t *testing.T) {
servetest.TestRc(t, rc.Params{
"type": "http",
Expand Down
Binary file modified docs/static/img/ncw-bitcoin-address.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/static/img/rclone-1200x630.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/static/img/rclone-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/cover.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/favicon/favicon_16px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/favicon/favicon_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_on_dark__horizontal_color_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_on_dark__horizontal_mono_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_on_dark__vertical_color_64px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_on_dark__vertical_mono_64px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_symbol_on_dark_mono_128px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_symbol_on_dark_mono_256px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/logo/logo_on_dark/logo_symbol_on_dark_mono_512px.png
Binary file modified graphics/logo/logo_on_dark/logo_symbol_on_dark_mono_64px.png
Binary file modified graphics/logo/logo_on_light/logo_on_light__vertical_color_64px.png
Binary file modified graphics/logo/logo_on_light/logo_on_light__vertical_mono_64px.png
Binary file modified graphics/logo/logo_on_light/logo_symbol_on_light_mono_128px.png
Binary file modified graphics/logo/logo_on_light/logo_symbol_on_light_mono_256px.png
Binary file modified graphics/logo/logo_on_light/logo_symbol_on_light_mono_512px.png
Binary file modified graphics/logo/logo_on_light/logo_symbol_on_light_mono_64px.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_128px.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_16px.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_256px.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_512px.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_600px_spaced.png
Binary file modified graphics/logo/logo_symbol/logo_symbol_color_64px.png