Commit 18cb1222 authored by Eric Willigers's avatar Eric Willigers Committed by Commit Bot

Web Share Target: ComputeMultipartBody in components

ComputeMultipartBody is now in components/web_share_target.

This allows it to be used on Desktop as well as Android.

Bug: 1125880
Change-Id: I63672ab4c59760e5dafe6b47d02e6848275dec67
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2539218
Commit-Queue: Eric Willigers <ericwilligers@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarMaksim Orlovich <morlovich@chromium.org>
Reviewed-by: default avatarPeter Kotwicz <pkotwicz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828882}
parent db4494fd
...@@ -1970,6 +1970,7 @@ static_library("browser") { ...@@ -1970,6 +1970,7 @@ static_library("browser") {
"//chrome/browser/ui/webui/usb_internals:mojo_bindings", "//chrome/browser/ui/webui/usb_internals:mojo_bindings",
"//chrome/browser/updates/announcement_notification", "//chrome/browser/updates/announcement_notification",
"//chrome/browser/video_tutorials", "//chrome/browser/video_tutorials",
"//chrome/browser/web_share_target",
"//chrome/common:channel_info", "//chrome/common:channel_info",
"//chrome/common:version_header", "//chrome/common:version_header",
"//chrome/common/net", "//chrome/common/net",
......
...@@ -3,6 +3,7 @@ include_rules = [ ...@@ -3,6 +3,7 @@ include_rules = [
"+components/resources/android", "+components/resources/android",
"+cc/layers/layer.h", "+cc/layers/layer.h",
"+chrome/android/test_support_jni_headers", "+chrome/android/test_support_jni_headers",
"+chrome/browser/web_share_target",
"+chrome_jni_registration/chrome_jni_registration.h", "+chrome_jni_registration/chrome_jni_registration.h",
"+components/browser_ui/site_settings/android", "+components/browser_ui/site_settings/android",
"+components/browser_ui/sms/android", "+components/browser_ui/sms/android",
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversion_utils.h"
#include "chrome/android/chrome_jni_headers/WebApkPostShareTargetNavigator_jni.h" #include "chrome/android/chrome_jni_headers/WebApkPostShareTargetNavigator_jni.h"
#include "chrome/browser/web_share_target/target_util.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "net/base/escape.h"
#include "net/base/mime_util.h" #include "net/base/mime_util.h"
#include "ui/base/window_open_disposition.h" #include "ui/base/window_open_disposition.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -23,121 +23,6 @@ using base::android::JavaParamRef; ...@@ -23,121 +23,6 @@ using base::android::JavaParamRef;
namespace webapk { namespace webapk {
std::string PercentEscapeString(const std::string& unescaped_string) {
std::ostringstream escaped_oss;
for (size_t i = 0; i < unescaped_string.length(); ++i) {
if (unescaped_string[i] == '"') {
escaped_oss << "%22";
} else if (unescaped_string[i] == 0x0a) {
escaped_oss << "%0A";
} else if (unescaped_string[i] == 0x0d) {
escaped_oss << "%0D";
} else {
escaped_oss << unescaped_string[i];
}
}
return escaped_oss.str();
}
void AddFile(const std::string& value_name,
const std::string& file_uri,
const std::string& file_name,
const std::string& content_type,
const std::string& boundary,
scoped_refptr<network::ResourceRequestBody> result) {
const char delimiter[] = "\r\n";
const size_t delimiter_length = 2;
std::string mime_header;
// First line is the boundary.
mime_header.append("--" + boundary + delimiter);
// Next line is the Content-disposition.
mime_header.append("Content-Disposition: form-data; name=\"" + value_name +
"\"");
if (!file_name.empty()) {
mime_header.append("; filename=\"" + file_name + "\"");
}
mime_header.append(delimiter);
if (!content_type.empty()) {
// If Content-type is specified, the next line is that.
mime_header.append("Content-Type: " + content_type + delimiter);
}
// Leave an empty line before appending the file_uri.
mime_header.append(delimiter);
result->AppendBytes(mime_header.c_str(), mime_header.length());
result->AppendFileRange(base::FilePath(file_uri), 0, -1, base::Time());
result->AppendBytes(delimiter, delimiter_length);
}
void AddPlainText(const std::string& value_name,
const std::string& value,
const std::string& file_name,
const std::string& content_type,
const std::string& boundary,
scoped_refptr<network::ResourceRequestBody> result) {
std::string item;
if (file_name.empty()) {
net::AddMultipartValueForUpload(value_name, value, boundary, content_type,
&item);
} else {
net::AddMultipartValueForUploadWithFileName(value_name, file_name, value,
boundary, content_type, &item);
}
result->AppendBytes(item.c_str(), item.length());
}
scoped_refptr<network::ResourceRequestBody> ComputeMultipartBody(
const std::vector<std::string>& names,
const std::vector<std::string>& values,
const std::vector<bool>& is_value_file_uris,
const std::vector<std::string>& filenames,
const std::vector<std::string>& types,
const std::string& boundary) {
size_t num_files = names.size();
if (num_files != values.size() || num_files != is_value_file_uris.size() ||
num_files != filenames.size() || num_files != types.size()) {
// The length of all arrays should always be the same for multipart POST.
// This should never happen.
return nullptr;
}
scoped_refptr<network::ResourceRequestBody> result =
new network::ResourceRequestBody();
for (size_t i = 0; i < num_files; i++) {
if (is_value_file_uris[i]) {
AddFile(PercentEscapeString(names[i]), values[i],
PercentEscapeString(filenames[i]), types[i], boundary, result);
} else {
AddPlainText(PercentEscapeString(names[i]), values[i],
PercentEscapeString(filenames[i]), types[i], boundary,
result);
}
}
std::string final_delimiter;
net::AddMultipartFinalDelimiterForUpload(boundary, &final_delimiter);
result->AppendBytes(final_delimiter.c_str(), final_delimiter.length());
return result;
}
std::string ComputeUrlEncodedBody(const std::vector<std::string>& names,
const std::vector<std::string>& values) {
if (names.size() != values.size() || names.size() == 0)
return "";
std::ostringstream application_body_oss;
application_body_oss << net::EscapeUrlEncodedData(names[0], true) << "="
<< net::EscapeUrlEncodedData(values[0], true);
for (size_t i = 1; i < names.size(); i++)
application_body_oss << "&" << net::EscapeUrlEncodedData(names[i], true)
<< "=" << net::EscapeUrlEncodedData(values[i], true);
return application_body_oss.str();
}
void NavigateShareTargetPost( void NavigateShareTargetPost(
const scoped_refptr<network::ResourceRequestBody>& post_data, const scoped_refptr<network::ResourceRequestBody>& post_data,
const std::string& header_list, const std::string& header_list,
...@@ -187,10 +72,10 @@ static void JNI_WebApkPostShareTargetNavigator_NativeLoadViewForShareTargetPost( ...@@ -187,10 +72,10 @@ static void JNI_WebApkPostShareTargetNavigator_NativeLoadViewForShareTargetPost(
std::string boundary = net::GenerateMimeMultipartBoundary(); std::string boundary = net::GenerateMimeMultipartBoundary();
header_list = base::StringPrintf( header_list = base::StringPrintf(
"Content-Type: multipart/form-data; boundary=%s\r\n", boundary.c_str()); "Content-Type: multipart/form-data; boundary=%s\r\n", boundary.c_str());
post_data = webapk::ComputeMultipartBody(names, values, is_value_file_uris, post_data = web_share_target::ComputeMultipartBody(
filenames, types, boundary); names, values, is_value_file_uris, filenames, types, boundary);
} else { } else {
std::string body = webapk::ComputeUrlEncodedBody(names, values); std::string body = web_share_target::ComputeUrlEncodedBody(names, values);
header_list = "Content-Type: application/x-www-form-urlencoded\r\n"; header_list = "Content-Type: application/x-www-form-urlencoded\r\n";
post_data = network::ResourceRequestBody::CreateFromBytes(body.c_str(), post_data = network::ResourceRequestBody::CreateFromBytes(body.c_str(),
body.length()); body.length());
......
...@@ -16,23 +16,6 @@ class GURL; ...@@ -16,23 +16,6 @@ class GURL;
namespace webapk { namespace webapk {
// Return a string as a quoted value, escaping quotes and line breaks.
std::string PercentEscapeString(const std::string& unescaped_string);
// Compute and return multipart/form-data POST body for share target.
scoped_refptr<network::ResourceRequestBody> ComputeMultipartBody(
const std::vector<std::string>& names,
const std::vector<std::string>& values,
const std::vector<bool>& is_value_file_uri,
const std::vector<std::string>& filenames,
const std::vector<std::string>& types,
const std::string& boundary);
// Compute and return application/x-www-form-urlencoded POST body for share
// target.
std::string ComputeUrlEncodedBody(const std::vector<std::string>& names,
const std::vector<std::string>& values);
// Navigate to share target gurl with |post_data| and |header_list|. // Navigate to share target gurl with |post_data| and |header_list|.
void NavigateShareTargetPost( void NavigateShareTargetPost(
const scoped_refptr<network::ResourceRequestBody>& post_data, const scoped_refptr<network::ResourceRequestBody>& post_data,
......
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("web_share_target") {
sources = [
"target_util.cc",
"target_util.h",
]
deps = [ "//net" ]
public_deps = [
"//base",
"//services/network/public/cpp:cpp_base",
]
}
source_set("unit_tests") {
testonly = true
sources = [ "target_util_unittest.cc" ]
deps = [
":web_share_target",
"//testing/gtest",
]
}
include_rules = [
"+net",
"+services/network",
]
file://chrome/browser/android/webapk/OWNERS
# TEAM: webapk-team@chromium.org
# COMPONENT: Mobile>WebAPKs
This directory contains code shared by the mobile and desktop implementations of
[Web Share Target](https://w3c.github.io/web-share-target/level-2/).
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/web_share_target/target_util.h"
#include <sstream>
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/escape.h"
#include "net/base/mime_util.h"
namespace {
void AddFile(const std::string& value_name,
const std::string& file_uri,
const std::string& file_name,
const std::string& content_type,
const std::string& boundary,
scoped_refptr<network::ResourceRequestBody> result) {
const char delimiter[] = "\r\n";
const size_t delimiter_length = 2;
std::string mime_header;
// First line is the boundary.
mime_header.append("--" + boundary + delimiter);
// Next line is the Content-disposition.
mime_header.append("Content-Disposition: form-data; name=\"" + value_name +
"\"");
if (!file_name.empty()) {
mime_header.append("; filename=\"" + file_name + "\"");
}
mime_header.append(delimiter);
if (!content_type.empty()) {
// If Content-type is specified, the next line is that.
mime_header.append("Content-Type: " + content_type + delimiter);
}
// Leave an empty line before appending the file_uri.
mime_header.append(delimiter);
result->AppendBytes(mime_header.c_str(), mime_header.length());
result->AppendFileRange(
#if defined(OS_WIN)
base::FilePath::FromUTF8Unsafe(file_uri),
#else
base::FilePath(file_uri),
#endif
0, -1, base::Time());
result->AppendBytes(delimiter, delimiter_length);
}
void AddPlainText(const std::string& value_name,
const std::string& value,
const std::string& file_name,
const std::string& content_type,
const std::string& boundary,
scoped_refptr<network::ResourceRequestBody> result) {
std::string item;
if (file_name.empty()) {
net::AddMultipartValueForUpload(value_name, value, boundary, content_type,
&item);
} else {
net::AddMultipartValueForUploadWithFileName(value_name, file_name, value,
boundary, content_type, &item);
}
result->AppendBytes(item.c_str(), item.length());
}
} // namespace
namespace web_share_target {
std::string PercentEscapeString(const std::string& unescaped_string) {
std::ostringstream escaped_oss;
for (char c : unescaped_string) {
if (c == '"') {
escaped_oss << "%22";
} else if (c == 0x0a) {
escaped_oss << "%0A";
} else if (c == 0x0d) {
escaped_oss << "%0D";
} else {
escaped_oss << c;
}
}
return escaped_oss.str();
}
scoped_refptr<network::ResourceRequestBody> ComputeMultipartBody(
const std::vector<std::string>& names,
const std::vector<std::string>& values,
const std::vector<bool>& is_value_file_uris,
const std::vector<std::string>& filenames,
const std::vector<std::string>& types,
const std::string& boundary) {
size_t num_files = names.size();
if (num_files != values.size() || num_files != is_value_file_uris.size() ||
num_files != filenames.size() || num_files != types.size()) {
// The length of all arrays should always be the same for multipart POST.
// This should never happen.
return nullptr;
}
scoped_refptr<network::ResourceRequestBody> result =
new network::ResourceRequestBody();
for (size_t i = 0; i < num_files; i++) {
if (is_value_file_uris[i]) {
AddFile(PercentEscapeString(names[i]), values[i],
PercentEscapeString(filenames[i]), types[i], boundary, result);
} else {
AddPlainText(PercentEscapeString(names[i]), values[i],
PercentEscapeString(filenames[i]), types[i], boundary,
result);
}
}
std::string final_delimiter;
net::AddMultipartFinalDelimiterForUpload(boundary, &final_delimiter);
result->AppendBytes(final_delimiter.c_str(), final_delimiter.length());
return result;
}
std::string ComputeUrlEncodedBody(const std::vector<std::string>& names,
const std::vector<std::string>& values) {
if (names.size() != values.size() || names.size() == 0)
return "";
std::ostringstream application_body_oss;
application_body_oss << net::EscapeUrlEncodedData(names[0], true) << "="
<< net::EscapeUrlEncodedData(values[0], true);
for (size_t i = 1; i < names.size(); i++)
application_body_oss << "&" << net::EscapeUrlEncodedData(names[i], true)
<< "=" << net::EscapeUrlEncodedData(values[i], true);
return application_body_oss.str();
}
} // namespace web_share_target
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEB_SHARE_TARGET_TARGET_UTIL_H_
#define CHROME_BROWSER_WEB_SHARE_TARGET_TARGET_UTIL_H_
#include <string>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "services/network/public/cpp/resource_request_body.h"
namespace web_share_target {
// Return a string as a quoted value, escaping quotes and line breaks.
std::string PercentEscapeString(const std::string& unescaped_string);
// Compute and return multipart/form-data POST body for share target.
scoped_refptr<network::ResourceRequestBody> ComputeMultipartBody(
const std::vector<std::string>& names,
const std::vector<std::string>& values,
const std::vector<bool>& is_value_file_uris,
const std::vector<std::string>& filenames,
const std::vector<std::string>& types,
const std::string& boundary);
// Compute and return application/x-www-form-urlencoded POST body for share
// target.
std::string ComputeUrlEncodedBody(const std::vector<std::string>& names,
const std::vector<std::string>& values);
} // namespace web_share_target
#endif // CHROME_BROWSER_WEB_SHARE_TARGET_TARGET_UTIL_H_
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/android/webapk/webapk_post_share_target_navigator.h" #include "chrome/browser/web_share_target/target_util.h"
#include <string> #include <string>
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace web_share_target {
std::string convertDataElementToString(const network::DataElement& element) { std::string convertDataElementToString(const network::DataElement& element) {
if (element.type() == network::mojom::DataElementType::kBytes) { if (element.type() == network::mojom::DataElementType::kBytes) {
return std::string(element.bytes(), element.length()); return std::string(element.bytes(), element.length());
...@@ -38,7 +40,7 @@ void CheckDataElements( ...@@ -38,7 +40,7 @@ void CheckDataElements(
} }
// Test that multipart/form-data body is empty if inputs are of different sizes. // Test that multipart/form-data body is empty if inputs are of different sizes.
TEST(WebApkPostShareTargetNavigatorTest, InvalidMultipartBody) { TEST(TargetUtilTest, InvalidMultipartBody) {
std::vector<std::string> names = {"name"}; std::vector<std::string> names = {"name"};
std::vector<std::string> values; std::vector<std::string> values;
std::vector<bool> is_value_file_uris; std::vector<bool> is_value_file_uris;
...@@ -46,14 +48,14 @@ TEST(WebApkPostShareTargetNavigatorTest, InvalidMultipartBody) { ...@@ -46,14 +48,14 @@ TEST(WebApkPostShareTargetNavigatorTest, InvalidMultipartBody) {
std::vector<std::string> types; std::vector<std::string> types;
std::string boundary = "boundary"; std::string boundary = "boundary";
scoped_refptr<network::ResourceRequestBody> multipart_body = scoped_refptr<network::ResourceRequestBody> multipart_body =
webapk::ComputeMultipartBody(names, values, is_value_file_uris, filenames, ComputeMultipartBody(names, values, is_value_file_uris, filenames, types,
types, boundary); boundary);
EXPECT_EQ(nullptr, multipart_body.get()); EXPECT_EQ(nullptr, multipart_body.get());
} }
// Test that multipart/form-data body is correctly computed for accepted // Test that multipart/form-data body is correctly computed for accepted
// file inputs. // file inputs.
TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForFile) { TEST(TargetUtilTest, ValidMultipartBodyForFile) {
std::vector<std::string> names = {"share-file\"", "share-file\""}; std::vector<std::string> names = {"share-file\"", "share-file\""};
std::vector<std::string> values = {"mock-file-path", "mock-shared-text"}; std::vector<std::string> values = {"mock-file-path", "mock-shared-text"};
std::vector<bool> is_value_file_uris = {true, false}; std::vector<bool> is_value_file_uris = {true, false};
...@@ -62,8 +64,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForFile) { ...@@ -62,8 +64,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForFile) {
std::vector<std::string> types = {"type", "type"}; std::vector<std::string> types = {"type", "type"};
std::string boundary = "boundary"; std::string boundary = "boundary";
scoped_refptr<network::ResourceRequestBody> multipart_body = scoped_refptr<network::ResourceRequestBody> multipart_body =
webapk::ComputeMultipartBody(names, values, is_value_file_uris, filenames, ComputeMultipartBody(names, values, is_value_file_uris, filenames, types,
types, boundary); boundary);
std::vector<network::mojom::DataElementType> expected_types = { std::vector<network::mojom::DataElementType> expected_types = {
network::mojom::DataElementType::kBytes, network::mojom::DataElementType::kBytes,
...@@ -84,7 +86,7 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForFile) { ...@@ -84,7 +86,7 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForFile) {
} }
// Test that multipart/form-data body is correctly computed for non-file inputs. // Test that multipart/form-data body is correctly computed for non-file inputs.
TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForText) { TEST(TargetUtilTest, ValidMultipartBodyForText) {
std::vector<std::string> names = {"name\""}; std::vector<std::string> names = {"name\""};
std::vector<std::string> values = {"value"}; std::vector<std::string> values = {"value"};
std::vector<bool> is_value_file_uris = {false}; std::vector<bool> is_value_file_uris = {false};
...@@ -92,8 +94,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForText) { ...@@ -92,8 +94,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForText) {
std::vector<std::string> types = {"type"}; std::vector<std::string> types = {"type"};
std::string boundary = "boundary"; std::string boundary = "boundary";
scoped_refptr<network::ResourceRequestBody> multipart_body = scoped_refptr<network::ResourceRequestBody> multipart_body =
webapk::ComputeMultipartBody(names, values, is_value_file_uris, filenames, ComputeMultipartBody(names, values, is_value_file_uris, filenames, types,
types, boundary); boundary);
std::vector<network::mojom::DataElementType> expected_types = { std::vector<network::mojom::DataElementType> expected_types = {
network::mojom::DataElementType::kBytes, network::mojom::DataElementType::kBytes,
...@@ -108,7 +110,7 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForText) { ...@@ -108,7 +110,7 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForText) {
// Test that multipart/form-data body is correctly computed for a mixture // Test that multipart/form-data body is correctly computed for a mixture
// of file and non-file inputs. // of file and non-file inputs.
TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForTextAndFile) { TEST(TargetUtilTest, ValidMultipartBodyForTextAndFile) {
std::vector<std::string> names = {"name1\"", "name2", "name3", std::vector<std::string> names = {"name1\"", "name2", "name3",
"name4", "name5", "name6"}; "name4", "name5", "name6"};
std::vector<std::string> values = {"value1", "file_uri2", "file_uri3", std::vector<std::string> values = {"value1", "file_uri2", "file_uri3",
...@@ -121,9 +123,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForTextAndFile) { ...@@ -121,9 +123,8 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForTextAndFile) {
"type4", "type5", "type6"}; "type4", "type5", "type6"};
std::string boundary = "boundary"; std::string boundary = "boundary";
scoped_refptr<network::ResourceRequestBody> body = scoped_refptr<network::ResourceRequestBody> body = ComputeMultipartBody(
webapk::ComputeMultipartBody(names, values, is_value_file_uris, filenames, names, values, is_value_file_uris, filenames, types, boundary);
types, boundary);
std::vector<network::mojom::DataElementType> expected_types = { std::vector<network::mojom::DataElementType> expected_types = {
// item 1 // item 1
...@@ -173,16 +174,15 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForTextAndFile) { ...@@ -173,16 +174,15 @@ TEST(WebApkPostShareTargetNavigatorTest, ValidMultipartBodyForTextAndFile) {
} }
// Test that multipart/form-data body is properly percent-escaped. // Test that multipart/form-data body is properly percent-escaped.
TEST(WebApkPostShareTargetNavigatorTest, MultipartBodyWithPercentEncoding) { TEST(TargetUtilTest, MultipartBodyWithPercentEncoding) {
std::vector<std::string> names = {"name"}; std::vector<std::string> names = {"name"};
std::vector<std::string> values = {"value"}; std::vector<std::string> values = {"value"};
std::vector<bool> is_value_file_uris = {false}; std::vector<bool> is_value_file_uris = {false};
std::vector<std::string> filenames = {"filename"}; std::vector<std::string> filenames = {"filename"};
std::vector<std::string> types = {"type"}; std::vector<std::string> types = {"type"};
std::string boundary = "boundary"; std::string boundary = "boundary";
scoped_refptr<network::ResourceRequestBody> body = scoped_refptr<network::ResourceRequestBody> body = ComputeMultipartBody(
webapk::ComputeMultipartBody(names, values, is_value_file_uris, filenames, names, values, is_value_file_uris, filenames, types, boundary);
types, boundary);
EXPECT_NE(nullptr, body->elements()); EXPECT_NE(nullptr, body->elements());
std::vector<network::mojom::DataElementType> expected_types = { std::vector<network::mojom::DataElementType> expected_types = {
...@@ -199,39 +199,41 @@ TEST(WebApkPostShareTargetNavigatorTest, MultipartBodyWithPercentEncoding) { ...@@ -199,39 +199,41 @@ TEST(WebApkPostShareTargetNavigatorTest, MultipartBodyWithPercentEncoding) {
// Test that application/x-www-form-urlencoded body is empty if inputs are of // Test that application/x-www-form-urlencoded body is empty if inputs are of
// different sizes. // different sizes.
TEST(WebApkPostShareTargetNavigatorTest, InvalidApplicationBody) { TEST(TargetUtilTest, InvalidApplicationBody) {
std::vector<std::string> names = {"name1", "name2"}; std::vector<std::string> names = {"name1", "name2"};
std::vector<std::string> values = {"value1"}; std::vector<std::string> values = {"value1"};
std::string application_body = webapk::ComputeUrlEncodedBody(names, values); std::string application_body = ComputeUrlEncodedBody(names, values);
EXPECT_EQ("", application_body); EXPECT_EQ("", application_body);
} }
// Test that application/x-www-form-urlencoded body is correctly computed for // Test that application/x-www-form-urlencoded body is correctly computed for
// accepted inputs. // accepted inputs.
TEST(WebApkPostShareTargetNavigatorTest, ValidApplicationBody) { TEST(TargetUtilTest, ValidApplicationBody) {
std::vector<std::string> names = {"name1", "name2"}; std::vector<std::string> names = {"name1", "name2"};
std::vector<std::string> values = {"value1", "value2"}; std::vector<std::string> values = {"value1", "value2"};
std::string application_body = webapk::ComputeUrlEncodedBody(names, values); std::string application_body = ComputeUrlEncodedBody(names, values);
EXPECT_EQ("name1=value1&name2=value2", application_body); EXPECT_EQ("name1=value1&name2=value2", application_body);
} }
// Test that PercentEscapeString correctly escapes quotes to %22. // Test that PercentEscapeString correctly escapes quotes to %22.
TEST(WebApkPostShareTargetNavigatorTest, NeedsPercentEscapeQuote) { TEST(TargetUtilTest, NeedsPercentEscapeQuote) {
EXPECT_EQ("hello%22", webapk::PercentEscapeString("hello\"")); EXPECT_EQ("hello%22", PercentEscapeString("hello\""));
} }
// Test that PercentEscapeString correctly escapes newline to %0A. // Test that PercentEscapeString correctly escapes newline to %0A.
TEST(WebApkPostShareTargetNavigatorTest, NeedsPercentEscape0A) { TEST(TargetUtilTest, NeedsPercentEscape0A) {
EXPECT_EQ("%0A", webapk::PercentEscapeString("\n")); EXPECT_EQ("%0A", PercentEscapeString("\n"));
} }
// Test that PercentEscapeString correctly escapes \r to %0D. // Test that PercentEscapeString correctly escapes \r to %0D.
TEST(WebApkPostShareTargetNavigatorTest, NeedsPercentEscape0D) { TEST(TargetUtilTest, NeedsPercentEscape0D) {
EXPECT_EQ("%0D", webapk::PercentEscapeString("\r")); EXPECT_EQ("%0D", PercentEscapeString("\r"));
} }
// Test that Percent Escape is not performed on strings that don't need to be // Test that Percent Escape is not performed on strings that don't need to be
// escaped. // escaped.
TEST(WebApkPostShareTargetNavigatorTest, NoPercentEscape) { TEST(TargetUtilTest, NoPercentEscape) {
EXPECT_EQ("helloworld", webapk::PercentEscapeString("helloworld")); EXPECT_EQ("helloworld", PercentEscapeString("helloworld"));
} }
} // namespace web_share_target
...@@ -3848,7 +3848,6 @@ test("unit_tests") { ...@@ -3848,7 +3848,6 @@ test("unit_tests") {
"../browser/android/usage_stats/usage_stats_database_unittest.cc", "../browser/android/usage_stats/usage_stats_database_unittest.cc",
"../browser/android/webapk/webapk_icon_hasher_unittest.cc", "../browser/android/webapk/webapk_icon_hasher_unittest.cc",
"../browser/android/webapk/webapk_installer_unittest.cc", "../browser/android/webapk/webapk_installer_unittest.cc",
"../browser/android/webapk/webapk_post_share_target_navigator_unittest.cc",
"../browser/android/webapk/webapk_web_manifest_checker_unittest.cc", "../browser/android/webapk/webapk_web_manifest_checker_unittest.cc",
"../browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc", "../browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc",
"../browser/data_reduction_proxy/data_reduction_proxy_settings_unittest_android.cc", "../browser/data_reduction_proxy/data_reduction_proxy_settings_unittest_android.cc",
...@@ -4132,6 +4131,7 @@ test("unit_tests") { ...@@ -4132,6 +4131,7 @@ test("unit_tests") {
"//chrome/browser/privacy_budget:unit_tests", "//chrome/browser/privacy_budget:unit_tests",
"//chrome/browser/updates/announcement_notification:unit_tests", "//chrome/browser/updates/announcement_notification:unit_tests",
"//chrome/browser/video_tutorials:unit_tests", "//chrome/browser/video_tutorials:unit_tests",
"//chrome/browser/web_share_target:unit_tests",
"//chrome/common:test_support", "//chrome/common:test_support",
"//chrome/common/privacy_budget:unit_tests", "//chrome/common/privacy_budget:unit_tests",
"//chrome/common/profiler:unit_tests", "//chrome/common/profiler:unit_tests",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment