| 368 | } |
| 369 | |
| 370 | ParseResult ParseThriftMessage(butil::IOBuf* source, |
| 371 | Socket*, bool /*read_eof*/, const void* /*arg*/) { |
| 372 | char header_buf[sizeof(thrift_head_t) + 4]; |
| 373 | const size_t n = source->copy_to(header_buf, sizeof(header_buf)); |
| 374 | if (n < sizeof(header_buf)) { |
| 375 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 376 | } |
| 377 | |
| 378 | const uint32_t sz = ntohl(*(uint32_t*)(header_buf + sizeof(thrift_head_t))); |
| 379 | uint32_t version = sz & THRIFT_HEAD_VERSION_MASK; |
| 380 | if (version != THRIFT_HEAD_VERSION_1) { |
| 381 | RPC_VLOG << "version=" << version |
| 382 | << " doesn't match THRIFT_VERSION=" << THRIFT_HEAD_VERSION_1; |
| 383 | return MakeParseError(PARSE_ERROR_TRY_OTHERS); |
| 384 | } |
| 385 | // suppress strict-aliasing warning |
| 386 | thrift_head_t* head = (thrift_head_t*)header_buf; |
| 387 | const uint32_t body_len = ntohl(head->body_len); |
| 388 | if (body_len > FLAGS_max_body_size) { |
| 389 | return MakeParseError(PARSE_ERROR_TOO_BIG_DATA); |
| 390 | } else if (source->length() < sizeof(thrift_head_t) + body_len) { |
| 391 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 392 | } |
| 393 | |
| 394 | MostCommonMessage* msg = MostCommonMessage::Get(); |
| 395 | source->pop_front(sizeof(thrift_head_t)); |
| 396 | source->cutn(&msg->payload, body_len); |
| 397 | return MakeMessage(msg); |
| 398 | } |
| 399 | |
| 400 | inline void ProcessThriftFramedRequestNoExcept(ThriftService* service, Controller* cntl, |
| 401 | ThriftFramedMessage* req, ThriftFramedMessage* res, |
no test coverage detected