[go: nahoru, domu]

blob: 8061b9190052bd7eeb63dfc913a48b111c3b944e [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
phajdan.jr@chromium.org95409e12010-08-17 20:07:112// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
phajdan.jr@chromium.org89b32522013-05-07 20:04:215#include "net/test/spawned_test_server/local_test_server.h"
phajdan.jr@chromium.org95409e12010-08-17 20:07:116
7#include <windows.h>
phajdan.jr@chromium.org95409e12010-08-17 20:07:118
9#include "base/base_paths.h"
rsleevi@chromium.org347599952010-10-28 11:57:3610#include "base/command_line.h"
bratell@opera.com656f57ca2013-09-19 09:58:1311#include "base/environment.h"
thestig@chromium.org47163d42013-05-16 02:37:5012#include "base/files/file_path.h"
Avi Drissman41c4a412023-01-11 22:45:3713#include "base/functional/bind.h"
Hans Wennborg725d0432020-06-18 13:54:1614#include "base/logging.h"
Sergey Ulanov3d874d23c2017-08-22 17:36:0215#include "base/path_service.h"
rsesek@chromium.org66c53142013-07-23 14:08:5216#include "base/process/launch.h"
avi@chromium.org4dc3ad4f2013-06-11 07:15:5017#include "base/strings/string_number_conversions.h"
18#include "base/strings/string_util.h"
avi@chromium.org750b2f3c2013-06-07 18:41:0519#include "base/strings/utf_string_conversions.h"
tfarina@chromium.orgb90d7e802011-01-09 16:32:2020#include "base/win/scoped_handle.h"
rsimha@google.com2bbc7f22012-09-12 21:53:1521#include "net/test/python_utils.h"
phajdan.jr@chromium.org95409e12010-08-17 20:07:1122
phajdan.jr@chromium.org95409e12010-08-17 20:07:1123namespace {
24
akalin@chromium.org546e47512010-11-26 03:40:0025// Given a file handle, reads into |buffer| until |bytes_max| bytes
26// has been read or an error has been encountered. Returns
27// true if the read was successful.
Avi Drissman13fc8932015-12-20 04:40:4628bool ReadData(HANDLE read_fd,
29 HANDLE write_fd,
30 DWORD bytes_max,
31 uint8_t* buffer) {
akalin@chromium.org546e47512010-11-26 03:40:0032 DWORD bytes_read = 0;
33 while (bytes_read < bytes_max) {
34 DWORD num_bytes;
35 if (!ReadFile(read_fd, buffer + bytes_read, bytes_max - bytes_read,
Raul Tambre94493c652019-03-11 17:18:3536 &num_bytes, nullptr)) {
akalin@chromium.org546e47512010-11-26 03:40:0037 PLOG(ERROR) << "ReadFile failed";
38 return false;
39 }
40 if (num_bytes <= 0) {
41 LOG(ERROR) << "ReadFile returned invalid byte count: " << num_bytes;
42 return false;
43 }
44 bytes_read += num_bytes;
45 }
46
akalin@chromium.org546e47512010-11-26 03:40:0047 return true;
48}
49
phajdan.jr@chromium.org95409e12010-08-17 20:07:1150} // namespace
51
52namespace net {
rsleevi@chromium.org347599952010-10-28 11:57:3653
David Benjamin76ee79eb2019-03-15 17:02:0954bool LocalTestServer::LaunchPython(
55 const base::FilePath& testserver_path,
56 const std::vector<base::FilePath>& python_path) {
brettw@chromium.org2f3b1cc2014-03-17 23:07:1557 base::CommandLine python_command(base::CommandLine::NO_PROGRAM);
David Benjamin5af020cf2021-09-17 22:59:1958 if (!GetPython3Command(&python_command))
phajdan.jr@chromium.org95409e12010-08-17 20:07:1159 return false;
phajdan.jr@chromium.org95409e12010-08-17 20:07:1160
mattm@chromium.org109bbf02012-09-05 01:24:2961 python_command.AppendArgPath(testserver_path);
rsleevi@chromium.org347599952010-10-28 11:57:3662 if (!AddCommandLineArguments(&python_command))
63 return false;
phajdan.jr@chromium.org95409e12010-08-17 20:07:1164
Raul Tambre94493c652019-03-11 17:18:3565 HANDLE child_read = nullptr;
66 HANDLE child_write = nullptr;
67 if (!CreatePipe(&child_read, &child_write, nullptr, 0)) {
davidben@chromium.org4ce0e742010-09-22 18:15:2368 PLOG(ERROR) << "Failed to create pipe";
69 return false;
70 }
phajdan.jr@chromium.org2f193522010-10-30 09:41:0871 child_read_fd_.Set(child_read);
72 child_write_fd_.Set(child_write);
davidben@chromium.org4ce0e742010-09-22 18:15:2373
74 // Have the child inherit the write half.
shrikantc928d342015-05-12 22:28:5875 if (!::DuplicateHandle(::GetCurrentProcess(), child_write,
76 ::GetCurrentProcess(), &child_write, 0, TRUE,
77 DUPLICATE_SAME_ACCESS)) {
davidben@chromium.org4ce0e742010-09-22 18:15:2378 PLOG(ERROR) << "Failed to enable pipe inheritance";
79 return false;
80 }
81
82 // Pass the handle on the command-line. Although HANDLE is a
83 // pointer, truncating it on 64-bit machines is okay. See
84 // http://msdn.microsoft.com/en-us/library/aa384203.aspx
85 //
86 // "64-bit versions of Windows use 32-bit handles for
87 // interoperability. When sharing a handle between 32-bit and 64-bit
88 // applications, only the lower 32 bits are significant, so it is
89 // safe to truncate the handle (when passing it from 64-bit to
90 // 32-bit) or sign-extend the handle (when passing it from 32-bit to
91 // 64-bit)."
Raul Tambre8c1981d2019-02-08 02:22:2692 python_command.AppendArg(
93 "--startup-pipe=" +
94 base::NumberToString(reinterpret_cast<uintptr_t>(child_write)));
davidben@chromium.org4ce0e742010-09-22 18:15:2395
phajdan.jr@chromium.org86f723ec22011-09-07 21:54:4296 base::LaunchOptions launch_options;
David Benjamin76ee79eb2019-03-15 17:02:0997 SetPythonPathInEnvironment(python_path, &launch_options.environment);
Sergey Ulanov3d874d23c2017-08-22 17:36:0298
99 // Set CWD to source root.
Ho Cheung7dfd9b62023-10-19 17:09:10100 if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT,
Avi Drissman5c80d832018-05-01 17:01:19101 &launch_options.current_directory)) {
Ho Cheung7dfd9b62023-10-19 17:09:10102 LOG(ERROR) << "Failed to get DIR_SRC_TEST_DATA_ROOT";
Sergey Ulanov3d874d23c2017-08-22 17:36:02103 return false;
104 }
105
brettw3c98c7d32017-07-25 01:44:20106 // TODO(brettw) bug 748258: Share only explicit handles.
107 launch_options.inherit_mode = base::LaunchOptions::Inherit::kAll;
rvargasac3c4b6c2014-12-13 00:34:29108 process_ = base::LaunchProcess(python_command, launch_options);
109 if (!process_.IsValid()) {
msw@chromium.org61a4c6f2011-07-20 04:54:52110 LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString();
shrikantc928d342015-05-12 22:28:58111 ::CloseHandle(child_write);
phajdan.jr@chromium.org95409e12010-08-17 20:07:11112 return false;
113 }
114
shrikantc928d342015-05-12 22:28:58115 ::CloseHandle(child_write);
phajdan.jr@chromium.org95409e12010-08-17 20:07:11116 return true;
117}
118
jnd@chromium.org31526822012-03-12 06:04:43119bool LocalTestServer::WaitToStart() {
tfarina@chromium.orgb90d7e802011-01-09 16:32:20120 base::win::ScopedHandle read_fd(child_read_fd_.Take());
121 base::win::ScopedHandle write_fd(child_write_fd_.Take());
akalin@chromium.orgf73ecb02010-11-25 07:54:10122
Avi Drissman13fc8932015-12-20 04:40:46123 uint32_t server_data_len = 0;
akalin@chromium.orgb2cc96d2010-11-27 01:52:52124 if (!ReadData(read_fd.Get(), write_fd.Get(), sizeof(server_data_len),
Avi Drissman13fc8932015-12-20 04:40:46125 reinterpret_cast<uint8_t*>(&server_data_len))) {
akalin@chromium.orgb2cc96d2010-11-27 01:52:52126 LOG(ERROR) << "Could not read server_data_len";
127 return false;
128 }
129 std::string server_data(server_data_len, '\0');
130 if (!ReadData(read_fd.Get(), write_fd.Get(), server_data_len,
Avi Drissman13fc8932015-12-20 04:40:46131 reinterpret_cast<uint8_t*>(&server_data[0]))) {
akalin@chromium.orgb2cc96d2010-11-27 01:52:52132 LOG(ERROR) << "Could not read server_data (" << server_data_len
133 << " bytes)";
akalin@chromium.org546e47512010-11-26 03:40:00134 return false;
akalin@chromium.orgdd8ae4c82010-11-25 11:00:09135 }
akalin@chromium.orgdd8ae4c82010-11-25 11:00:09136
Sergey Ulanov2a0b0192017-08-31 23:09:40137 int port;
138 if (!SetAndParseServerData(server_data, &port)) {
akalin@chromium.orgb2cc96d2010-11-27 01:52:52139 LOG(ERROR) << "Could not parse server_data: " << server_data;
140 return false;
141 }
Sergey Ulanov2a0b0192017-08-31 23:09:40142 SetPort(port);
akalin@chromium.orgb2cc96d2010-11-27 01:52:52143
akalin@chromium.orgf73ecb02010-11-25 07:54:10144 return true;
davidben@chromium.org4ce0e742010-09-22 18:15:23145}
146
phajdan.jr@chromium.org95409e12010-08-17 20:07:11147} // namespace net