| 407 | } |
| 408 | |
| 409 | std::shared_ptr<KeeperRequestForSession> IKeeperStateMachine::parseRequest( |
| 410 | nuraft::buffer & data, bool final, ZooKeeperLogSerializationVersion * serialization_version, size_t * request_end_position) |
| 411 | { |
| 412 | ReadBufferFromNuraftBuffer buffer(data); |
| 413 | auto request_for_session = std::make_shared<KeeperRequestForSession>(); |
| 414 | readIntBinary(request_for_session->session_id, buffer); |
| 415 | |
| 416 | int32_t length = 0; |
| 417 | Coordination::read(length, buffer); |
| 418 | /// Request should not exceed max_request_size (this is verified in KeeperTCPHandler) |
| 419 | if (length < 0) |
| 420 | throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid request length: {}", length); |
| 421 | |
| 422 | /// because of backwards compatibility, only 32bit xid could be written |
| 423 | /// for that reason we serialize XID in 2 parts: |
| 424 | /// - lower: 32 least significant bits of 64bit XID OR 32bit XID |
| 425 | /// - upper: 32 most significant bits of 64bit XID |
| 426 | XidHelper xid_helper{}; |
| 427 | Coordination::read(xid_helper.parts.lower, buffer); |
| 428 | |
| 429 | /// go to end of the buffer and read extra information including second part of XID |
| 430 | auto buffer_position = buffer.getPosition(); |
| 431 | buffer.seek(length - sizeof(uint32_t), SEEK_CUR); |
| 432 | |
| 433 | if (request_end_position) |
| 434 | *request_end_position = buffer.getPosition(); |
| 435 | |
| 436 | using enum ZooKeeperLogSerializationVersion; |
| 437 | ZooKeeperLogSerializationVersion version = INITIAL; |
| 438 | |
| 439 | if (!buffer.eof()) |
| 440 | { |
| 441 | version = WITH_TIME; |
| 442 | readIntBinary(request_for_session->time, buffer); |
| 443 | } |
| 444 | else |
| 445 | request_for_session->time |
| 446 | = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); |
| 447 | |
| 448 | if (!buffer.eof()) |
| 449 | { |
| 450 | version = WITH_ZXID_DIGEST; |
| 451 | |
| 452 | readIntBinary(request_for_session->zxid, buffer); |
| 453 | |
| 454 | chassert(!buffer.eof()); |
| 455 | |
| 456 | request_for_session->digest.emplace(); |
| 457 | readIntBinary(request_for_session->digest->version, buffer); |
| 458 | if (request_for_session->digest->version != KeeperDigestVersion::NO_DIGEST || !buffer.eof()) |
| 459 | readIntBinary(request_for_session->digest->value, buffer); |
| 460 | } |
| 461 | |
| 462 | if (!buffer.eof()) |
| 463 | { |
| 464 | version = WITH_XID_64; |
| 465 | Coordination::read(xid_helper.parts.upper, buffer); |
| 466 | } |
no test coverage detected