如何解析HTTP POST(文件上传)流?

时间:2010-09-25 15:19:30

标签: c++ c http actionscript post

我正在使用actionscript引擎上传文件,引擎将选择文件并通过网络通过HTTP POST命令发送文件,该文件说POST消息如下:

POST /handler.cfm HTTP/1.1
  Accept: text/*
  Content-Type: multipart/form-data; 
  boundary=----------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
  User-Agent: Shockwave Flash 
  Host: www.example.com 
  Content-Length: 421 
  Connection: Keep-Alive 
  Cache-Control: no-cache

  ------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
  Content-Disposition: form-data; name="Filename"

  MyFile.jpg
  ------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
  Content-Disposition: form-data; name="photo"; filename="MyFile.jpg"
  Content-Type: application/octet-stream

  FileDataHere
  ------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
  Content-Disposition: form-data; name="Upload"

  Submit Query

  ------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--

在服务器端,我有一个C ++程序侦听端口80并解析POST消息。我只想要文件名和文件数据。如何使用c ++解码文件数据,它是base64编码的,是否有一个库可以为我做?我想解码二进制文件,并将其写入文件,谢谢!

3 个答案:

答案 0 :(得分:5)

不,没有编码。多部分消息的每个子部分的主体包括在逐字节字节中。因此,您必须小心选择文件数据中不存在的boundary字符串。

要解析多部分/表单数据表单提交,您将有足够的MIME解析器来解析标题,选择您想要的参数boundaryname,并将收到的消息拆分为边界串。这并非完全无关紧要,因此您可能需要consider existing libraries

(不幸的是,HTTP中的浏览器实际上与RFC 1341中列出的标准MIME规则略有不同。特别是,字段名称和文件名参数往往包含非ASCII字符和未转义的引号。但是如果你希望你能自己产生POST,以避免这些争用领域。)

答案 1 :(得分:1)

如果没有“Content_Transfer_Encoding”标头,则假设数据以“7位”(RFC 1521; RFC 1867; RFC 2616)进行编码。

我不知道tere是一个解析/解码HTTP POST的C库。我很确定有:)

答案 2 :(得分:0)

您可以上传不受限制的data/file大小。试试这个解决方案

const char* ctype = "multipart/form-data; boundary=----WebKitFormBoundaryfm9qwXVLSbFKKR88";
size_t content_length = 1459606;
http_payload* hp = new http_payload(ctype, content_length);
if (hp->is_multipart()) {
    int ret = hp->read_all("C:\\temp\\");
    if (ret < 0) {
        std::cout << hp->get_last_error() << std::endl;
        hp->clear();
    }
    else {
        std::string dir_str("C:\\upload_dir\\");
        ret = hp->read_files([&dir_str](http_posted_file* file) {
            std::string path(dir_str.c_str());
            path.append(file->get_file_name());
            file->save_as(path.c_str());
            file->clear(); path.clear();
            std::string().swap(path);
        });
        hp->clear();
        std::cout << "Total file uploaded :" << ret << std::endl;
    }
}
else {
    int ret = hp->read_all();
    if (ret < 0) {
        std::cout << hp->get_last_error() << std::endl;
        hp->clear();
    }
    else {
        std::cout << "Posted data :" << hp->get_body() << std::endl;
        hp->clear();

    }
}

https://github.com/safeonlineworld/web_jsx/blob/0d08773c95f4ae8a9799dbd29e0a4cd84413d108/src/web_jsx/core/http_payload.cpp#L402