HelloRequest sends a Hello request to the Couchbase server, which specifies the client features and capabilities. This is typically the first request sent after connecting to the server. It includes the agent name and a randomly generated connection ID in JSON format.
| 481 | // It includes the agent name and a randomly generated connection ID in JSON |
| 482 | // format. |
| 483 | bool CouchbaseOperations::CouchbaseRequest::helloRequest() { |
| 484 | std::string agent = "brpc/1.0.0 ("; |
| 485 | #ifdef __APPLE__ |
| 486 | agent += "Darwin/"; |
| 487 | #elif defined(__linux__) |
| 488 | agent += "Linux/"; |
| 489 | #else |
| 490 | agent += "UnknownOS/"; |
| 491 | #endif |
| 492 | #if defined(__x86_64__) |
| 493 | agent += "x86_64"; |
| 494 | #elif defined(__aarch64__) |
| 495 | agent += "arm64"; |
| 496 | #else |
| 497 | agent += "unknown"; |
| 498 | #endif |
| 499 | agent += ";bssl/0x1010107f)"; |
| 500 | |
| 501 | // Generate a random connection ID as hex std::string |
| 502 | unsigned char raw_id[CONNECTION_ID_SIZE]; |
| 503 | FILE* urandom = fopen("/dev/urandom", "rb"); |
| 504 | if (!urandom || |
| 505 | fread(raw_id, 1, CONNECTION_ID_SIZE, urandom) != CONNECTION_ID_SIZE) { |
| 506 | if (urandom) fclose(urandom); |
| 507 | DEBUG_PRINT("Failed to generate random connection id"); |
| 508 | return false; |
| 509 | } |
| 510 | fclose(urandom); |
| 511 | char hex_id[RANDOM_ID_HEX_SIZE] = {0}; |
| 512 | for (int i = 0; i < CONNECTION_ID_SIZE; ++i) { |
| 513 | sprintf(hex_id + i * 2, "%02x", raw_id[i]); |
| 514 | } |
| 515 | |
| 516 | // Format key as JSON: {"a":"agent","i":"hex_id"} |
| 517 | std::string key = |
| 518 | std::string("{\"a\":\"") + agent + "\",\"i\":\"" + hex_id + "\"}"; |
| 519 | |
| 520 | const uint16_t key_len = key.size(); |
| 521 | uint16_t features[] = { |
| 522 | butil::HostToNet16(0x0001), // Datatype |
| 523 | butil::HostToNet16(0x0006), // XError |
| 524 | butil::HostToNet16(0x0007), // SelectBucket |
| 525 | butil::HostToNet16(0x000b), // Snappy |
| 526 | butil::HostToNet16(0x0012) // Collections |
| 527 | }; |
| 528 | |
| 529 | const uint32_t value_len = sizeof(features); |
| 530 | const uint32_t total_body_len = key_len + value_len; |
| 531 | |
| 532 | const policy::CouchbaseRequestHeader header = { |
| 533 | policy::CB_MAGIC_REQUEST, |
| 534 | policy::CB_HELLO_SELECT_FEATURES, |
| 535 | butil::HostToNet16(key_len), // key length |
| 536 | 0, // extras length |
| 537 | policy::CB_BINARY_RAW_BYTES, // data type |
| 538 | 0, // vbucket id |
| 539 | butil::HostToNet32(total_body_len), // total body length |
| 540 | 0, // opaque |