Implementing upload server
This commit is contained in:
parent
99ef1b0ea0
commit
34ab765a5c
7 changed files with 132 additions and 17 deletions
23
README.md
23
README.md
|
@ -11,6 +11,12 @@ The server accepts the following commands:
|
|||
|
||||
//todo
|
||||
|
||||
#### The upload server
|
||||
|
||||
If the upload server is running, the user will be able to put files
|
||||
on the **absoluteServePath**. After the file is uploaded successfully,
|
||||
if the timeout is not reached, the user will get back the filename.
|
||||
|
||||
#### Sending commands via netcat
|
||||
|
||||
To grab a file the following command can be send:
|
||||
|
@ -32,13 +38,19 @@ Sample Configuration File:
|
|||
```
|
||||
{
|
||||
"address": "localhost",
|
||||
"port": "8080",
|
||||
"port": 8080,
|
||||
"maxDirDepth": 30,
|
||||
"absoluteServePath": "/Users/denis/Dropbox/Pictures/CuteAvatars",
|
||||
"pic": {
|
||||
"color": false,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
"color": true,
|
||||
"x": 197,
|
||||
"y": 50
|
||||
},
|
||||
"upload": {
|
||||
"enabled": false,
|
||||
"timeout": 5,
|
||||
"address": "localhost",
|
||||
"port": 8081
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -53,7 +65,8 @@ The **config.json** file contains the following settings:
|
|||
|
||||
4. absoluteServePath - The path from where to serve the files.
|
||||
|
||||
5. pic - The X and Y max size for the pic command. A value of 0 means original size
|
||||
5. pic - The X and Y max size for the pic command. A value of 0 means original size.
|
||||
|
||||
6. upload - Settings for the upload server.
|
||||
If one of the settings are changed, the server will reload the configuration.
|
||||
Except for the absoluteServePath.
|
|
@ -5,14 +5,60 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"bufio"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/zyxar/image2ascii/ascii"
|
||||
)
|
||||
|
||||
func randSeq(n int) string {
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// UploadFile uploads a file to the server
|
||||
func UploadFile(c Client) (string, error) {
|
||||
|
||||
input := bufio.NewScanner(c.Connection())
|
||||
start := time.Now()
|
||||
timeout := time.Duration(viper.GetInt("upload.timeout")) * time.Second
|
||||
|
||||
var filename = randSeq(10)
|
||||
var _, err = os.Stat(MakePathFromStringStack(c.Stack()) + filename)
|
||||
|
||||
// Make sure that the filename is random.
|
||||
for !os.IsNotExist(err) {
|
||||
filename = randSeq(10)
|
||||
_, err = os.Stat(MakePathFromStringStack(c.Stack()) + filename)
|
||||
}
|
||||
|
||||
f, err := os.Create(MakePathFromStringStack(c.Stack()) + filename)
|
||||
if err != nil {
|
||||
return filename, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for input.Scan() {
|
||||
if time.Since(start) >= timeout {
|
||||
log.Println(c.Connection().RemoteAddr().String() + " has reached timeout!")
|
||||
break
|
||||
}
|
||||
f.WriteString(input.Text() + "\n")
|
||||
}
|
||||
|
||||
return filename, nil
|
||||
}
|
||||
|
||||
// SendAsciiPic sends an image as ascii text to the client.
|
||||
func SendAsciiPic(c Client, path string) error {
|
||||
f, err := os.Open(MakePathFromStringStack(c.Stack()) + path)
|
||||
|
|
|
@ -28,17 +28,20 @@ func loadConfigFromFile() error {
|
|||
// setDefaultConfiguration will set the default configuration settings.
|
||||
func setDefaultConfiguration() {
|
||||
viper.SetDefault("address", "localhost")
|
||||
viper.SetDefault("port", "8080")
|
||||
viper.SetDefault("port", 8080)
|
||||
viper.SetDefault("configPath", ConfigPath)
|
||||
viper.SetDefault("maxDirDepth", 30)
|
||||
viper.SetDefault("absoluteServePath", "./")
|
||||
viper.SetDefault("pic.x", 0)
|
||||
viper.SetDefault("pic.y", 0)
|
||||
viper.SetDefault("pic.color", false)
|
||||
viper.SetDefault("upload.enabled", false)
|
||||
viper.SetDefault("upload.address", "localhost")
|
||||
viper.SetDefault("upload.port", 8081)
|
||||
}
|
||||
|
||||
// InitializedConfiguration initializes the configuration for the application.
|
||||
func InitializedConfiguration(callback func(e fsnotify.Event)) {
|
||||
// InitializeConfiguration initializes the configuration for the application.
|
||||
func InitializeConfiguration() {
|
||||
flag.StringVar(&ConfigPath, "config", ".", "Set the location of the config file.")
|
||||
flag.Parse()
|
||||
|
||||
|
@ -46,5 +49,8 @@ func InitializedConfiguration(callback func(e fsnotify.Event)) {
|
|||
loadConfigFromFile()
|
||||
|
||||
viper.WatchConfig()
|
||||
viper.OnConfigChange(callback)
|
||||
}
|
||||
|
||||
func ConfigChangeCallback(cb func(event fsnotify.Event)) {
|
||||
viper.OnConfigChange(cb)
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@ import (
|
|||
|
||||
func TestLoadConfigFromFile(t *testing.T) {
|
||||
// SetDefaultConfiguration must be called BEFORE LoadConfigFromFile.
|
||||
InitializedConfiguration()
|
||||
InitializeConfiguration()
|
||||
|
||||
Address := viper.GetString("address")
|
||||
if Address == "" {
|
||||
t.Error("TestLoadConfigFromFile: Can't get Address!")
|
||||
}
|
||||
|
||||
Port := viper.GetString("port")
|
||||
if Port == "" {
|
||||
Port := viper.GetInt("port")
|
||||
if Port == 0 {
|
||||
t.Error("TestLoadConfigFromFile: Can't get Port!")
|
||||
}
|
||||
|
||||
|
|
|
@ -88,18 +88,21 @@ func HandleConnection(client Client) {
|
|||
log.Println(client.Connection().RemoteAddr(), "has disconnected.")
|
||||
}
|
||||
|
||||
func StartFtpServer() {
|
||||
config.InitializedConfiguration(func(e fsnotify.Event) {
|
||||
log.Println("Configuration reloaded!")
|
||||
func Init() {
|
||||
config.InitializeConfiguration()
|
||||
config.ConfigChangeCallback(func(event fsnotify.Event) {
|
||||
log.Println("Configuration reloaded successfully!")
|
||||
})
|
||||
}
|
||||
|
||||
func StartFtpServer() {
|
||||
Addr := viper.GetString("address")
|
||||
Port := viper.GetString("port")
|
||||
Port := viper.GetInt("port")
|
||||
DirDepth := viper.GetInt("maxDirDepth")
|
||||
BasePath = viper.GetString("absoluteServePath")
|
||||
|
||||
// Start the server
|
||||
listener, err := net.Listen("tcp", Addr+":"+Port)
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", Addr, Port))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -122,3 +125,45 @@ func StartFtpServer() {
|
|||
go HandleConnection(&client)
|
||||
}
|
||||
}
|
||||
|
||||
func StartUploadServer() {
|
||||
if viper.GetBool("upload.enabled") == false {
|
||||
log.Println("Uploading not enabled. To enable modify the config file and restart the server")
|
||||
return
|
||||
}
|
||||
|
||||
Addr := viper.GetString("upload.address")
|
||||
Port := viper.GetInt("upload.port")
|
||||
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", Addr, Port))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Upload server running on:", Addr, "port", Port)
|
||||
|
||||
for {
|
||||
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
}
|
||||
|
||||
client := FTPClient{}
|
||||
client.SetStack(MakeStringStack(1))
|
||||
client.SetConnection(conn)
|
||||
|
||||
log.Println(conn.RemoteAddr().String() + " is uploading something.")
|
||||
|
||||
filename, err := UploadFile(&client)
|
||||
if err == nil {
|
||||
io.WriteString(conn, filename)
|
||||
} else {
|
||||
log.Print(conn.RemoteAddr().String())
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
log.Println(conn.RemoteAddr().String() + "'s upload finished.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ func TestMakePathFromStringStack(t *testing.T) {
|
|||
st.Push("folder two")
|
||||
st.Push("trinity")
|
||||
|
||||
BasePath = "./"
|
||||
|
||||
path := MakePathFromStringStack(st)
|
||||
expected := fmt.Sprintf("%s%s/%s/%s/", BasePath, "first", "folder two", "trinity")
|
||||
|
||||
|
|
|
@ -5,5 +5,8 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
server.Init()
|
||||
|
||||
go server.StartUploadServer()
|
||||
server.StartFtpServer()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue