c++ - 从C++中的Content-Disposition header 正确提取文件名的更快方法

标签 c++ content-disposition

我想从“文件名”属性中提取所有可能的有效文件名类型
Content-Disposition HTTP header 的示例,如下例:

Content-Disposition: attachment; filename="filename.jpg"
Content-Disposition: attachment; filename=file-2020-April.txt.vbs"

此外,有时文件名包含非ASCII字符,在这种情况下,
文件名来自“filename = *”属性,例如以下示例:(这只是一个示例,不是实际数据)
Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt

我使用以下字符串函数仅从filename =“中提取
string ContentDispositionHeader;
int startPos = ContentDispositionHeader.find("\"");
startPos++;
int endPos = ContentDispositionHeader.find_last_of("\"");
int length = endPos - startPos;
string filename = ContentDispositionHeader.substr(startPos, length);

但是,我需要编写代码来管理两种文件命名方式(普通和UTF-8)。
有没有一种更快的方法来轻松提取文件名。

最佳答案

我相信,如果您正在寻找O(n),那么的不能比n = length of the header更快。而且,这就是您已经在尝试做的事情。

下面的示例考虑到引号始终存在,以类似的方式从 header 中提取文件名(有关更多信息,请引用RFC 6266);并且,如果存在ASCII,则UTF-8格式始终遵循ASCII。此外,在解析 header 时,可能还有更多情况需要注意。

这是示例(live):

#include <iostream>
#include <string>
#include <vector>
#include <utility>

// Filenames: <ASCII, UTF-8>
using Filenames = std::pair<std::string, std::string>;

Filenames getFilename( const std::string& header )
{
    std::string ascii;

    const std::string q1 { R"(filename=")" };
    if ( const auto pos = header.find(q1); pos != std::string::npos )
    {
        const auto len = pos + q1.size();

        const std::string q2 { R"(")" };
        if ( const auto pos = header.find(q2, len); pos != std::string::npos )
        {
            ascii = header.substr(len, pos - len);
        }
    }

    std::string utf8;

    const std::string u { R"(UTF-8'')" };
    if ( const auto pos = header.find(u); pos != std::string::npos )
    {
        utf8 = header.substr(pos + u.size());
    }

    return { ascii, utf8 };
}

int main()
{
    const std::vector<std::string> headers
    {
        R"(Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt)",
        R"(Content-Disposition: attachment; filename*=UTF-8''日本.txt)",
        R"(Content-Disposition: attachment; filename="filename.jpg")",
        R"(Content-Disposition: attachment; filename="file-2020-April.txt.vbs")"
    };

    for ( const auto& header : headers )
    {
        const auto& [ascii, utf8] = getFilename( header );
        std::cout << header
                  << "\n\tASCII: " << ascii
                  << "\n\tUTF-8: " << utf8 << '\n';
    }

    return 0;
}

输出:
Content-Disposition: attachment; filename="??.txt"; filename*=UTF-8''日本.txt
    ASCII: ??.txt
    UTF-8: 日本.txt
Content-Disposition: attachment; filename*=UTF-8''日本.txt
    ASCII: 
    UTF-8: 日本.txt
Content-Disposition: attachment; filename="filename.jpg"
    ASCII: filename.jpg
    UTF-8: 
Content-Disposition: attachment; filename="file-2020-April.txt.vbs"
    ASCII: file-2020-April.txt.vbs
    UTF-8: 

关于c++ - 从C++中的Content-Disposition header 正确提取文件名的更快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61003841/

相关文章:

c++ - 内容处置文件名中的特殊字符

c# - Content-Disposition header 中的 Unicode

c++ - 如何向 C 窗口中的几个对等点发送多播消息

c++ - 创建和使用 AABB 进行碰撞检测 3d (OpenGL)

php - Chrome 添加 "-, attachment"到下载的文件

cors - axios 暴露响应头 : Content-Disposition

java - 文件上传中的内容处理

c++ - Boost动态序列化所有派生类型

c++ - 当实例化是可能的,但继承不是在 C++ 中

C++ STL,我想知道映射中的双向迭代器和运算符[]有什么不同