Browse Source

Implements timeouts.

Added DialTimeout and Dial functions.
Fixes issue #27.
Julien Laffaye 10 years ago
parent
commit
a9410e3e51
2 changed files with 22 additions and 7 deletions
  1. 4 3
      client_test.go
  2. 18 4
      ftp.go

+ 4 - 3
client_test.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"io/ioutil"
 	"testing"
+	"time"
 )
 
 const (
@@ -12,7 +13,7 @@ const (
 )
 
 func TestConn(t *testing.T) {
-	c, err := Connect("localhost:21")
+	c, err := DialTimeout("localhost:21", 5*time.Second)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -112,8 +113,8 @@ func TestConn(t *testing.T) {
 }
 
 // ftp.mozilla.org uses multiline 220 response
-func TestConn2(t *testing.T) {
-	c, err := Connect("ftp.mozilla.org:21")
+func TestMultiline(t *testing.T) {
+	c, err := DialTimeout("ftp.mozilla.org:21", 5*time.Second)
 	if err != nil {
 		t.Fatal(err)
 	}

+ 18 - 4
ftp.go

@@ -27,6 +27,7 @@ const (
 type ServerConn struct {
 	conn     *textproto.Conn
 	host     string
+	timeout  time.Duration
 	features map[string]string
 }
 
@@ -44,20 +45,33 @@ type response struct {
 	c    *ServerConn
 }
 
-// Connect initializes the connection to the specified ftp server address.
+// Connect is an alias to Dial, for backward compatibility
+func Connect(addr string) (*ServerConn, error) {
+	return Dial(addr)
+}
+
+// Dial is like DialTimeout with no timeout
+func Dial(addr string) (*ServerConn, error) {
+	return DialTimeout(addr, 0)
+}
+
+// DialTimeout initializes the connection to the specified ftp server address.
 //
 // It is generally followed by a call to Login() as most FTP commands require
 // an authenticated user.
-func Connect(addr string) (*ServerConn, error) {
-	conn, err := textproto.Dial("tcp", addr)
+func DialTimeout(addr string, timeout time.Duration) (*ServerConn, error) {
+	tconn, err := net.DialTimeout("tcp", addr, timeout)
 	if err != nil {
 		return nil, err
 	}
 
+	conn := textproto.NewConn(tconn)
+
 	a := strings.SplitN(addr, ":", 2)
 	c := &ServerConn{
 		conn:     conn,
 		host:     a[0],
+		timeout:  timeout,
 		features: make(map[string]string),
 	}
 
@@ -219,7 +233,7 @@ func (c *ServerConn) openDataConn() (net.Conn, error) {
 	// Build the new net address string
 	addr := fmt.Sprintf("%s:%d", c.host, port)
 
-	conn, err := net.Dial("tcp", addr)
+	conn, err := net.DialTimeout("tcp", addr, c.timeout)
 	if err != nil {
 		return nil, err
 	}