Add FTP storage method
This commit is contained in:
parent
47c785b4d3
commit
aef7e308d0
@ -24,8 +24,13 @@ func GetStorage(config *conf.ConfigFile) (Storage, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case "ftp":
|
||||||
|
storage, err = NewFTPStorage(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("Error: storage method '" + storageMethod + "' not implemented.")
|
return nil, errors.New("Error: storage method '" + storageMethod + "' not found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return storage, nil
|
return storage, nil
|
||||||
|
121
client/storage_ftp.go
Normal file
121
client/storage_ftp.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.google.com/p/goconf/conf"
|
||||||
|
"errors"
|
||||||
|
"github.com/jlaffaye/goftp"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FTP_MAX_CONNECTIONS = 10 //should this be configurable?
|
||||||
|
|
||||||
|
type FTPStorage struct {
|
||||||
|
connectionsChan chan int
|
||||||
|
server string
|
||||||
|
port int
|
||||||
|
directory string
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFTPStorage(config *conf.ConfigFile) (*FTPStorage, error) {
|
||||||
|
server, err := config.GetString("storage", "server")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error: FTPStorage indicated in config file, but 'server' not specified.")
|
||||||
|
}
|
||||||
|
port, err := config.GetInt("storage", "port")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error: FTPStorage indicated in config file, but 'port' not specified.")
|
||||||
|
}
|
||||||
|
directory, err := config.GetString("storage", "directory")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error: FTPStorage indicated in config file, but 'directory' not specified.")
|
||||||
|
}
|
||||||
|
username, err := config.GetString("storage", "username")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error: FTPStorage indicated in config file, but 'username' not specified.")
|
||||||
|
}
|
||||||
|
password, err := config.GetString("storage", "password")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error: FTPStorage indicated in config file, but 'password' not specified.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := new(FTPStorage)
|
||||||
|
fs.server = server
|
||||||
|
fs.port = port
|
||||||
|
fs.directory = directory
|
||||||
|
fs.username = username
|
||||||
|
fs.password = password
|
||||||
|
|
||||||
|
fs.connectionsChan = make(chan int, FTP_MAX_CONNECTIONS)
|
||||||
|
|
||||||
|
return fs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FTPStorage) Put(filename string, hash string) (e error) {
|
||||||
|
//make sure we don't flood the FTP server
|
||||||
|
fs.connectionsChan <- 0
|
||||||
|
defer func() { <-fs.connectionsChan }()
|
||||||
|
|
||||||
|
infile, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer infile.Close()
|
||||||
|
|
||||||
|
connection, err := ftp.Connect(fs.server + ":" + strconv.Itoa(fs.port))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer connection.Quit()
|
||||||
|
|
||||||
|
err = connection.Login(fs.username, fs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = connection.ChangeDir(fs.directory)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection.Stor(hash, infile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FTPStorage) Get(filename string, hash string) error {
|
||||||
|
fs.connectionsChan <- 0
|
||||||
|
defer func() { <-fs.connectionsChan }()
|
||||||
|
|
||||||
|
connection, err := ftp.Connect(fs.server + ":" + strconv.Itoa(fs.port))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer connection.Quit()
|
||||||
|
|
||||||
|
err = connection.Login(fs.username, fs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = connection.ChangeDir(fs.directory)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadedFile, err := connection.Retr(hash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer downloadedFile.Close()
|
||||||
|
|
||||||
|
outfile, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer outfile.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(outfile, downloadedFile)
|
||||||
|
return err
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user