Skip to content

Commit

Permalink
feat: handle absolute and relative paths as expected (#32)
Browse files Browse the repository at this point in the history
* feat: use zap everywhere

* bugfix: handle absolute and relative paths as expected (#31)

* chore: ignore .vscode folder

* feat: handle absolute and relative paths as expected

Previous behavior would take the absolute or relative path and
expand the directory structure onto the receiver. This is not what
one expects when for instance sending files using the absolute path
"portal send /home/zinokader/data/somefile.txt", which previously would
actually try to recreate the same directory structure "/home/zinokader..."
on the receiver end.

Now, we handle absolute paths by sending the last directory or file
(and its subfiles/subdirectories), this means "/home/zinokader/folder"
will just send and expand "folder" and all of its contents on the receiving end.
  • Loading branch information
ZinoKader committed Jan 18, 2023
1 parent 138e937 commit 3f0c93c
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
# misc
.DS_Store
dist/
.vscode
10 changes: 8 additions & 2 deletions internal/conn/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package conn
import (
"context"
"errors"
"log"
"net/http"

"github.com/SpatiumPortae/portal/internal/logger"
"go.uber.org/zap"
"nhooyr.io/websocket"
)

Expand All @@ -26,9 +27,14 @@ func FromContext(ctx context.Context) (Conn, error) {
func Middleware() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger, err := logger.FromContext(ctx)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
wsConn, err := websocket.Accept(w, r, &websocket.AcceptOptions{InsecureSkipVerify: true})
if err != nil {
log.Println("failed to upgrade connection:", err)
logger.Error("failed to upgrade connection", zap.Error(err))
return
}
next.ServeHTTP(w, r.WithContext(WithConn(r.Context(), &WS{Conn: wsConn})))
Expand Down
22 changes: 18 additions & 4 deletions internal/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,17 @@ func FilesTotalSize(files []*os.File) (int64, error) {
return size, nil
}

// addToTarArchive adds a file/folder to a tar archive. This function handles symlinks by replacing
// them with the files that they point to
// addToTarArchive adds a file/folder to a tar archive.
// Handles symlinks by replacing them with the files that they point to.
func addToTarArchive(tw *tar.Writer, file *os.File) error {
return filepath.Walk(file.Name(), func(path string, fi os.FileInfo, err error) error {
var absoluteBase string
absPath, err := filepath.Abs(file.Name())
if err != nil {
return err
}
absoluteBase = filepath.Dir(absPath)

return filepath.Walk(file.Name(), func(path string, fi os.FileInfo, err error) error {
if (fi.Mode() & os.ModeSymlink) == os.ModeSymlink {
// read path that the symlink is pointing to
var link string
Expand All @@ -165,7 +171,15 @@ func addToTarArchive(tw *tar.Writer, file *os.File) error {
if e != nil {
return err
}
header.Name = filepath.ToSlash(path)

// use absolute paths to handle both relative and absolute input paths identically
targetPath, err := filepath.Abs(path)
if err != nil {
return err
}
// remove the absolute root from the filename, leaving only the desired filename
header.Name = filepath.ToSlash(strings.TrimPrefix(targetPath, absoluteBase))
header.Name = strings.TrimPrefix(header.Name, string(os.PathSeparator))

if err := tw.WriteHeader(header); err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions internal/rendezvous/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (s *Server) handleEstablishSender() http.HandlerFunc {
}
rc := conn.Rendezvous{Conn: c}

// Bind an ID to this communication and send ot to the sender
// Bind an ID to this communication and send to to the sender
id := s.ids.Bind()
defer func() { s.ids.Delete(id) }()
err = rc.WriteMsg(rendezvous.Msg{
Expand Down Expand Up @@ -110,7 +110,7 @@ func (s *Server) handleEstablishSender() http.HandlerFunc {
}
}

// handleEstablishReceiver returns a websocket handler that that communicates with the sender.
// handleEstablishReceiver returns a websocket handler that communicates with the sender.
func (s *Server) handleEstablishReceiver() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
logger, err := logger.FromContext(r.Context())
Expand Down
2 changes: 1 addition & 1 deletion internal/rendezvous/mailbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (mailboxes *Mailboxes) StoreMailbox(p string, m *Mailbox) {
mailboxes.Store(p, m)
}

// GetMailbox returns the decired mailbox.
// GetMailbox returns the desired mailbox.
func (mailboxes *Mailboxes) GetMailbox(p string) (*Mailbox, error) {
mailbox, ok := mailboxes.Load(p)
if !ok {
Expand Down
5 changes: 4 additions & 1 deletion internal/rendezvous/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@ type Server struct {
// NewServer constructs a new Server struct and setups the routes.
func NewServer(port int) *Server {
router := &mux.Router{}
lgr := logger.New()
stdLoggerWrapper, _ := zap.NewStdLogAt(lgr, zap.ErrorLevel)
s := &Server{
httpServer: &http.Server{
Addr: fmt.Sprintf(":%d", port),
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
Handler: router,
ErrorLog: stdLoggerWrapper,
},
router: router,
mailboxes: &Mailboxes{&sync.Map{}},
ids: &IDs{&sync.Map{}},
logger: logger.New(),
logger: lgr,
}
s.routes()
return s
Expand Down

0 comments on commit 3f0c93c

Please sign in to comment.