Skip to content

Commit

Permalink
merge http into rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
nasdf committed Mar 2, 2021
1 parent 51eb6c6 commit 501c970
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 188 deletions.
2 changes: 0 additions & 2 deletions pkg/command/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"os"
"os/signal"

"github.com/multiverse-vcs/go-multiverse/pkg/http"
"github.com/multiverse-vcs/go-multiverse/pkg/remote"
"github.com/multiverse-vcs/go-multiverse/pkg/rpc"
"github.com/nasdf/ulimit"
Expand Down Expand Up @@ -41,7 +40,6 @@ func NewDaemonCommand() *cli.Command {
return err
}

go http.ListenAndServe(server)
go rpc.ListenAndServe(server)

fmt.Printf(Banner)
Expand Down
106 changes: 0 additions & 106 deletions pkg/http/http.go

This file was deleted.

40 changes: 0 additions & 40 deletions pkg/http/util.go

This file was deleted.

10 changes: 10 additions & 0 deletions pkg/rpc/file/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package file

import (
"github.com/multiverse-vcs/go-multiverse/pkg/remote"
)

// Service wraps a remote and provides RPC.
type Service struct {
*remote.Server
}
70 changes: 41 additions & 29 deletions pkg/http/file.go → pkg/rpc/file/search.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,56 @@
package http
package file

import (
"encoding/json"
"context"
"errors"
"net/http"
"strings"

path "github.com/ipfs/go-path"
unixfs "github.com/ipfs/go-unixfs"
"github.com/julienschmidt/httprouter"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/multiverse-vcs/go-multiverse/pkg/fs"
"github.com/multiverse-vcs/go-multiverse/pkg/object"
)

// File returns file contents from the repository tree.
func (s *Server) File(w http.ResponseWriter, req *http.Request) error {
ctx := req.Context()
// SearchArgs contains the args.
type SearchArgs struct {
// Remote is the remote path.
Remote string
// Branch is the branch name.
Branch string
// Path is the file path.
Path string
}

// SearchReply contains the reply.
type SearchReply struct {
// Content contains file content.
Content string
// Entries contains directory entries.
Entries []*fs.DirEntry
// IsDir specifies if the file is a directory.
IsDir bool
}

// Search returns the contents of a file at the given remote path.
func (s *Service) Search(args *SearchArgs, reply *SearchReply) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

parts := strings.Split(args.Remote, "/")
if len(parts) != 2 {
return errors.New("invalid remote path")
}

highlight := req.URL.Query().Get("highlight")
params := httprouter.ParamsFromContext(ctx)
pname := params.ByName("peer")
rname := params.ByName("repo")
bname := params.ByName("branch")
fname := params.ByName("file")
pname := parts[0]
rname := parts[1]

peerID, err := peer.Decode(pname)
if err != nil {
return err
}

authorID, err := s.Namesys.Resolve(ctx, peerID)
authorID, err := s.Namesys.Search(ctx, peerID)
if err != nil {
return err
}
Expand All @@ -49,12 +70,12 @@ func (s *Server) File(w http.ResponseWriter, req *http.Request) error {
return err
}

head, ok := repo.Branches[bname]
head, ok := repo.Branches[args.Branch]
if !ok {
return errors.New("branch does not exist")
}

fpath, err := path.FromSegments("/ipfs/", head.String(), "tree", fname)
fpath, err := path.FromSegments("/ipfs/", head.String(), "tree", args.Path)
if err != nil {
return err
}
Expand All @@ -76,25 +97,16 @@ func (s *Server) File(w http.ResponseWriter, req *http.Request) error {
return err
}

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(tree)
case highlight != "":
blob, err := fs.Cat(ctx, s.Peer.DAG, fnode.Cid())
if err != nil {
return err
}

w.Header().Set("Content-Type", "text/html")
Highlight(fname, blob, highlight, w)
reply.Entries = tree
default:
blob, err := fs.Cat(ctx, s.Peer.DAG, fnode.Cid())
if err != nil {
return err
}

w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(blob))
reply.Content = blob
}

reply.IsDir = fsnode.IsDir()
return nil
}
}
57 changes: 46 additions & 11 deletions pkg/rpc/rpc.go
Original file line number Diff line number Diff line change
@@ -1,55 +1,90 @@
package rpc

import (
"io"
"log"
"net"
"net/http"
"net/rpc"
"net/rpc/jsonrpc"
"os"
"path/filepath"

"github.com/multiverse-vcs/go-multiverse/pkg/remote"
"github.com/multiverse-vcs/go-multiverse/pkg/rpc/author"
"github.com/multiverse-vcs/go-multiverse/pkg/rpc/file"
"github.com/multiverse-vcs/go-multiverse/pkg/rpc/repo"
)

// SockFile is the name of the unix socket file.
const SockFile = "rpc.sock"

// DialErrMsg is an error message for failed RPC connections.
var DialErrMsg = `
Could not connect to local RPC server.
Make sure the Multiverse daemon is up.
See 'multi help daemon' for more info.
`

// HttpConn wraps an HTTP request.
type HttpConn struct {
r io.Reader
w io.Writer
}

// Read reads bytes from the reader.
func (c *HttpConn) Read(p []byte) (n int, err error) {
return c.r.Read(p)
}

// Write writes bytes to the writer.
func (c *HttpConn) Write(d []byte) (n int, err error) {
return c.w.Write(d)
}

// Close does nothing.
func (c *HttpConn) Close() error {
return nil
}

// NewClient returns a new RPC client.
func NewClient() (*rpc.Client, error) {
home, err := os.UserHomeDir()
if err != nil {
return nil, err
}

config := remote.NewConfig(filepath.Join(home, remote.DotDir))
if err := config.Read(); err != nil {
return nil, err
}

socket := filepath.Join(home, remote.DotDir, SockFile)
return rpc.DialHTTP("unix", socket)
return rpc.DialHTTP("tcp", config.HttpAddress)
}

// ListenAndServe starts the RPC listener.
func ListenAndServe(server *remote.Server) error {
socket := filepath.Join(server.Root, SockFile)
if err := os.RemoveAll(socket); err != nil {
return err
}

rpc.RegisterName("Author", &author.Service{server})
rpc.RegisterName("File", &file.Service{server})
rpc.RegisterName("Repo", &repo.Service{server})

rpc.HandleHTTP()
http.HandleFunc("/_jsonRPC_", ServeHTTP)

listener, err := net.Listen("unix", socket)
listener, err := net.Listen("tcp", server.Config.HttpAddress)
if err != nil {
log.Fatal(err)
}
defer listener.Close()

return http.Serve(listener, nil)
}

// ServeHTTP serves json rpc connections over http.
func ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.WriteHeader(http.StatusOK)

if req.Method == http.MethodPost {
jsonrpc.ServeConn(&HttpConn{req.Body, w})
}
}

0 comments on commit 501c970

Please sign in to comment.