【问题标题】:FTP over HTTP using a Microsoft Azure function使用 Microsoft Azure 功能的 HTTP 上的 FTP
【发布时间】:2020-03-17 10:42:54
【问题描述】:

我必须使用 Microsoft Azure 功能通过 HTTP 设置 FTP,但是当尝试连接到 FTP 服务器时,客户端超时并抛出“ERR_GENERIC_CLIENT”错误并退出。我确定问题来自 FTP 客户端配置,但我找不到要更改的内容。 天蓝色的功能:

let Client = require('ssh2-sftp-client');
let client = new Client();
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const boundary = req.headers['content-type'].split('=')[1];
    const splitedBody = req.body.toString().split(boundary);
    let parsedBody = {};
    let errors = [];
    splitedBody.forEach(field => {
        if (field.includes('name=')) {
            if (!field.includes('filename')) {
                let regex = /name="(.*?)"\r\n\r\n(.*)/g;
                let m = regex.exec(field);
                parsedBody[m[1]] = m[2];
            }
            else {
                let regex = /Content-Type:\s(.*?)\s\s(((.*)\s)*)--/;
                let m = regex.exec(field);
                let file = field.split(m[1])[1]
                file = file.substring(4, file.length - 4);
                fileBuffer = Buffer.from(file);
                let fileNameRegex = /filename="(.*?)"/g;
                let fileName = fileNameRegex.exec(field)[1];
                parsedBody.file = file;
                parsedBody.buffer = fileBuffer;
                parsedBody.fileName = fileName;
            }
        }
    });
    const config = {
        host: parsedBody.host,
        port: parseInt(parsedBody.port),
        username: parsedBody.user,
        password: parsedBody.password,
        tryKeyboard: true,
        readyTimeout: 5000
    };
    try {
        await client.connect(config);
        try {
            let result = await client.put(
                parsedBody.buffer,
                parsedBody.path,
                {
                    flags: 'w',  // w - write and a - append
                    encoding: null, // use null for binary files
                    mode: 0o666, // mode to use for created file (rwx)
                    autoClose: true // automatically close the write stream when finished
                })
        }
        catch (e) {
            errors.push({e, msg: 'put'});
            context.log(`main error: ${e.message}`);
        }
    }
    catch (e) {
        errors.push({e, msg: 'connect'});
        context.log(e);
    }
    finally {
        client.end();
    }
    context.res = {
        body: {
            config,
            errors
        }
    };
};

为了测试,我使用了一个小的虚拟 HTML 表单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ftp over http</title>
</head>
<body>
                <form action="azure function URL" enctype="multipart/form-data" method="post">
                    <input type="hidden" name="host" value="ftp.server.address">
                    <input type="hidden" name="port" value="21">
                    <input type="hidden" name="path" value="/test/">
                    <input type="hidden" name="user" value="username">
                    <input type="hidden" name="password" value="password">
            <div>
                Text field title: <input type="text" name="title" /></div>
            <div>
                File: <input type="file" name="file" /></div>
            <input type="submit" value="Upload" />
        </form>
</body>
</html>```
When I submit the form all I receive is the unhelpfull and undocumented "ERR_GENERIC_CLIENT" code.

【问题讨论】:

  • Azure 逻辑应用提供内置的客户端 ftp 功能。您是否考虑过使用它而不是通过 Azure Function 构建自己的 ftp 客户端?
  • 嗨 Zak,请问您的问题是否已解决?如果解决方案有效,请您accept 将其作为答案(单击我的答案旁边的复选标记,将其从灰色切换为已填充)。提前致谢。

标签: node.js azure ftp


【解决方案1】:

根据您提供的代码,您使用sdk ssh2-sftp-client 连接ftp 服务器。这是错误的。我们可以用它来连接 sftp 服务器。如果你想连接ftp服务器,我建议你使用sdkbasic-ftp。 sdk的使用方法请参考https://github.com/patrickjuchli/basic-ftp

例如

  1. 代码
const ftp = require("basic-ftp")
const client = new ftp.Client()
module.exports = async function (context, req) {
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const boundary = req.headers['content-type'].split('=')[1];
    const splitedBody = req.body.toString().split(boundary);
    let parsedBody = {};
    let errors = [];
    splitedBody.forEach(field => {
        if (field.includes('name=')) {
            if (!field.includes('filename')) {
                let regex = /name="(.*?)"\r\n\r\n(.*)/g;
                let m = regex.exec(field);
                parsedBody[m[1]] = m[2];
            }
            else {
                let regex = /Content-Type:\s(.*?)\s\s(((.*)\s)*)--/;
                let m = regex.exec(field);
                let file = field.split(m[1])[1]
                file = file.substring(4, file.length - 4);
                fileBuffer = Buffer.from(file);
                let fileNameRegex = /filename="(.*?)"/g;
                let fileName = fileNameRegex.exec(field)[1];
                parsedBody.file = file;
                parsedBody.buffer = fileBuffer;
                parsedBody.fileName = fileName;
            }
        }
    });



client.ftp.verbose = true
    try {
        await   client.access({
            host: parsedBody.host,
        port: parseInt(parsedBody.port),
        user: parsedBody.user,
        password: parsedBody.password

        })
        var stream =getStream(parsedBody.buffer)
        const result =await client.upload(stream,parsedBody.path)
        context.log(result)

    }
    catch(err) {
        context.log(err)
        errors += err
    }
    client.close()

    context.res = {
        body: {
            errors
        }
    };











 };
  1. 测试(我用邮递员做测试)

  1. 连接FTP服务器查看(我用FileZilla

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    相关资源
    最近更新 更多