我需要通过代理连接到ftp服务器,并从Golang代码下载文件.我已经实现了简单客户端:
package main
import (
"bufio"
"fmt"
"github.com/jlaffaye/ftp"
"io"
"log"
"net"
"net/http"
"os"
"strings"
"time"
)
var targetAddr = "ftp.dlptest.com"
var proxyAddr = "146.19.106.109:3128"
var user = "dlpuser"
var pass = "rNrKYTX9g7z3RgJRmxWuGHbeu"
var path = "/xxx.txt"
func connectViaProxy(network, address string) (net.Conn, error) {
parts := strings.Split(address, ":")
addr := fmt.Sprintf("%s:%s", targetAddr, parts[1])
proxyConn, err := net.Dial(network, proxyAddr)
if err != nil {
return nil, err
}
req, err := http.NewRequest(http.MethodConnect, "http://"+addr, nil)
if err != nil {
proxyConn.Close()
return nil, err
}
req.Header.Set("Accept", "*/*")
req.Header.Set("User-Agent", "curl/8.1.2")
req.Header.Set("Host", targetAddr+":21")
err = req.Write(proxyConn)
if err != nil {
return nil, err
}
resp, err := http.ReadResponse(bufio.NewReader(proxyConn), req)
if err != nil {
proxyConn.Close()
return nil, err
}
if resp.StatusCode != 200 {
x, _ := io.ReadAll(resp.Body)
fmt.Println(string(x))
proxyConn.Close()
return nil, fmt.Errorf("non-200 status code received from proxy: %v", resp.Status)
}
return proxyConn, nil
}
func main() {
c, err := ftp.Dial(targetAddr+":21",
ftp.DialWithTimeout(5*time.Second),
ftp.DialWithDebugOutput(os.Stdin),
ftp.DialWithDialFunc(connectViaProxy),
)
if err != nil {
log.Fatal(err)
}
err = c.Login(user, pass)
if err != nil {
log.Fatal(err)
}
if r, err := c.Retr(path); err != nil {
fmt.Println(err, ":<")
} else {
if reader, err := io.ReadAll(r); err != nil {
fmt.Println(err, ":(")
} else {
fmt.Println(string(reader))
}
}
if err = c.Quit(); err != nil {
log.Fatal(err)
}
}
不幸的是,我在try 连接时收到了403禁用.通常情况下,我会认为这是服务器限制,但它通过cURL完全正常工作:
curl -vvv -x 146.19.106.109:3128 -u dlpuser:rNrKYTX9g7z3RgJRmxWuGHbeu ftp://ftp.dlptest.com/xxx.txt
有人知道为什么会发生这种事吗?据我所知,curl也在幕后使用http Connect,所以我想知道我错过了什么.
另外,不要担心代码中的凭据-这些凭据可以在Web上公开测试