Refactoring: Instead of using net.Conn use a Client interface instead
This commit is contained in:
parent
a9da0ce2d9
commit
cb46154ec8
3 changed files with 66 additions and 18 deletions
|
@ -1,9 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/metonimie/simpleFTP/server/server"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/metonimie/simpleFTP/server/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -16,12 +17,17 @@ func main() {
|
||||||
log.Println("Running on:", "localhost", "port", "8080")
|
log.Println("Running on:", "localhost", "port", "8080")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
conn, err := listener.Accept()
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
go server.HandleConnection(conn)
|
client := server.FTPClient{}
|
||||||
|
client.SetStack(new(server.StringStack))
|
||||||
|
client.SetConnection(conn)
|
||||||
|
|
||||||
|
go server.HandleConnection(&client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,67 @@ import (
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleConnection(c net.Conn) {
|
// ClientStack interface holds the function needed to work with a stack.
|
||||||
defer c.Close()
|
type ClientStack interface {
|
||||||
io.WriteString(c, "Hello and welcome to simple ftp\n")
|
Stack() Stack // Returns the underlying Stack.
|
||||||
|
}
|
||||||
|
|
||||||
log.Println(c.RemoteAddr(), "has connected.")
|
// Client interface provides the blueprints for the Client that is used by the server.
|
||||||
|
type Client interface {
|
||||||
|
Connection() net.Conn // Connection returns the connection stream.
|
||||||
|
SetConnection(conn net.Conn) // SetConnection sets the connection for the client.
|
||||||
|
Disconnect() // Disconnect closes the Client's connections and clears up resources.
|
||||||
|
}
|
||||||
|
|
||||||
|
// FTPClient represents a FTPClient connection, it holds a root cage and the underlying connection.
|
||||||
|
type FTPClient struct {
|
||||||
|
rootCage *StringStack // rootCage is a StringStack that is used to represent the current directory the client is in.
|
||||||
|
connection net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack returns the root cage stack.
|
||||||
|
func (c *FTPClient) Stack() Stack {
|
||||||
|
return c.rootCage
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStack sets the stack for the FTPClient.
|
||||||
|
func (c *FTPClient) SetStack(stack *StringStack) {
|
||||||
|
c.rootCage = stack
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection returns the Connection of the client.
|
||||||
|
func (c *FTPClient) Connection() net.Conn {
|
||||||
|
return c.connection
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConnection sets the given connection to the client.
|
||||||
|
func (c *FTPClient) SetConnection(conn net.Conn) {
|
||||||
|
c.connection = conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnects the client.
|
||||||
|
func (c *FTPClient) Disconnect() {
|
||||||
|
c.connection.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleConnection(client Client) {
|
||||||
|
defer client.Disconnect()
|
||||||
|
io.WriteString(client.Connection(), "Hello and welcome to simple ftp\n")
|
||||||
|
|
||||||
|
log.Println(client.Connection().RemoteAddr(), "has connected.")
|
||||||
|
|
||||||
// Process input
|
// Process input
|
||||||
input := bufio.NewScanner(c)
|
input := bufio.NewScanner(client.Connection())
|
||||||
for input.Scan() {
|
for input.Scan() {
|
||||||
log.Println(c.RemoteAddr(), ":", input.Text())
|
log.Println(client.Connection().RemoteAddr(), ":", input.Text())
|
||||||
|
|
||||||
err := ProcessInput(c, input.Text())
|
err := ProcessInput(client, input.Text())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
io.WriteString(c, err.Error()+"\n")
|
io.WriteString(client.Connection(), err.Error()+"\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client has left.
|
// Client has left.
|
||||||
log.Println(c.RemoteAddr(), "has disconnected.")
|
log.Println(client.Connection().RemoteAddr(), "has disconnected.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ func checkArgumentsLength(length int, expected int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProcessInput(c net.Conn, text string) error {
|
func ProcessInput(c Client, text string) error {
|
||||||
commands := strings.Fields(text)
|
commands := strings.Fields(text)
|
||||||
commandsLen := len(commands)
|
commandsLen := len(commands)
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ func ProcessInput(c net.Conn, text string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the file
|
// Get the file
|
||||||
_, err = GetFile(c, commands[1])
|
_, err = GetFile(c.Connection(), commands[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +42,7 @@ func ProcessInput(c net.Conn, text string) error {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ListFiles(c)
|
err = ListFiles(c.Connection())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +56,7 @@ func ProcessInput(c net.Conn, text string) error {
|
||||||
// clear | hexdump -C
|
// clear | hexdump -C
|
||||||
var b = []byte{0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x4a}
|
var b = []byte{0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x4a}
|
||||||
|
|
||||||
c.Write(b)
|
c.Connection().Write(b)
|
||||||
case "help":
|
case "help":
|
||||||
// Check arguments
|
// Check arguments
|
||||||
err := checkArgumentsLength(commandsLen, 1)
|
err := checkArgumentsLength(commandsLen, 1)
|
||||||
|
@ -65,7 +64,7 @@ func ProcessInput(c net.Conn, text string) error {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ShowHelp(c)
|
err = ShowHelp(c.Connection())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +74,7 @@ func ProcessInput(c net.Conn, text string) error {
|
||||||
return &InputError{thisCommand, err}
|
return &InputError{thisCommand, err}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Close()
|
c.Connection().Close()
|
||||||
default:
|
default:
|
||||||
return &InputError{thisCommand, InputInvalidCommand}
|
return &InputError{thisCommand, InputInvalidCommand}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue