OLD | NEW |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 }; | 67 }; |
68 | 68 |
69 using ScopedHINTERNET = base::ScopedGeneric<HINTERNET, ScopedHINTERNETTraits>; | 69 using ScopedHINTERNET = base::ScopedGeneric<HINTERNET, ScopedHINTERNETTraits>; |
70 | 70 |
71 class HTTPTransportWin final : public HTTPTransport { | 71 class HTTPTransportWin final : public HTTPTransport { |
72 public: | 72 public: |
73 HTTPTransportWin(); | 73 HTTPTransportWin(); |
74 ~HTTPTransportWin() override; | 74 ~HTTPTransportWin() override; |
75 | 75 |
76 bool ExecuteSynchronously() override; | 76 bool ExecuteSynchronously(std::string* response_body) override; |
77 | 77 |
78 private: | 78 private: |
79 DISALLOW_COPY_AND_ASSIGN(HTTPTransportWin); | 79 DISALLOW_COPY_AND_ASSIGN(HTTPTransportWin); |
80 }; | 80 }; |
81 | 81 |
82 HTTPTransportWin::HTTPTransportWin() : HTTPTransport() { | 82 HTTPTransportWin::HTTPTransportWin() : HTTPTransport() { |
83 } | 83 } |
84 | 84 |
85 HTTPTransportWin::~HTTPTransportWin() { | 85 HTTPTransportWin::~HTTPTransportWin() { |
86 } | 86 } |
87 | 87 |
88 bool HTTPTransportWin::ExecuteSynchronously() { | 88 bool HTTPTransportWin::ExecuteSynchronously(std::string* response_body) { |
89 ScopedHINTERNET session( | 89 ScopedHINTERNET session( |
90 WinHttpOpen(base::UTF8ToUTF16(PACKAGE_NAME "/" PACKAGE_VERSION).c_str(), | 90 WinHttpOpen(base::UTF8ToUTF16(PACKAGE_NAME "/" PACKAGE_VERSION).c_str(), |
91 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, | 91 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, |
92 WINHTTP_NO_PROXY_NAME, | 92 WINHTTP_NO_PROXY_NAME, |
93 WINHTTP_NO_PROXY_BYPASS, | 93 WINHTTP_NO_PROXY_BYPASS, |
94 0)); | 94 0)); |
95 if (!session.get()) { | 95 if (!session.get()) { |
96 LogErrorWinHttpMessage("WinHttpOpen"); | 96 LogErrorWinHttpMessage("WinHttpOpen"); |
97 return false; | 97 return false; |
98 } | 98 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 return false; | 147 return false; |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 // We need the Content-Length up front, so buffer in memory. We should modify | 151 // We need the Content-Length up front, so buffer in memory. We should modify |
152 // the interface to not require this, and then use WinHttpWriteData after | 152 // the interface to not require this, and then use WinHttpWriteData after |
153 // WinHttpSendRequest. | 153 // WinHttpSendRequest. |
154 std::vector<uint8_t> post_data; | 154 std::vector<uint8_t> post_data; |
155 | 155 |
156 // Write the body of a POST if any. | 156 // Write the body of a POST if any. |
| 157 const size_t kBufferSize = 4096; |
157 for (;;) { | 158 for (;;) { |
158 uint8_t buffer[4096]; | 159 uint8_t buffer[kBufferSize]; |
159 ssize_t bytes_to_write = | 160 ssize_t bytes_to_write = |
160 body_stream()->GetBytesBuffer(buffer, sizeof(buffer)); | 161 body_stream()->GetBytesBuffer(buffer, sizeof(buffer)); |
161 if (bytes_to_write == 0) | 162 if (bytes_to_write == 0) |
162 break; | 163 break; |
163 post_data.insert(post_data.end(), buffer, buffer + bytes_to_write); | 164 post_data.insert(post_data.end(), buffer, buffer + bytes_to_write); |
164 } | 165 } |
165 | 166 |
166 if (!WinHttpSendRequest(request.get(), | 167 if (!WinHttpSendRequest(request.get(), |
167 WINHTTP_NO_ADDITIONAL_HEADERS, | 168 WINHTTP_NO_ADDITIONAL_HEADERS, |
168 0, | 169 0, |
(...skipping 22 matching lines...) Expand all Loading... |
191 WINHTTP_NO_HEADER_INDEX)) { | 192 WINHTTP_NO_HEADER_INDEX)) { |
192 LogErrorWinHttpMessage("WinHttpQueryHeaders"); | 193 LogErrorWinHttpMessage("WinHttpQueryHeaders"); |
193 return false; | 194 return false; |
194 } | 195 } |
195 | 196 |
196 if (status_code != 200) { | 197 if (status_code != 200) { |
197 LOG(ERROR) << base::StringPrintf("HTTP status %d", status_code); | 198 LOG(ERROR) << base::StringPrintf("HTTP status %d", status_code); |
198 return false; | 199 return false; |
199 } | 200 } |
200 | 201 |
201 // TODO(scottmg): Retrieve body of response if necessary with | 202 if (response_body) { |
202 // WinHttpQueryDataAvailable and WinHttpReadData. | 203 response_body->clear(); |
| 204 |
| 205 // There isn’t any reason to call WinHttpQueryDataAvailable(), because it |
| 206 // returns the number of bytes available to be read without blocking at the |
| 207 // time of the call, not the number of bytes until end-of-file. This method, |
| 208 // which executes synchronously, is only concerned with reading until EOF. |
| 209 DWORD bytes_read = 0; |
| 210 do { |
| 211 char read_buffer[kBufferSize]; |
| 212 if (!WinHttpReadData( |
| 213 request.get(), read_buffer, sizeof(read_buffer), &bytes_read)) { |
| 214 LogErrorWinHttpMessage("WinHttpReadData"); |
| 215 return false; |
| 216 } |
| 217 |
| 218 response_body->append(read_buffer, bytes_read); |
| 219 } while (bytes_read > 0); |
| 220 } |
203 | 221 |
204 return true; | 222 return true; |
205 } | 223 } |
206 | 224 |
207 } // namespace | 225 } // namespace |
208 | 226 |
209 // static | 227 // static |
210 scoped_ptr<HTTPTransport> HTTPTransport::Create() { | 228 scoped_ptr<HTTPTransport> HTTPTransport::Create() { |
211 return scoped_ptr<HTTPTransportWin>(new HTTPTransportWin); | 229 return scoped_ptr<HTTPTransportWin>(new HTTPTransportWin); |
212 } | 230 } |
213 | 231 |
214 } // namespace crashpad | 232 } // namespace crashpad |
OLD | NEW |