diff --git a/conn_test.go b/conn_test.go index 47baeea..4b9d7a5 100644 --- a/conn_test.go +++ b/conn_test.go @@ -75,7 +75,7 @@ func (mock *ftpMock) listen(t *testing.T) { // At least one command must have a multiline response switch cmdParts[0] { case "FEAT": - mock.proto.Writer.PrintfLine("211-Features:\r\n FEAT\r\n PASV\r\n EPSV\r\n SIZE\r\n211 End") + mock.proto.Writer.PrintfLine("211-Features:\r\n FEAT\r\n PASV\r\n EPSV\r\n UTF8\r\n SIZE\r\n211 End") case "USER": if cmdParts[1] == "anonymous" { mock.proto.Writer.PrintfLine("331 Please send your password") @@ -196,6 +196,15 @@ func (mock *ftpMock) listen(t *testing.T) { mock.proto.Writer.PrintfLine("350 Restarting at %s. Send STORE or RETRIEVE to initiate transfer", cmdParts[1]) case "NOOP": mock.proto.Writer.PrintfLine("200 NOOP ok.") + case "OPTS": + if len(cmdParts) != 3 { + mock.proto.Writer.PrintfLine("500 wrong number of arguments") + break + } + if (strings.Join(cmdParts[1:], " ")) == "UTF8 ON" { + mock.proto.Writer.PrintfLine("200 OK, UTF-8 enabled") + break + } case "REIN": mock.proto.Writer.PrintfLine("220 Logged out") case "QUIT": @@ -319,7 +328,7 @@ func openConn(t *testing.T, addr string, options ...DialOption) (*ftpMock, *Serv // Helper to close a client connected to a mock server func closeConn(t *testing.T, mock *ftpMock, c *ServerConn, commands []string) { - expected := []string{"FEAT", "USER", "PASS", "TYPE"} + expected := []string{"FEAT", "USER", "PASS", "TYPE", "OPTS"} expected = append(expected, commands...) expected = append(expected, "QUIT") diff --git a/ftp.go b/ftp.go index 46b804f..49968ba 100644 --- a/ftp.go +++ b/ftp.go @@ -53,6 +53,7 @@ type dialOptions struct { explicitTLS bool conn net.Conn disableEPSV bool + disableUTF8 bool location *time.Location debugOutput io.Writer dialFunc func(network, address string) (net.Conn, error) @@ -176,6 +177,13 @@ func DialWithDisabledEPSV(disabled bool) DialOption { }} } +// DialWithDisabledUTF8 returns a DialOption that configures the ServerConn with UTF8 option disabled +func DialWithDisabledUTF8(disabled bool) DialOption { + return DialOption{func(do *dialOptions) { + do.disableUTF8 = disabled + }} +} + // DialWithLocation returns a DialOption that configures the ServerConn with specified time.Location // The location is used to parse the dates sent by the server which are in server's timezone func DialWithLocation(location *time.Location) DialOption { @@ -280,7 +288,9 @@ func (c *ServerConn) Login(user, password string) error { } // Switch to UTF-8 - err = c.setUTF8() + if !c.options.disableUTF8 { + err = c.setUTF8() + } // If using implicit TLS, make data connections also use TLS if c.options.tlsConfig != nil {