| 229 | } |
| 230 | |
| 231 | void THttpTransport::readHeaders() { |
| 232 | // Initialize headers state variables |
| 233 | contentLength_ = 0; |
| 234 | chunked_ = false; |
| 235 | chunkedDone_ = false; |
| 236 | chunkSize_ = 0; |
| 237 | continue_ = false; |
| 238 | |
| 239 | // Control state flow |
| 240 | bool statusLine = true; |
| 241 | bool finished = false; |
| 242 | |
| 243 | // Loop until headers are finished |
| 244 | while (true) { |
| 245 | char* line = readLine(); |
| 246 | |
| 247 | if (strlen(line) == 0) { |
| 248 | if (finished) { |
| 249 | readHeaders_ = false; |
| 250 | break; |
| 251 | } else { |
| 252 | // Must have been an HTTP 100, keep going for another status line |
| 253 | statusLine = true; |
| 254 | } |
| 255 | } else { |
| 256 | if (statusLine) { |
| 257 | VLOG(4) << line; |
| 258 | statusLine = false; |
| 259 | finished = parseStatusLine(line); |
| 260 | } else { |
| 261 | VLOG(4) << " " << line; |
| 262 | parseHeader(line); |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | // Perform any validation of the headers needed. |
| 268 | headersDone(); |
| 269 | |
| 270 | // The headers have been validated, so if the client included the 'Expect: 100-continue" |
| 271 | // header, we respond that it can continue with sending the request. See Section 8.2.3 |
| 272 | // of RFC2616 for more details: https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html |
| 273 | if (continue_) { |
| 274 | std::ostringstream h; |
| 275 | h << "HTTP/1.1 100 Continue" << CRLF << CRLF; |
| 276 | string header = h.str(); |
| 277 | transport_->write( |
| 278 | (const uint8_t*)header.c_str(), static_cast<uint32_t>(header.size())); |
| 279 | transport_->flush(); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | void THttpTransport::write(const uint8_t* buf, uint32_t len) { |
| 284 | writeBuffer_.write(buf, len); |