Change directories, list their contents, and download files

Image for post

Photo by Adam Birkett on Unsplash

In Part 1 we learned how to serve multiple clients concurrently, designed a struct to represent an FTP connection, routed client commands to their server-side handlers, and covered the basics of sending responses. Now we’re ready for the meat of FTP: manipulating directories and downloading files.

As a reminder, here’s ftp.Serve, the router that dispatches commands from the client to their handler functions. It’s these handler functions that we’re going to study today.

// Serve scans incoming requests for valid commands and routes them to handler functions.
	func Serve(c *Conn) {
		c.respond(status220)

		s := bufio.NewScanner(c.conn)
		for s.Scan() {
			input := strings.Fields(s.Text())
			if len(input) == 0 {
				continue
			}
			command, args := input[0], input[1:]
			log.Printf("<< %s %v", command, args)

			switch command {
			case "CWD": // cd
				c.cwd(args)
			case "LIST": // ls
				c.list(args)
			case "PORT":
				c.port(args)
			case "USER":
				c.user(args)
			case "QUIT": // close
				c.respond(status221)
				return
			case "RETR": // get
				c.retr(args)
			case "TYPE":
				c.setDataType(args)
			default:
				c.respond(status502)
			}
		}
		if s.Err() != nil {
			log.Print(s.Err())
		}
	}

#golang #go #programming #ftp #concurrency

How to Write a Concurrent FTP Server in Go (Part 2)
1.75 GEEK