This repository has been archived on 2021-07-08. You can view files and clone it, but cannot push or open issues or pull requests.
opensend/files.go

190 lines
5.3 KiB
Go
Raw Normal View History

/*
Copyright © 2021 Arsen Musayelyan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
2020-12-03 10:12:43 +00:00
package main
import (
"io"
"io/ioutil"
"net"
2021-06-19 07:01:31 +00:00
"net/http"
2020-12-03 10:12:43 +00:00
"os"
"path/filepath"
"strconv"
"strings"
2021-06-19 07:01:31 +00:00
"github.com/rs/zerolog/log"
)
2020-12-03 10:12:43 +00:00
// Save encrypted key to file
func SaveEncryptedKey(encryptedKey []byte, filePath string) {
// Use ConsoleWriter logger
// Create file at given file path
keyFile, err := os.Create(filePath)
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error creating file")
}
2020-12-03 10:12:43 +00:00
// Close file at the end of this function
defer keyFile.Close()
// Write encrypted key to file
bytesWritten, err := keyFile.Write(encryptedKey)
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error writing key to file")
}
2020-12-03 10:12:43 +00:00
// Log bytes written
log.Info().Str("file", filepath.Base(filePath)).Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
}
// Create HTTP server to transmit files
func SendFiles(dir string) {
// Use ConsoleWriter logger with normal FatalHook
// Create TCP listener on port 9898
2020-12-05 06:45:38 +00:00
listener, err := net.Listen("tcp", ":9898")
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error starting listener")
}
2021-06-19 07:01:31 +00:00
http.HandleFunc("/key", func(res http.ResponseWriter, req *http.Request) {
// Inform user client has requested key
log.Info().Msg("Key requested")
// Read saved key
key, err := ioutil.ReadFile(dir + "/key.aes")
if err != nil {
log.Fatal().Err(err).Msg("Error reading key")
2020-12-21 07:18:42 +00:00
}
2021-06-19 07:01:31 +00:00
// Write saved key to ResponseWriter
_, err = res.Write(key)
2020-12-21 07:18:42 +00:00
if err != nil {
2021-06-19 07:01:31 +00:00
log.Fatal().Err(err).Msg("Error writing response")
2020-12-21 07:18:42 +00:00
}
2021-06-19 07:01:31 +00:00
})
http.HandleFunc("/index", func(res http.ResponseWriter, req *http.Request) {
// Inform user a client has requested the file index
log.Info().Msg("Index requested")
// Get directory listing
dirListing, err := ioutil.ReadDir(dir)
if err != nil {
log.Fatal().Err(err).Msg("Error reading directory")
2020-12-21 07:18:42 +00:00
}
2021-06-19 07:01:31 +00:00
// Create new slice to house filenames for index
var indexSlice []string
// For each file in listing
for _, file := range dirListing {
// If the file is not the key
if !strings.Contains(file.Name(), "key.aes") {
// Append the file path to indexSlice
indexSlice = append(indexSlice, file.Name())
}
2020-12-03 10:12:43 +00:00
}
2021-06-19 07:01:31 +00:00
// Join index slice into string
indexStr := strings.Join(indexSlice, "|")
// Write index to ResponseWriter
_, err = res.Write([]byte(indexStr))
if err != nil {
log.Fatal().Err(err).Msg("Error writing response")
}
})
http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
log.Info().Str("file", filepath.Base(req.URL.Path)).Msg("File requested")
http.FileServer(http.Dir(dir)).ServeHTTP(res, req)
})
http.HandleFunc("/stop", func(res http.ResponseWriter, req *http.Request) {
log.Info().Msg("Stop signal received")
res.WriteHeader(http.StatusOK)
listener.Close()
})
http.Serve(listener, nil)
}
type Sender struct {
RemoteAddr string
}
func (c *Sender) Get(endpoint string) (io.ReadCloser, int, error) {
res, err := http.Get(c.RemoteAddr + endpoint)
if err != nil {
return nil, 0, err
}
2021-06-19 07:01:31 +00:00
return res.Body, res.StatusCode, nil
}
2020-12-03 10:12:43 +00:00
2021-06-19 07:01:31 +00:00
func NewSender(senderAddr string) *Sender {
// Get server address by getting the IP without the port, and appending :9898
2021-06-19 07:01:31 +00:00
host, _, _ := net.SplitHostPort(senderAddr)
serverAddr := "http://" + net.JoinHostPort(host, "9898")
return &Sender{RemoteAddr: serverAddr}
2020-12-03 10:12:43 +00:00
}
// Get files from sender
2021-06-19 07:01:31 +00:00
func RecvFiles(sender *Sender) {
2020-12-03 10:12:43 +00:00
// Use ConsoleWriter logger
2021-06-19 07:01:31 +00:00
indexReader, code, err := sender.Get("/index")
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error getting index")
}
// If non-ok code returned, fatally log
2021-06-19 07:01:31 +00:00
if code != http.StatusOK {
2020-12-21 07:18:42 +00:00
log.Fatal().Err(err).Msg("Sender reported error")
}
2021-06-19 07:01:31 +00:00
indexBytes, err := ioutil.ReadAll(indexReader)
if err != nil {
log.Fatal().Err(err).Msg("Error reading index from response")
}
// Get index from message
2021-06-19 07:01:31 +00:00
index := strings.Split(strings.TrimSpace(string(indexBytes)), "|")
2020-12-03 10:12:43 +00:00
for _, file := range index {
// Read received message
2021-06-19 07:01:31 +00:00
fileData, code, err := sender.Get("/" + file)
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error getting file")
}
// If non-ok code returned
2021-06-19 07:01:31 +00:00
if code != http.StatusOK {
// fatally log
2021-06-19 07:01:31 +00:00
log.Fatal().
Int("status", code).
Str("statusText", http.StatusText(code)).
Err(err).
Msg("Sender reported error")
2020-12-21 07:18:42 +00:00
// Otherwise
} else {
2020-12-03 10:12:43 +00:00
// Create new file at index filepath
2020-12-31 07:54:18 +00:00
newFile, err := os.Create(*workDir + "/" + file)
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error creating file")
}
2020-12-03 10:12:43 +00:00
// Copy response body to new file
2021-06-19 07:01:31 +00:00
bytesWritten, err := io.Copy(newFile, fileData)
2020-12-21 07:18:42 +00:00
if err != nil {
log.Fatal().Err(err).Msg("Error writing to file")
}
2020-12-03 10:12:43 +00:00
// Log bytes written
log.Info().Str("file", filepath.Base(file)).Msg("Wrote " + strconv.Itoa(int(bytesWritten)) + " bytes")
// Close new file
newFile.Close()
}
}
}
// Send stop signal to sender
2021-06-19 07:01:31 +00:00
func SendSrvStopSignal(sender *Sender) {
_, _, _ = sender.Get("/stop")
2020-12-21 07:18:42 +00:00
}