Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented a web server to browse a repository (snapshots, files) #4276

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

ducalex
Copy link
Contributor

@ducalex ducalex commented Mar 29, 2023

What does this PR change? What problem does it solve?

It adds a web server to browse a repository (snapshots, files). Overall it is a very simple patch and requires no additional dependencies but it might be very useful for people who can't use fuse mount.

It allows to browse snapshots, view files, and cherry pick files to download an archive.

Usage: restic -r repo serve and open your web browser to http://localhost:3080/

demo.2.mp4

Was the change previously discussed in an issue or on the forum?

It is related to #60 but after reading the discussion I don't know if this PR would be enough to close it.

Checklist

  • I have read the contribution guidelines.
  • I have enabled maintainer edits.
  • I have added tests for all code changes.
  • I have added documentation for relevant changes (in the manual).
  • There's a new file in changelog/unreleased/ that describes the changes for our users (see template).
  • I have run gofmt on the code in all commits.
  • All commit messages are formatted in the same style as the other commits in the repo.
  • I'm done! This pull request is ready for review.

@rawtaz
Copy link
Contributor

rawtaz commented Mar 29, 2023

I like the idea. I've actually started the very same thing myself a while ago. Nothing to show though.

@ducalex
Copy link
Contributor Author

ducalex commented Apr 2, 2023

I like the idea. I've actually started the very same thing myself a while ago. Nothing to show though.

I think I've now accomplished everything I wanted for this PR! Seems to work pretty well so far.

Do you mind having a quick look at the code to see if I did something obviously stupid before I undraft it?

Copy link
Contributor

@Enrico204 Enrico204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting feature! LGTM!

cmd/restic/cmd_serve.go Outdated Show resolved Hide resolved
cmd/restic/cmd_serve.go Outdated Show resolved Hide resolved
Comment on lines 237 to 251
<link rel="stylesheet" href="/style.css">
<title>{{.Title}} :: restic</title>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm, what about adding viewport meta tags, so that mobile browsers are happy?
https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag

<meta name="viewport" content="width=device-width, initial-scale=1" />

I haven't tested the current code, though.

@ducalex ducalex marked this pull request as ready for review April 7, 2023 20:55
@ducalex
Copy link
Contributor Author

ducalex commented May 5, 2023

Anyone willing to review? I'm happy to make any changes needed.

@isarrider
Copy link

This will be awesome for usability - Thank you @ducalex

@isarrider
Copy link

is there an update for the review?
It would increase the family compability by a lot ;)

@ducalex
Copy link
Contributor Author

ducalex commented Aug 1, 2023

is there an update for the review? It would increase the family compability by a lot ;)

It's been 5 months so clearly not a priority or maybe my particular implementation is beyond salvaging? Would be nice to have an answer from a maintainer either way! I'm still available to complete the work once a direction has been chosen.

@zanna-37
Copy link

@MichaelEischer any chances this can be reviewed? I tested it and works well. It would be a great improvement for windows users that cannot mount the repo easily.

I was able to rebase it quickly without knowledge of Go or restic, so pretty straightforward to integrate.
Thank you very much.

@fd0
Copy link
Member

fd0 commented Apr 11, 2024

I like this approach a lot! Before we can get this merged (and the implementation to handle HTML files correctly and fixes the XSS issue I've discovered by briefly testing it), the challenges mentioned in #4754 need to be addressed. :)

@ducalex
Copy link
Contributor Author

ducalex commented Apr 13, 2024

I like this approach a lot! Before we can get this merged (and the implementation to handle HTML files correctly and fixes the XSS issue I've discovered by briefly testing it), the challenges mentioned in #4754 need to be addressed. :)

I think it's reasonable to delay the addition of WebDAV until you're done with your work and my quick draft clearly isn't production-worthy!

But, depending on the timeline you have in mind, it might still be worth merging this web server PR. Adding a random token to the URL and forcing html/svg to render as text/plain should negate any potential XSS issues.

I can appreciate that you have a vision and my implementation might not fit. But perhaps you can reshape my code into something that you can live with until your better version comes out?

I hope I do not come across as pushy, I just think we're really overdue for a convenient way to browse snapshots!

@fd0
Copy link
Member

fd0 commented Apr 15, 2024

I can appreciate that you have a vision and my implementation might not fit. But perhaps you can reshape my code into something that you can live with until your better version comes out?

Yes, that's something we can indeed do. Especially if we just need to swap out the backend implementation, that's quite easy to do and won't be noticed by users at all.

I hope I do not come across as pushy, I just think we're really overdue for a convenient way to browse snapshots!

For my personal use fuse was sufficient, but I can understand that it's inconvenient on macOS and not available on Windows, so I can see your need!

So, from my point of view we can start tackling the web server in parallel to the WebDAV server (and unify them once the latter is merged). The access control layer (e.g. a random password or so) we can even build in the context of the web server and then also use for the WebDAV server as well.

I can think of the following that needs to be done:

  • Build an access control layer
  • Move the code for the server to a new package below internal/restic somewhere, so that within the cmd_serve.go the server is only configured and run
  • Split the code for the server that handles serving blobs and the website that is returned
  • Embed the templates using the suggested embed functionality (that's really easy to do!)

Please let me know how we should split the work, I'd like to contribute. :)

@ducalex
Copy link
Contributor Author

ducalex commented Apr 22, 2024

I can certainly split the code and add an authentication layer that can be shared by the servers, do something like:

package server:
    internal/server/auth.go         some shared authenticator that handles .htpasswd, maybe like rest-server?
    internal/server/web.go          the current server (html)
    internal/server/webdav.go    the webdav server

Not quite sure about naming. I also don't quite know where to put the HTML templates, internal/server/assets?

Otherwise feel free to take the lead and lay down the structure that you have in mind!

@fd0
Copy link
Member

fd0 commented Apr 25, 2024

I've started reworking the server but then ran out of time (for today). It does not work yet, I'll need to debug this next.

@fd0
Copy link
Member

fd0 commented Apr 26, 2024

The server works now, I've split it out into its own package (directory) and embedded the assets, which are stored in their own files now.

Copy link
Member

@MichaelEischer MichaelEischer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few random remarks from my side.

cmd/restic/cmd_serve.go Outdated Show resolved Hide resolved
internal/server/assets/fs.go Outdated Show resolved Hide resolved
}

mux.HandleFunc("/tree/", func(rw http.ResponseWriter, req *http.Request) {
snapshotID, curPath, _ := strings.Cut(req.URL.Path[6:], "/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path surgery can be replaced with https://pkg.go.dev/net/http#StripPrefix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants