Add support for copying files and folders.

This commit is contained in:
2021-12-19 14:31:57 +01:00
parent 161cb79b88
commit 311339685c
450 changed files with 232338 additions and 3 deletions

19
vendor/github.com/jaschaephraim/lrserver/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2014-2015 Jascha Ephraim
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

114
vendor/github.com/jaschaephraim/lrserver/README.md generated vendored Normal file
View File

@ -0,0 +1,114 @@
# `lrserver` LiveReload server for Go #
Golang package that implements a simple LiveReload server as described in the [LiveReload protocol](http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol).
Using the recommended default port 35729:
- `http://localhost:35729/livereload.js` serves the LiveReload client JavaScript (https://github.com/livereload/livereload-js)
- `ws://localhost:35729/livereload` communicates with the client via web socket.
File watching must be implemented by your own application, and reload/alert
requests sent programmatically.
Multiple servers can be instantiated, and each can support multiple connections.
## Full Documentation: [![GoDoc](https://godoc.org/github.com/jaschaephraim/lrserver?status.svg)](http://godoc.org/github.com/jaschaephraim/lrserver) ##
## Basic Usage ##
### Get Package ###
```bash
go get github.com/jaschaephraim/lrserver
```
### Import Package ###
```go
import "github.com/jaschaephraim/lrserver"
```
### Instantiate Server ###
```go
lr := lrserver.New(lrserver.DefaultName, lrserver.DefaultPort)
```
### Start Server ###
```go
go func() {
err := lr.ListenAndServe()
if err != nil {
// Handle error
}
}()
```
### Send Messages to the Browser ###
```go
lr.Reload("file")
lr.Alert("message")
```
## Example ##
```go
import (
"log"
"net/http"
"github.com/jaschaephraim/lrserver"
"gopkg.in/fsnotify.v1"
)
// html includes the client JavaScript
const html = `<!doctype html>
<html>
<head>
<title>Example</title>
</head>
<body>
<script src="http://localhost:35729/livereload.js"></script>
</body>
</html>`
func Example() {
// Create file watcher
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatalln(err)
}
defer watcher.Close()
// Add dir to watcher
err = watcher.Add("/path/to/watched/dir")
if err != nil {
log.Fatalln(err)
}
// Create and start LiveReload server
lr := lrserver.New(lrserver.DefaultName, lrserver.DefaultPort)
go lr.ListenAndServe()
// Start goroutine that requests reload upon watcher event
go func() {
for {
select {
case event := <-watcher.Events:
lr.Reload(event.Name)
case err := <-watcher.Errors:
log.Println(err)
}
}
}()
// Start serving html
http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(html))
})
http.ListenAndServe(":3000", nil)
}
```

162
vendor/github.com/jaschaephraim/lrserver/connection.go generated vendored Normal file
View File

@ -0,0 +1,162 @@
package lrserver
import (
"encoding/json"
"strconv"
"sync"
"time"
"github.com/gorilla/websocket"
)
type conn struct {
conn *websocket.Conn
server *Server
handshake bool
reloadChan chan string
alertChan chan string
closeChan chan closeSignal
}
func (c *conn) start() {
go c.receive()
go c.transmit()
// Say hello
err := c.conn.WriteJSON(makeServerHello(c.server.Name()))
if err != nil {
c.close(websocket.CloseInternalServerErr, err)
}
// Block until close signal is sent
<-c.closeChan
}
func (c *conn) receive() {
for {
// Get next message
msgType, reader, err := c.conn.NextReader()
if err != nil {
c.close(0, err)
return
}
// Close if binary instead of text
if msgType == websocket.BinaryMessage {
c.close(websocket.CloseUnsupportedData, nil)
return
}
// Close if it's not JSON
hello := new(clientHello)
err = json.NewDecoder(reader).Decode(hello)
if err != nil {
c.close(websocket.ClosePolicyViolation, err)
return
}
// Close if missing a command field
if hello.Command == "" {
c.close(websocket.ClosePolicyViolation, nil)
}
// Validate handshake
if !c.handshake {
if !validateHello(hello) {
c.badHandshake()
return
}
c.handshake = true
c.server.logStatus("connected")
}
}
}
func (c *conn) transmit() {
for {
var resp interface{}
select {
// Reload
case file := <-c.reloadChan:
if !c.handshake {
c.badHandshake()
return
}
resp = makeServerReload(file, c.server.LiveCSS())
// Alert
case msg := <-c.alertChan:
if !c.handshake {
c.badHandshake()
return
}
resp = makeServerAlert(msg)
}
err := c.conn.WriteJSON(resp)
if err != nil {
c.close(websocket.CloseInternalServerErr, err)
return
}
}
}
func (c *conn) badHandshake() {
c.close(websocket.ClosePolicyViolation, websocket.ErrBadHandshake)
}
func (c *conn) close(closeCode int, closeErr error) error {
var err error
var errMsg string
if closeErr != nil {
errMsg = closeErr.Error()
c.server.logError(closeErr)
// Attempt to set close code from error message
errMsgLen := len(errMsg)
if errMsgLen >= 21 && errMsg[:17] == "websocket: close " {
closeCode, _ = strconv.Atoi(errMsg[17:21])
if errMsgLen > 21 {
errMsg = errMsg[22:]
}
}
}
// Default close code
if closeCode == 0 {
closeCode = websocket.CloseNoStatusReceived
}
// Send close message
closeMessage := websocket.FormatCloseMessage(closeCode, errMsg)
deadline := time.Now().Add(time.Second)
err = c.conn.WriteControl(websocket.CloseMessage, closeMessage, deadline)
// Kill and remove connection
c.closeChan <- closeSignal{}
c.server.connSet.remove(c)
return err
}
type connSet struct {
conns map[*conn]struct{}
m sync.Mutex
}
func (cs *connSet) add(c *conn) {
cs.m.Lock()
cs.conns[c] = struct{}{}
cs.m.Unlock()
}
func (cs *connSet) remove(c *conn) {
cs.m.Lock()
delete(cs.conns, c)
cs.m.Unlock()
}
type closeSignal struct{}

33
vendor/github.com/jaschaephraim/lrserver/handlers.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
package lrserver
import (
"net/http"
"github.com/gorilla/websocket"
)
func jsHandler(s *Server) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Content-Type", "application/javascript")
_, err := rw.Write([]byte(s.js))
if err != nil {
s.logError(err)
}
}
}
func webSocketHandler(s *Server) http.HandlerFunc {
// Do not check origin
upgrader := websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
return func(rw http.ResponseWriter, req *http.Request) {
conn, err := upgrader.Upgrade(rw, req, nil)
if err != nil {
s.logError(err)
return
}
s.newConn(conn)
}
}

1206
vendor/github.com/jaschaephraim/lrserver/javascript.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

30
vendor/github.com/jaschaephraim/lrserver/lrserver.go generated vendored Normal file
View File

@ -0,0 +1,30 @@
/*
Package lrserver implements a basic LiveReload server.
(See http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol .)
Using the recommended default port 35729:
http://localhost:35729/livereload.js
serves the LiveReload client JavaScript, and:
ws://localhost:35729/livereload
communicates with the client via web socket.
File watching must be implemented by your own application, and reload/alert
requests sent programmatically.
Multiple servers can be instantiated, and each can support multiple connections.
*/
package lrserver
const (
// DefaultName is the livereload Server's default name
DefaultName string = "LiveReload"
// DefaultPort is the livereload Server's default server port
DefaultPort uint16 = 35729
)

68
vendor/github.com/jaschaephraim/lrserver/messages.go generated vendored Normal file
View File

@ -0,0 +1,68 @@
package lrserver
var protocols = []string{
"http://livereload.com/protocols/official-7",
"http://livereload.com/protocols/official-8",
"http://livereload.com/protocols/official-9",
"http://livereload.com/protocols/2.x-origin-version-negotiation",
"http://livereload.com/protocols/2.x-remote-control",
}
type clientHello struct {
Command string `json:"command"`
Protocols []string `json:"protocols"`
}
func validateHello(hello *clientHello) bool {
if hello.Command != "hello" {
return false
}
for _, c := range hello.Protocols {
for _, s := range protocols {
if c == s {
return true
}
}
}
return false
}
type serverHello struct {
Command string `json:"command"`
Protocols []string `json:"protocols"`
ServerName string `json:"serverName"`
}
func makeServerHello(name string) *serverHello {
return &serverHello{
"hello",
protocols,
name,
}
}
type serverReload struct {
Command string `json:"command"`
Path string `json:"path"`
LiveCSS bool `json:"liveCSS"`
}
func makeServerReload(file string, liveCSS bool) *serverReload {
return &serverReload{
Command: "reload",
Path: file,
LiveCSS: liveCSS,
}
}
type serverAlert struct {
Command string `json:"command"`
Message string `json:"message"`
}
func makeServerAlert(msg string) *serverAlert {
return &serverAlert{
Command: "alert",
Message: msg,
}
}

203
vendor/github.com/jaschaephraim/lrserver/server.go generated vendored Normal file
View File

@ -0,0 +1,203 @@
package lrserver
import (
"fmt"
"log"
"net"
"net/http"
"os"
"strconv"
"context"
"github.com/gorilla/websocket"
)
// Server contains a single lrserver instance's data
type Server struct {
name string
port uint16
server *http.Server
connSet *connSet
js string
statusLog *log.Logger
liveCSS bool
}
// New creates a new Server instance
func New(name string, port uint16) *Server {
// Create router
router := http.NewServeMux()
logPrefix := "[" + name + "] "
// Create server
s := &Server{
name: name,
server: &http.Server{
Handler: router,
ErrorLog: log.New(os.Stderr, logPrefix, 0),
},
connSet: &connSet{conns: make(map[*conn]struct{})},
statusLog: log.New(os.Stdout, logPrefix, 0),
liveCSS: true,
}
s.setPort(port)
// Handle JS
router.HandleFunc("/livereload.js", jsHandler(s))
// Handle reload requests
router.HandleFunc("/livereload", webSocketHandler(s))
return s
}
func (s *Server) Close() error {
if s.server != nil {
return s.server.Close()
}
return nil
}
func (s *Server) Shutdown(ctx context.Context) error {
if s.server != nil {
return s.server.Shutdown(ctx)
}
return nil
}
func (s *Server) ListenAndServe() error {
// Create listener
l, err := net.Listen("tcp", makeAddr(s.port))
if err != nil {
return err
}
// Set assigned port if necessary
if s.port == 0 {
port, err := makePort(l.Addr().String())
if err != nil {
return err
}
s.setPort(port)
}
s.logStatus("listening on " + s.server.Addr)
return s.server.Serve(l)
}
// Reload sends a reload message to the client
func (s *Server) Reload(file string) {
s.logStatus("requesting reload: " + file)
for conn := range s.connSet.conns {
conn.reloadChan <- file
}
}
// Alert sends an alert message to the client
func (s *Server) Alert(msg string) {
s.logStatus("requesting alert: " + msg)
for conn := range s.connSet.conns {
conn.alertChan <- msg
}
}
// Name gets the server name
func (s *Server) Name() string {
return s.name
}
// Port gets the port that the server is listening on
func (s *Server) Port() uint16 {
return s.port
}
// LiveCSS gets the live CSS preference
func (s *Server) LiveCSS() bool {
return s.liveCSS
}
// StatusLog gets the server's status logger,
// which writes to os.Stdout by default
func (s *Server) StatusLog() *log.Logger {
return s.statusLog
}
// ErrorLog gets the server's error logger,
// which writes to os.Stderr by default
func (s *Server) ErrorLog() *log.Logger {
return s.server.ErrorLog
}
// SetLiveCSS sets the live CSS preference
func (s *Server) SetLiveCSS(n bool) {
s.liveCSS = n
}
// SetStatusLog sets the server's status logger,
// which can be set to nil
func (s *Server) SetStatusLog(l *log.Logger) {
s.statusLog = l
}
// SetErrorLog sets the server's error logger,
// which can be set to nil
func (s *Server) SetErrorLog(l *log.Logger) {
s.server.ErrorLog = l
}
func (s *Server) setPort(port uint16) {
s.port = port
s.server.Addr = makeAddr(port)
if port != 0 {
s.js = fmt.Sprintf(js, s.port)
}
}
func (s *Server) newConn(wsConn *websocket.Conn) {
c := &conn{
conn: wsConn,
server: s,
handshake: false,
reloadChan: make(chan string),
alertChan: make(chan string),
closeChan: make(chan closeSignal),
}
s.connSet.add(c)
go c.start()
}
func (s *Server) logStatus(msg ...interface{}) {
if s.statusLog != nil {
s.statusLog.Println(msg...)
}
}
func (s *Server) logError(msg ...interface{}) {
if s.server.ErrorLog != nil {
s.server.ErrorLog.Println(msg...)
}
}
// makeAddr converts uint16(x) to ":x"
func makeAddr(port uint16) string {
return fmt.Sprintf(":%d", port)
}
// makePort converts ":x" to uint16(x)
func makePort(addr string) (uint16, error) {
_, portString, err := net.SplitHostPort(addr)
if err != nil {
return 0, err
}
port64, err := strconv.ParseUint(portString, 10, 16)
if err != nil {
return 0, err
}
return uint16(port64), nil
}