| 1555 | } |
| 1556 | |
| 1557 | bool CouchbaseOperations::CouchbaseResponse::popManifest( |
| 1558 | std::string* manifest_json) { |
| 1559 | const size_t n = _buf.size(); |
| 1560 | policy::CouchbaseResponseHeader header; |
| 1561 | if (n < sizeof(header)) { |
| 1562 | butil::string_printf(&_err, "buffer is too small to contain a header"); |
| 1563 | return false; |
| 1564 | } |
| 1565 | _buf.copy_to(&header, sizeof(header)); |
| 1566 | |
| 1567 | if (header.command != policy::CB_GET_COLLECTIONS_MANIFEST) { |
| 1568 | butil::string_printf(&_err, "Not a get collections manifest response"); |
| 1569 | return false; |
| 1570 | } |
| 1571 | |
| 1572 | // Making sure buffer has the whole body (extras + key + value) |
| 1573 | if (n < sizeof(header) + header.total_body_length) { |
| 1574 | butil::string_printf(&_err, "Not enough data"); |
| 1575 | return false; |
| 1576 | } |
| 1577 | |
| 1578 | if (header.status != 0) { |
| 1579 | // handle error case |
| 1580 | if (header.extras_length != 0) { |
| 1581 | DEBUG_PRINT("Get Collections Manifest response must not have extras"); |
| 1582 | } |
| 1583 | if (header.key_length != 0) { |
| 1584 | DEBUG_PRINT("Get Collections Manifest response must not have key"); |
| 1585 | } |
| 1586 | _buf.pop_front(sizeof(header) + header.extras_length + header.key_length); |
| 1587 | // Possibly read error message from value if present |
| 1588 | size_t value_size = |
| 1589 | header.total_body_length - header.extras_length - header.key_length; |
| 1590 | if (value_size > 0) { |
| 1591 | std::string err_msg; |
| 1592 | _buf.cutn(&err_msg, value_size); |
| 1593 | _err = formatErrorMessage(header.status, "Get Collections Manifest", |
| 1594 | err_msg); |
| 1595 | } else { |
| 1596 | _err = formatErrorMessage(header.status, "Get Collections Manifest"); |
| 1597 | } |
| 1598 | return false; |
| 1599 | } |
| 1600 | |
| 1601 | // Success case: the manifest should be in the value section |
| 1602 | size_t value_size = |
| 1603 | header.total_body_length - header.extras_length - header.key_length; |
| 1604 | if (value_size == 0) { |
| 1605 | butil::string_printf(&_err, "No manifest data in response"); |
| 1606 | _buf.pop_front(sizeof(header) + header.total_body_length); |
| 1607 | return false; |
| 1608 | } |
| 1609 | |
| 1610 | // Skip header and any extras/key |
| 1611 | _buf.pop_front(sizeof(header) + header.extras_length + header.key_length); |
| 1612 | |
| 1613 | // Read the manifest JSON from the value section |
| 1614 | _buf.cutn(manifest_json, value_size); |
no test coverage detected