Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: util/net/http_transport_win.cc

Issue 852213004: win: Add implementation of HTTPTransport based on WinHTTP (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@multiproc-impl
Patch Set: check status Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/net/http_transport.h"
16
17 #include <windows.h>
18 #include <winhttp.h>
19
20 #include "base/logging.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "util/net/http_body.h"
24
25 namespace crashpad {
26
27 namespace {
28
29 // PLOG doesn't work for messages from WinHTTP, so we need to use
30 // FORMAT_MESSAGE_FROM_HMODULE + the dll name manually here.
31 void LogErrorWinHttpMessage(const char* extra) {
32 DWORD error_code = GetLastError();
33 const int kErrorMessageBufferSize = 256;
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:25 nit: remove the constant name since it is not used
scottmg 2015/01/21 19:48:27 Done.
34 char msgbuf[kErrorMessageBufferSize];
35 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
36 FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_HMODULE;
37 DWORD len = FormatMessageA(flags,
38 GetModuleHandle(L"winhttp.dll"),
39 error_code,
40 0,
41 msgbuf,
42 arraysize(msgbuf),
43 NULL);
44 if (len) {
45 LOG(ERROR) << extra << ": " << msgbuf
46 << base::StringPrintf(" (0x%X)", error_code);
47 } else {
48 LOG(ERROR) << base::StringPrintf(
49 "Error (0x%X) while retrieving error. (0x%X)",
50 GetLastError(),
51 error_code);
52 }
53 }
54
55 class HTTPTransportWin final : public HTTPTransport {
56 public:
57 HTTPTransportWin();
58 ~HTTPTransportWin() override;
59
60 bool ExecuteSynchronously() override;
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(HTTPTransportWin);
64 };
65
66 HTTPTransportWin::HTTPTransportWin() : HTTPTransport() {
67 }
68
69 HTTPTransportWin::~HTTPTransportWin() {
70 }
71
72 bool HTTPTransportWin::ExecuteSynchronously() {
73 HINTERNET session = WinHttpOpen(L"Crashpad/1.0",
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:25 magic string is magic. do we have the same string
Mark Mentovai 2015/01/21 19:23:17 cpu wrote:
scottmg 2015/01/21 19:48:27 Done.
74 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
75 WINHTTP_NO_PROXY_NAME,
76 WINHTTP_NO_PROXY_BYPASS,
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:24 we'll be fiddling with the proxy setting eventuall
scottmg 2015/01/21 19:48:27 Acknowledged.
77 0);
78 if (!session) {
79 LogErrorWinHttpMessage("WinHttpOpen");
80 return false;
81 }
82
83 URL_COMPONENTS url_components = {0};
84 url_components.dwStructSize = sizeof(URL_COMPONENTS);
85 url_components.dwHostNameLength = 1;
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:24 sample uses -1. I guess any value other than zero?
scottmg 2015/01/21 19:48:27 Yeah, it's a bit crazy, explained here in "Remarks
86 url_components.dwUrlPathLength = 1;
87 url_components.dwExtraInfoLength = 1;
88 std::wstring url_wide(base::UTF8ToUTF16(url()));
89 if (!WinHttpCrackUrl(
90 url_wide.c_str(), 0, ICU_REJECT_USERPWD, &url_components)) {
91 LogErrorWinHttpMessage("WinHttpCrackUrl");
92 return false;
93 }
94 std::wstring host_name(url_components.lpszHostName,
95 url_components.dwHostNameLength);
96 std::wstring url_path(url_components.lpszUrlPath,
97 url_components.dwUrlPathLength);
98 std::wstring extra_info(url_components.lpszExtraInfo,
99 url_components.dwExtraInfoLength);
100
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:25 not using GURL in this project I assume?
scottmg 2015/01/21 19:48:27 Not at the moment. Maybe we should?
101 HINTERNET connect =
102 WinHttpConnect(session, host_name.c_str(), url_components.nPort, 0);
103 if (!connect) {
104 LogErrorWinHttpMessage("WinHttpConnect");
105 return false;
106 }
107
108 HINTERNET request = WinHttpOpenRequest(connect,
109 base::UTF8ToUTF16(method()).c_str(),
110 url_path.c_str(),
111 nullptr,
112 WINHTTP_NO_REFERER,
113 WINHTTP_DEFAULT_ACCEPT_TYPES,
114 0);
115 if (!request) {
116 LogErrorWinHttpMessage("WinHttpOpenRequest");
117 return false;
118 }
119
120 // Add headers to the request.
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:24 if the headers are trusted we are fine. Else we ha
scottmg 2015/01/21 19:48:27 Good point, noted. At the moment it's only used in
121 for (const auto& pair : headers()) {
122 std::wstring header_string =
123 base::UTF8ToUTF16(pair.first) + L": " + base::UTF8ToUTF16(pair.second);
124 if (!WinHttpAddRequestHeaders(request,
125 header_string.c_str(),
126 header_string.size(),
127 WINHTTP_ADDREQ_FLAG_ADD)) {
128 LogErrorWinHttpMessage("WinHttpAddRequestHeaders");
129 return false;
130 }
131 }
132
133 // We need the Content-Length up front, so buffer in memory. We should modify
134 // the interface to not require this, and then use WinHttpWriteData after
135 // WinHttpSendRequest.
136 std::vector<uint8_t> post_data;
137
138 // Write the body of a POST if any.
139 for (;;) {
140 uint8_t buffer[4 << 10];
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:24 rather use the decimal (or hex constant) ? neither
scottmg 2015/01/21 19:48:27 Done.
141 ssize_t bytes_to_write =
142 body_stream()->GetBytesBuffer(buffer, sizeof(buffer));
143 if (bytes_to_write == 0)
144 break;
145 post_data.insert(post_data.end(), buffer, buffer + bytes_to_write);
Mark Mentovai 2015/01/21 19:23:17 Is there no callback-based way to get winhttp to a
scottmg 2015/01/21 19:48:27 It doesn't need the data up front (it can be writt
scottmg 2015/01/21 20:43:59 Hm, actually I have some reading comprehension pro
146 }
147
148 if (!WinHttpSendRequest(request,
149 WINHTTP_NO_ADDITIONAL_HEADERS,
150 0,
151 &post_data[0],
152 post_data.size(),
153 post_data.size(),
154 0)) {
155 LogErrorWinHttpMessage("WinHttpSendRequest");
156 return false;
157 }
158
159 if (!WinHttpReceiveResponse(request, nullptr)) {
160 LogErrorWinHttpMessage("WinHttpReceiveResponse");
161 return false;
162 }
163
164 DWORD status_code = 0;
165 DWORD sizeof_status_code = sizeof(status_code);
166
167 if (!WinHttpQueryHeaders(
168 request,
169 WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
170 WINHTTP_HEADER_NAME_BY_INDEX,
171 &status_code,
172 &sizeof_status_code,
173 WINHTTP_NO_HEADER_INDEX)) {
174 LogErrorWinHttpMessage("WinHttpQueryHeaders");
175 return false;
176 }
177
178 if (status_code != 200) {
179 LOG(ERROR) << base::StringPrintf("HTTP status %d", status_code);
180 return false;
181 }
182
183 // TODO(scottmg): Retrieve body of response if necessary with
184 // WinHttpQueryDataAvailable and WinHttpReadData.
185
cpu_(ooo_6.6-7.5) 2015/01/21 02:26:25 closing the handles only happens here below, not i
Mark Mentovai 2015/01/21 19:23:17 cpu wrote:
scottmg 2015/01/21 19:48:27 Done.
186 if (!WinHttpCloseHandle(request)) {
187 LogErrorWinHttpMessage("WinHttpCloseHandle(request)");
188 return false;
189 }
190 if (!WinHttpCloseHandle(connect)) {
191 LogErrorWinHttpMessage("WinHttpCloseHandle(connect)");
192 return false;
193 }
194 if (!WinHttpCloseHandle(session)) {
195 LogErrorWinHttpMessage("WinHttpCloseHandle(session)");
196 return false;
197 }
198
199 return true;
200 }
201
202 } // namespace
203
204 // static
205 scoped_ptr<HTTPTransport> HTTPTransport::Create() {
206 return scoped_ptr<HTTPTransportWin>(new HTTPTransportWin);
207 }
208
209 } // namespace crashpad
210
Mark Mentovai 2015/01/21 19:23:17 Blank line at EOF.
scottmg 2015/01/21 19:48:27 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698