http_form_data_unittest.cc revision 05d29044d14a60775ed6c51c75a414eb0cb50347
147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved.
247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be
347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko// found in the LICENSE file.
447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <chromeos/http/http_form_data.h>
647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <set>
847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <base/files/file_util.h>
1047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <base/files/scoped_temp_dir.h>
1147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <chromeos/mime_utils.h>
1247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko#include <gtest/gtest.h>
1347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
1447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenkonamespace chromeos {
1547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenkonamespace http {
1647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
1747e9a9dd3dce9d197820ee4241135e6859f95360Alex VakulenkoTEST(HttpFormData, TextFormField) {
1847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  TextFormField form_field{"field1", "abcdefg", mime::text::kPlain, "7bit"};
1947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const char expected_header[] =
2047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"field1\"\r\n"
2147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: text/plain\r\n"
2247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Transfer-Encoding: 7bit\r\n"
2347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n";
2447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(expected_header, form_field.GetContentHeader());
2547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(7u, form_field.GetDataSize());
2647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  char buffer[100];
2747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  size_t read = 0;
2847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_TRUE(form_field.ReadData(buffer, sizeof(buffer), &read, nullptr));
2947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(7u, read);
3047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ("abcdefg", (std::string{buffer, read}));
3147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}
3247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
3347e9a9dd3dce9d197820ee4241135e6859f95360Alex VakulenkoTEST(HttpFormData, FileFormField) {
3447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::ScopedTempDir dir;
3547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_TRUE(dir.CreateUniqueTempDir());
3647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string file_content{"text line1\ntext line2\n"};
3747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::FilePath file_name = dir.path().Append("sample.txt");
3847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_EQ(file_content.size(),
3905d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko            static_cast<size_t>(base::WriteFile(
4005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                file_name, file_content.data(), file_content.size())));
4147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
4247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::File file{file_name, base::File::FLAG_READ | base::File::FLAG_OPEN};
4347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_TRUE(file.IsValid());
4405d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  FileFormField form_field{"test_file",
4505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                           file.Pass(),
4605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                           "sample.txt",
4747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                           content_disposition::kFormData,
4805d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                           mime::text::kPlain,
4905d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                           ""};
5047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const char expected_header[] =
5147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"test_file\";"
5247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      " filename=\"sample.txt\"\r\n"
5347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: text/plain\r\n"
5447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n";
5547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(expected_header, form_field.GetContentHeader());
5647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(file_content.size(), form_field.GetDataSize());
5747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  char buffer[100];
5847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  size_t read = 0;
5947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_TRUE(form_field.ReadData(buffer, sizeof(buffer), &read, nullptr));
6047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(file_content.size(), read);
6147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(file_content, (std::string{buffer, read}));
6247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}
6347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
6447e9a9dd3dce9d197820ee4241135e6859f95360Alex VakulenkoTEST(HttpFormData, MultiPartFormField) {
6547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::ScopedTempDir dir;
6647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_TRUE(dir.CreateUniqueTempDir());
6747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string file1{"text line1\ntext line2\n"};
6847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::FilePath filename1 = dir.path().Append("sample.txt");
6947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_EQ(file1.size(),
7005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko            static_cast<size_t>(
7105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                base::WriteFile(filename1, file1.data(), file1.size())));
7247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string file2{"\x01\x02\x03\x04\x05"};
7347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::FilePath filename2 = dir.path().Append("test.bin");
7447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_EQ(file2.size(),
7505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko            static_cast<size_t>(
7605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                base::WriteFile(filename2, file2.data(), file2.size())));
7747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
7847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  MultiPartFormField form_field{"foo", mime::multipart::kFormData, "Delimiter"};
7947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  form_field.AddTextField("name", "John Doe");
8005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  EXPECT_TRUE(form_field.AddFileField("file1",
8105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                      filename1,
8247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                      content_disposition::kFormData,
8305d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                      mime::text::kPlain,
8405d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                      nullptr));
8505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  EXPECT_TRUE(form_field.AddFileField("file2",
8605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                      filename2,
8747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                      content_disposition::kFormData,
8847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                      mime::application::kOctet_stream,
8947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                      nullptr));
9047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const char expected_header[] =
9147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"foo\"\r\n"
9247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: multipart/form-data; boundary=\"Delimiter\"\r\n"
9347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n";
9447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(expected_header, form_field.GetContentHeader());
9547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string all_data;
9647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  for (;;) {
9747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    char buffer[1000];
9847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    size_t read = 0;
9947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    ASSERT_TRUE(form_field.ReadData(buffer, sizeof(buffer), &read, nullptr));
10047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    if (read == 0)
10147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      break;
10247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    all_data.append(buffer, buffer + read);
10347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  }
10447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const char expected_data[] =
10547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--Delimiter\r\n"
10647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"name\"\r\n"
10747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
10847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "John Doe\r\n"
10947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--Delimiter\r\n"
11047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"file1\";"
11147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      " filename=\"sample.txt\"\r\n"
11247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: text/plain\r\n"
11347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Transfer-Encoding: binary\r\n"
11447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
11547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "text line1\ntext line2\n\r\n"
11647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--Delimiter\r\n"
11747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"file2\";"
11847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      " filename=\"test.bin\"\r\n"
11947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: application/octet-stream\r\n"
12047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Transfer-Encoding: binary\r\n"
12147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
12247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\x01\x02\x03\x04\x05\r\n"
12347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--Delimiter--";
12447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(expected_data, all_data);
12547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(all_data.size(), form_field.GetDataSize());
12647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}
12747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
12847e9a9dd3dce9d197820ee4241135e6859f95360Alex VakulenkoTEST(HttpFormData, MultiPartBoundary) {
12947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const int count = 10;
13047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::set<std::string> boundaries;
13147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  for (int i = 0; i < count; i++) {
13247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    MultiPartFormField field{""};
13347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    std::string boundary = field.GetBoundary();
13447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    boundaries.insert(boundary);
13547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    // Our generated boundary must be 16 character long and contain lowercase
13647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    // hexadecimal digits only.
13747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    EXPECT_EQ(16u, boundary.size());
13847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    EXPECT_EQ(std::string::npos,
13947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko              boundary.find_first_not_of("0123456789abcdef"));
14047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  }
14147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // Now make sure the boundary strings were generated at random, so we should
14247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // get |count| unique boundary strings. However since the strings are random,
14347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // there is a very slim change of generating the same string twice, so
14447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // expect at least 90% of unique strings. 90% is picked arbitrarily here.
14547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  int expected_min_unique = count * 9 / 10;
14647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_GE(boundaries.size(), expected_min_unique);
14747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}
14847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
14947e9a9dd3dce9d197820ee4241135e6859f95360Alex VakulenkoTEST(HttpFormData, FormData) {
15047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::ScopedTempDir dir;
15147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_TRUE(dir.CreateUniqueTempDir());
15247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string file1{"text line1\ntext line2\n"};
15347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::FilePath filename1 = dir.path().Append("sample.txt");
15447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_EQ(file1.size(),
15505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko            static_cast<size_t>(
15605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                base::WriteFile(filename1, file1.data(), file1.size())));
15747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string file2{"\x01\x02\x03\x04\x05"};
15847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  base::FilePath filename2 = dir.path().Append("test.bin");
15947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  ASSERT_EQ(file2.size(),
16005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko            static_cast<size_t>(
16105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                base::WriteFile(filename2, file2.data(), file2.size())));
16247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
16347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  FormData form_data{"boundary1"};
16447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  form_data.AddTextField("name", "John Doe");
16547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::unique_ptr<MultiPartFormField> files{
16647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      new MultiPartFormField{"files", "", "boundary2"}};
16705d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  EXPECT_TRUE(files->AddFileField(
16805d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko      "", filename1, content_disposition::kFile, mime::text::kPlain, nullptr));
16905d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  EXPECT_TRUE(files->AddFileField("",
17005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                  filename2,
17147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                  content_disposition::kFile,
17247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                  mime::application::kOctet_stream,
17347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko                                  nullptr));
17447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  form_data.AddCustomField(std::move(files));
17547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ("multipart/form-data; boundary=\"boundary1\"",
17647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko            form_data.GetContentType());
17747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  std::string all_data;
17847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  for (;;) {
17947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    char buffer[8];
18047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    size_t read = 0;
18147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    ASSERT_TRUE(form_data.ReadData(buffer, sizeof(buffer), &read, nullptr));
18247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    if (read == 0)
18347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      break;
18447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko    all_data.append(buffer, buffer + read);
18547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  }
18647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  const char expected_data[] =
18747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary1\r\n"
18847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"name\"\r\n"
18947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
19047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "John Doe\r\n"
19147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary1\r\n"
19247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: form-data; name=\"files\"\r\n"
19347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: multipart/mixed; boundary=\"boundary2\"\r\n"
19447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
19547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary2\r\n"
19647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: file; filename=\"sample.txt\"\r\n"
19747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: text/plain\r\n"
19847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Transfer-Encoding: binary\r\n"
19947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
20047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "text line1\ntext line2\n\r\n"
20147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary2\r\n"
20247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Disposition: file; filename=\"test.bin\"\r\n"
20347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Type: application/octet-stream\r\n"
20447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "Content-Transfer-Encoding: binary\r\n"
20547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\r\n"
20647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "\x01\x02\x03\x04\x05\r\n"
20747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary2--\r\n"
20847e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko      "--boundary1--";
20947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(expected_data, all_data);
21047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  EXPECT_EQ(all_data.size(), form_data.GetDataSize());
21147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}
21247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}  // namespace http
21347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko}  // namespace chromeos
214