couchbase 3.8.2 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/CMakeLists.txt +16 -1
- data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
- data/ext/cache/extconf_include.rb +6 -6
- data/ext/cache/mozilla-ca-bundle.crt +121 -55
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +136 -23
- data/ext/couchbase/cmake/APKBUILD.in +25 -4
- data/ext/couchbase/cmake/Bundler.cmake +143 -34
- data/ext/couchbase/cmake/CPM.cmake +126 -12
- data/ext/couchbase/cmake/Cache.cmake +7 -1
- data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
- data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
- data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
- data/ext/couchbase/cmake/OpenSSL.cmake +82 -7
- data/ext/couchbase/cmake/Packaging.cmake +519 -65
- data/ext/couchbase/cmake/Protostellar.cmake +250 -0
- data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
- data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
- data/ext/couchbase/cmake/TestFramework.cmake +283 -0
- data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
- data/ext/couchbase/cmake/Testing.cmake +27 -9
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
- data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
- data/ext/couchbase/cmake/build_config.hxx.in +2 -1
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
- data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
- data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
- data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
- data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
- data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
- data/ext/couchbase/cmake/tarball_glob.txt +49 -0
- data/ext/couchbase/core/agent_group.cxx +0 -8
- data/ext/couchbase/core/agent_group.hxx +0 -4
- data/ext/couchbase/core/analytics_stream.cxx +314 -0
- data/ext/couchbase/core/analytics_stream.hxx +129 -0
- data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
- data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
- data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
- data/ext/couchbase/core/bucket.cxx +381 -87
- data/ext/couchbase/core/bucket.hxx +105 -25
- data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
- data/ext/couchbase/core/capella.hxx +91 -0
- data/ext/couchbase/core/cluster.cxx +1551 -397
- data/ext/couchbase/core/cluster.hxx +39 -8
- data/ext/couchbase/core/cluster_agent.cxx +0 -8
- data/ext/couchbase/core/cluster_agent.hxx +0 -4
- data/ext/couchbase/core/cluster_options.hxx +26 -3
- data/ext/couchbase/core/collections_component.cxx +39 -15
- data/ext/couchbase/core/config_profiles.cxx +1 -1
- data/ext/couchbase/core/crud_component.cxx +2 -2
- data/ext/couchbase/core/crud_options.hxx +34 -0
- data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
- data/ext/couchbase/core/document_id_redaction.hxx +81 -0
- data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
- data/ext/couchbase/core/error_context/key_value.cxx +25 -2
- data/ext/couchbase/core/error_context/key_value.hxx +60 -33
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
- data/ext/couchbase/core/error_context/search.hxx +5 -0
- data/ext/couchbase/core/error_context/search_json.hxx +3 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
- data/ext/couchbase/core/error_context/view.hxx +5 -0
- data/ext/couchbase/core/free_form_http_request.cxx +237 -4
- data/ext/couchbase/core/free_form_http_request.hxx +41 -8
- data/ext/couchbase/core/http_component.cxx +300 -284
- data/ext/couchbase/core/http_component.hxx +0 -4
- data/ext/couchbase/core/impl/analytics.cxx +38 -5
- data/ext/couchbase/core/impl/analytics.hxx +34 -0
- data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
- data/ext/couchbase/core/impl/collection.cxx +215 -202
- data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
- data/ext/couchbase/core/impl/error.cxx +22 -2
- data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
- data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
- data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
- data/ext/couchbase/core/impl/node_id.cxx +49 -13
- data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
- data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
- data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
- data/ext/couchbase/core/impl/public_cluster.cxx +229 -42
- data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
- data/ext/couchbase/core/impl/query.cxx +76 -7
- data/ext/couchbase/core/impl/query.hxx +36 -0
- data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
- data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
- data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
- data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
- data/ext/couchbase/core/impl/scope.cxx +70 -0
- data/ext/couchbase/core/impl/search.cxx +31 -1
- data/ext/couchbase/core/impl/transactions.cxx +130 -0
- data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
- data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
- data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
- data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
- data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +1 -2
- data/ext/couchbase/core/io/dns_client.cxx +122 -45
- data/ext/couchbase/core/io/dns_codec.hxx +21 -21
- data/ext/couchbase/core/io/dns_config.cxx +21 -6
- data/ext/couchbase/core/io/http_command.hxx +149 -121
- data/ext/couchbase/core/io/http_error.hxx +107 -0
- data/ext/couchbase/core/io/http_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_session.cxx +606 -154
- data/ext/couchbase/core/io/http_session.hxx +147 -30
- data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
- data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
- data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
- data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
- data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
- data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
- data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
- data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
- data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
- data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
- data/ext/couchbase/core/io/mcbp_session.cxx +309 -301
- data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
- data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
- data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
- data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
- data/ext/couchbase/core/io/streams.cxx +151 -21
- data/ext/couchbase/core/io/streams.hxx +48 -1
- data/ext/couchbase/core/logger/logger.cxx +36 -0
- data/ext/couchbase/core/logger/logger.hxx +46 -6
- data/ext/couchbase/core/logger/redaction.hxx +503 -0
- data/ext/couchbase/core/management/eventing_status.hxx +10 -0
- data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
- data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
- data/ext/couchbase/core/mcbp/codec.cxx +27 -18
- data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
- data/ext/couchbase/core/mcbp/packet.hxx +2 -2
- data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
- data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
- data/ext/couchbase/core/meta/features.hxx +13 -0
- data/ext/couchbase/core/meta/version.cxx +6 -3
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
- data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
- data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
- data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
- data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
- data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
- data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
- data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
- data/ext/couchbase/core/operations/document_query.cxx +108 -221
- data/ext/couchbase/core/operations/document_query.hxx +18 -4
- data/ext/couchbase/core/operations/document_search.cxx +52 -8
- data/ext/couchbase/core/operations/document_search.hxx +3 -0
- data/ext/couchbase/core/operations/document_view.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
- data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
- data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
- data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
- data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
- data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
- data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
- data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/error_utils.cxx +60 -6
- data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
- data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
- data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
- data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
- data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
- data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
- data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
- data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
- data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
- data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
- data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
- data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
- data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
- data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
- data/ext/couchbase/core/operations_fwd.hxx +3 -3
- data/ext/couchbase/core/origin.cxx +54 -26
- data/ext/couchbase/core/origin.hxx +12 -0
- data/ext/couchbase/core/orphan_reporter.cxx +2 -1
- data/ext/couchbase/core/platform/random.cc +7 -7
- data/ext/couchbase/core/protocol/client_request.cxx +2 -2
- data/ext/couchbase/core/protocol/client_request.hxx +38 -21
- data/ext/couchbase/core/protocol/client_response.cxx +11 -3
- data/ext/couchbase/core/protocol/client_response.hxx +27 -6
- data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
- data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
- data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
- data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
- data/ext/couchbase/core/protocol/datatype.hxx +118 -1
- data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
- data/ext/couchbase/core/protocol/magic.hxx +4 -0
- data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/server_request.hxx +3 -1
- data/ext/couchbase/core/protocol/status.cxx +1 -1
- data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
- data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
- data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
- data/ext/couchbase/core/protostellar/component.cxx +2445 -0
- data/ext/couchbase/core/protostellar/component.hxx +391 -0
- data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
- data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
- data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
- data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
- data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
- data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
- data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
- data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
- data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
- data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
- data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
- data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
- data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
- data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
- data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
- data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
- data/ext/couchbase/core/query_stream.cxx +447 -0
- data/ext/couchbase/core/query_stream.hxx +141 -0
- data/ext/couchbase/core/query_stream_component.cxx +243 -0
- data/ext/couchbase/core/query_stream_component.hxx +68 -0
- data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
- data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
- data/ext/couchbase/core/response_handler.hxx +41 -4
- data/ext/couchbase/core/row_streamer.cxx +332 -46
- data/ext/couchbase/core/row_streamer.hxx +31 -1
- data/ext/couchbase/core/row_streamer_options.hxx +55 -0
- data/ext/couchbase/core/sasl/client.h +3 -0
- data/ext/couchbase/core/search_scoring.hxx +66 -0
- data/ext/couchbase/core/stream_error_details.hxx +69 -0
- data/ext/couchbase/core/timeout_defaults.hxx +0 -1
- data/ext/couchbase/core/topology/capabilities.hxx +6 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
- data/ext/couchbase/core/topology/configuration.cxx +21 -6
- data/ext/couchbase/core/topology/configuration.hxx +29 -8
- data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
- data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
- data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
- data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +108 -63
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +19 -2
- data/ext/couchbase/core/transactions/error_list.hxx +2 -2
- data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
- data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
- data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
- data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
- data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
- data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
- data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
- data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
- data/ext/couchbase/core/transactions/transactions.cxx +3 -55
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +165 -72
- data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
- data/ext/couchbase/core/transactions/utils.cxx +10 -0
- data/ext/couchbase/core/transactions/waitable_op_list.hxx +2 -2
- data/ext/couchbase/core/transactions.hxx +9 -9
- data/ext/couchbase/core/utils/byteswap.hxx +166 -9
- data/ext/couchbase/core/utils/connection_string.cxx +50 -85
- data/ext/couchbase/core/utils/connection_string.hxx +15 -0
- data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
- data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
- data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
- data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
- data/ext/couchbase/core/utils/movable_function.hxx +301 -52
- data/ext/couchbase/core/utils/name_codec.hxx +154 -11
- data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
- data/ext/couchbase/core/utils/url_codec.cxx +12 -51
- data/ext/couchbase/core/websocket_codec.cxx +13 -37
- data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
- data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
- data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
- data/ext/couchbase/couchbase/bucket.hxx +57 -0
- data/ext/couchbase/couchbase/cluster.hxx +183 -5
- data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
- data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
- data/ext/couchbase/couchbase/collection.hxx +234 -14
- data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
- data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
- data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
- data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
- data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/error.hxx +32 -0
- data/ext/couchbase/couchbase/error_codes.hxx +33 -1
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
- data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
- data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
- data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
- data/ext/couchbase/couchbase/get_result.hxx +1 -0
- data/ext/couchbase/couchbase/increment_options.hxx +1 -1
- data/ext/couchbase/couchbase/insert_options.hxx +1 -1
- data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/match_query.hxx +1 -1
- data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
- data/ext/couchbase/couchbase/network_options.hxx +1 -1
- data/ext/couchbase/couchbase/node_id.hxx +42 -14
- data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
- data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
- data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
- data/ext/couchbase/couchbase/query_options.hxx +23 -12
- data/ext/couchbase/couchbase/query_row.hxx +111 -0
- data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
- data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/result.hxx +14 -3
- data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
- data/ext/couchbase/couchbase/scope.hxx +85 -2
- data/ext/couchbase/couchbase/search_options.hxx +58 -8
- data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
- data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
- data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
- data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
- data/ext/couchbase/couchbase/transactions.hxx +27 -18
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/vector_query.hxx +1 -1
- data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
- data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
- data/ext/extconf.rb +15 -10
- data/ext/rcb_analytics.cxx +82 -102
- data/ext/rcb_backend.cxx +42 -36
- data/ext/rcb_backend.hxx +2 -0
- data/ext/rcb_buckets.cxx +47 -59
- data/ext/rcb_collections.cxx +42 -52
- data/ext/rcb_crud.cxx +345 -224
- data/ext/rcb_diagnostics.cxx +117 -27
- data/ext/rcb_exceptions.cxx +152 -99
- data/ext/rcb_exceptions.hxx +25 -0
- data/ext/rcb_extras.cxx +18 -19
- data/ext/rcb_hdr_histogram.cxx +19 -4
- data/ext/rcb_logger.cxx +202 -27
- data/ext/rcb_logger.hxx +12 -0
- data/ext/rcb_multi.cxx +40 -40
- data/ext/rcb_observability.cxx +7 -5
- data/ext/rcb_query.cxx +99 -142
- data/ext/rcb_range_scan.cxx +41 -35
- data/ext/rcb_search.cxx +98 -99
- data/ext/rcb_users.cxx +36 -56
- data/ext/rcb_utils.cxx +100 -37
- data/ext/rcb_utils.hxx +287 -33
- data/ext/rcb_version.cxx +1 -1
- data/ext/rcb_views.cxx +55 -51
- data/lib/active_support/cache/couchbase_store.rb +77 -12
- data/lib/couchbase/bucket.rb +20 -0
- data/lib/couchbase/cluster.rb +17 -0
- data/lib/couchbase/collection.rb +36 -1
- data/lib/couchbase/errors.rb +18 -0
- data/lib/couchbase/fork_hooks.rb +16 -7
- data/lib/couchbase/get_replica_strategy.rb +89 -0
- data/lib/couchbase/logger.rb +1 -1
- data/lib/couchbase/management/analytics_index_manager.rb +15 -15
- data/lib/couchbase/management/bucket_manager.rb +6 -6
- data/lib/couchbase/management/collection_manager.rb +6 -6
- data/lib/couchbase/management/query_index_manager.rb +7 -7
- data/lib/couchbase/management/search_index_manager.rb +13 -13
- data/lib/couchbase/management/user_manager.rb +10 -10
- data/lib/couchbase/management/view_index_manager.rb +5 -5
- data/lib/couchbase/options.rb +174 -42
- data/lib/couchbase/protostellar/bucket.rb +4 -0
- data/lib/couchbase/protostellar/cluster.rb +4 -0
- data/lib/couchbase/protostellar/collection.rb +4 -0
- data/lib/couchbase/protostellar/error_handling.rb +2 -1
- data/lib/couchbase/protostellar/request.rb +1 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
- data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
- data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
- data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
- data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
- data/lib/couchbase/search_options.rb +95 -6
- data/lib/couchbase/version.rb +1 -1
- metadata +91 -33
- data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
- data/ext/couchbase/core/columnar/agent.hxx +0 -71
- data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
- data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
- data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
- data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
- data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
- data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
- data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
- data/ext/couchbase/core/columnar/error.hxx +0 -51
- data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
- data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
- data/ext/couchbase/core/columnar/management_component.cxx +0 -300
- data/ext/couchbase/core/columnar/management_component.hxx +0 -56
- data/ext/couchbase/core/columnar/query_component.cxx +0 -523
- data/ext/couchbase/core/columnar/query_component.hxx +0 -57
- data/ext/couchbase/core/columnar/query_options.hxx +0 -59
- data/ext/couchbase/core/columnar/query_result.cxx +0 -130
- data/ext/couchbase/core/columnar/query_result.hxx +0 -78
- data/ext/couchbase/core/io/config_tracker.cxx +0 -687
- data/ext/couchbase/core/io/config_tracker.hxx +0 -123
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2024-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* Log redaction annotations.
|
|
20
|
+
*
|
|
21
|
+
* The SDK never removes or obscures anything itself. It wraps sensitive values in fixed tags so
|
|
22
|
+
* that an external tool can strip or hash them after the fact. Three categories exist:
|
|
23
|
+
*
|
|
24
|
+
* <ud>...</ud> user data document keys and values, application usernames, query statements,
|
|
25
|
+
* email addresses, document xattrs
|
|
26
|
+
* <md>...</md> metadata cluster names, bucket/scope/collection names, design document,
|
|
27
|
+
* view and index names, replication stream names
|
|
28
|
+
* <sd>...</sd> system data IP addresses, hostnames, ports, DNS topology
|
|
29
|
+
*
|
|
30
|
+
* Usage at a log site:
|
|
31
|
+
*
|
|
32
|
+
* CB_LOG_INFO("connecting to {}", logger::system_data(host));
|
|
33
|
+
* CB_LOG_DEBUG("fetching {}", logger::user_data(key));
|
|
34
|
+
*
|
|
35
|
+
* Choosing a category, in order:
|
|
36
|
+
*
|
|
37
|
+
* A literal from this source takes no tag: an opcode name, a status enum, an error code, a
|
|
38
|
+
* duration, a retry count. It reads the same for every deployment and identifies nobody.
|
|
39
|
+
*
|
|
40
|
+
* A secret takes no tag either, because it must not be logged at all: a password, a bearer
|
|
41
|
+
* token, a TLS private key, a SASL payload, a session cookie. A tag would be no protection
|
|
42
|
+
* here, since redaction is off by default and a credential that reaches a log file has already
|
|
43
|
+
* left the process. There is deliberately no wrapper for this case.
|
|
44
|
+
*
|
|
45
|
+
* Otherwise the origin of the value decides. Something the application supplied is user data, a
|
|
46
|
+
* Couchbase resource name is metadata, a host or the network path to it is system data. A value
|
|
47
|
+
* that came from outside the SDK and fits none of the three is user data, because the fallback
|
|
48
|
+
* has to be the strictest category rather than no tag at all.
|
|
49
|
+
*
|
|
50
|
+
* A tag belongs to a log line and nowhere else, so it goes on in the log statement rather than in
|
|
51
|
+
* the code that produced the value. Nothing headed for the wire, into a config, or back to the
|
|
52
|
+
* caller may carry one, which means no getter, no to_json() and no fmt formatter for a core type
|
|
53
|
+
* returns a tagged value: those same functions are reached from places a tag would corrupt.
|
|
54
|
+
* key_value_error_context::to_json() is the case to keep in mind, since couchbase/fmt/error.hxx
|
|
55
|
+
* puts its output into any fmt::format("{}", error) an application writes, with no log statement
|
|
56
|
+
* involved. Leaving the tag to the statement also keeps a bucket name rendering the same way
|
|
57
|
+
* whether the statement got it from config parsing or from a user call. An accessor added to serve
|
|
58
|
+
* a log statement therefore returns its value bare: get_node_addresses() hands back "host:port"
|
|
59
|
+
* and each of the four call sites wraps it.
|
|
60
|
+
*
|
|
61
|
+
* The categories are the ones Couchbase Server's log redaction specification defines, and are not
|
|
62
|
+
* ours to reinterpret. The tool that consumes these tags removes only user data today; removing
|
|
63
|
+
* metadata and system data as well is specified but unreleased. Tagging all three regardless is
|
|
64
|
+
* what makes that a change in the tool rather than an audit of every log statement in the SDK, so
|
|
65
|
+
* a tag being inert today is not a reason to leave it off.
|
|
66
|
+
*
|
|
67
|
+
* A list of values gets one tag per entry rather than one around the whole list, so that an entry
|
|
68
|
+
* still matches the same value logged on its own elsewhere. There is a list form of each category,
|
|
69
|
+
* and it also renders the double quotes some of these lines already carry, because a tag has to sit
|
|
70
|
+
* inside them:
|
|
71
|
+
*
|
|
72
|
+
* CB_LOG_INFO("bootstrap nodes: [{}]",
|
|
73
|
+
* logger::system_data_list(addresses, logger::list_entries::quoted));
|
|
74
|
+
*
|
|
75
|
+
* A serialized document goes the other way: annotate the whole argument, or none of it, but never
|
|
76
|
+
* a value inside it. A tag written into a JSON string value is read back as part of that value by
|
|
77
|
+
* anything that parses the line, and some of what this SDK logs has a shape other tools consume --
|
|
78
|
+
* SDK RFC 0067 fixes the threshold and orphan reports field by field. So the tag sits outside the
|
|
79
|
+
* document. Note that the values inside are still escaped as described below, so this is no longer
|
|
80
|
+
* byte-identical. It is still safe for a consumer that parses the line, because both escapes are
|
|
81
|
+
* JSON's own: "\n" is how JSON spells a newline inside a string, where a literal one is illegal,
|
|
82
|
+
* and "\u003c" is a legal escape for "<". A parser therefore reconstructs the original value
|
|
83
|
+
* exactly, which is what SDK RFC 0067 consumers depend on:
|
|
84
|
+
*
|
|
85
|
+
* CB_LOG_WARNING("Operations over threshold: {}",
|
|
86
|
+
* logger::system_data(utils::json::generate(report)));
|
|
87
|
+
*
|
|
88
|
+
* One tag then has to carry values that may span categories, so pick the strictest category any
|
|
89
|
+
* value inside the document could belong to. The whole document hashes as a single token either
|
|
90
|
+
* way, so what a coarse span costs is diagnosability, not protection. "None of it" is the other
|
|
91
|
+
* legitimate answer, and it is the one the configuration dumps below take.
|
|
92
|
+
*
|
|
93
|
+
* The same holds outside a serialized document: a value that mixes categories takes one tag,
|
|
94
|
+
* around the whole value, at the strictest category it contains. A connection string carries a
|
|
95
|
+
* hostname, a bucket name and a username at once, and an HTTP request path can carry a view's
|
|
96
|
+
* start_key, so both are tagged whole as user data. Reaching inside a value to tag only the part
|
|
97
|
+
* of it that is sensitive is where this feature gets implemented wrong: the boundaries move with
|
|
98
|
+
* the format, and a miss is silent.
|
|
99
|
+
*
|
|
100
|
+
* Two things must never appear inside a tagged value, and the wrappers remove both while redaction
|
|
101
|
+
* is enabled, so that no call site has to remember.
|
|
102
|
+
*
|
|
103
|
+
* A newline. The tool that consumes these tags is line-oriented, so a value that spans lines leaves
|
|
104
|
+
* its opening tag and its closing tag on different lines; the tool reports an unmatched tag and
|
|
105
|
+
* passes the value through in clear text, which is the one failure mode this whole mechanism exists
|
|
106
|
+
* to prevent. Newlines and carriage returns become "\n" and "\r". The values most likely to span
|
|
107
|
+
* lines are HTTP bodies and serialized documents, which is to say exactly the ones that must not
|
|
108
|
+
* leak.
|
|
109
|
+
*
|
|
110
|
+
* A tag sequence. A value containing "</ud>" closes its own span early, and the rest of it is then
|
|
111
|
+
* outside any tag. This is not an attack -- whoever controls the value already knows it -- but it
|
|
112
|
+
* is a silent failure: an application whose document happens to contain one of these sequences
|
|
113
|
+
* hands out a log it believes was redacted. Only the "<" of such a sequence is escaped, and only
|
|
114
|
+
* when it really begins one, so ordinary markup in a logged body stays readable.
|
|
115
|
+
*
|
|
116
|
+
* The exclusion markers below escape neither, because the whole point of not_redacted() is to show
|
|
117
|
+
* the bytes as they are.
|
|
118
|
+
*
|
|
119
|
+
* One shape stays untagged for the opposite reason. A hex dump written with the "{:a}" spec
|
|
120
|
+
* renders as a multi-line grid, so escaping would keep the tag intact but flatten the dump into a
|
|
121
|
+
* single line of "\n" literals, and a flattened hex dump is not a hex dump. So a hex dump is never
|
|
122
|
+
* tagged, and the checker rejects a tag around one. The dumps left in the tree are frame headers
|
|
123
|
+
* and raw socket reads, neither of which carries application data, so they are passed bare rather
|
|
124
|
+
* than marked; the one that could have carried a document body was removed instead of annotated.
|
|
125
|
+
*
|
|
126
|
+
* `bin/check-log-annotations` cannot help with the general case. Whether a value contains a
|
|
127
|
+
* newline is a property of the value at run time, not of the source.
|
|
128
|
+
*
|
|
129
|
+
* Qualify the calls as above. In particular `metadata` is also a member function on several core
|
|
130
|
+
* types (query_result, row_streamer, transaction_get_result), where an unqualified call would
|
|
131
|
+
* resolve to the member instead. In a file whose enclosing namespace is `couchbase` rather than
|
|
132
|
+
* `couchbase::core`, write `core::logger::` instead: a plain `logger::` there finds the public
|
|
133
|
+
* `couchbase::logger` from <couchbase/logger.hxx>, which has none of these functions.
|
|
134
|
+
*
|
|
135
|
+
* When redaction is disabled the wrappers format exactly as the underlying value, so annotating a
|
|
136
|
+
* log statement never changes its output for users who have not opted in.
|
|
137
|
+
*
|
|
138
|
+
* These wrappers hold a reference to the value and are only valid within the enclosing
|
|
139
|
+
* full-expression. That is always the case inside a CB_LOG_* macro. Do not store one:
|
|
140
|
+
*
|
|
141
|
+
* auto tagged = logger::user_data(build_key()); // DANGLING - build_key() is destroyed here
|
|
142
|
+
*
|
|
143
|
+
* Note that CB_LOG_*_RAW bypasses fmt entirely and cannot carry annotations, and CB_LOG_PROTOCOL
|
|
144
|
+
* is deliberately not redacted. The configuration dumps behind the dump_configuration option are
|
|
145
|
+
* left unannotated for the same reason: both exist to show exactly what crossed the wire, and both
|
|
146
|
+
* are opt-in debugging aids rather than something a deployment leaves on. Each of those sites says
|
|
147
|
+
* so with logger::not_redacted(), so the choice is visible where the dump is written.
|
|
148
|
+
*
|
|
149
|
+
* `bin/check-log-annotations` reports log arguments that look sensitive but are not wrapped. It is
|
|
150
|
+
* a heuristic over argument names, so it suggests rather than decides. It cannot see a value that
|
|
151
|
+
* was tagged anywhere other than the log site, which is why the list forms above exist as named
|
|
152
|
+
* wrappers rather than as a helper per file: the checker recognises the name and counts the
|
|
153
|
+
* argument as annotated, instead of having to be told to look away from it.
|
|
154
|
+
*
|
|
155
|
+
* Two wrappers record a reviewed exclusion:
|
|
156
|
+
*
|
|
157
|
+
* logger::not_sensitive(value) the identifier suggests a category the value does not belong to
|
|
158
|
+
* logger::not_redacted(value) sensitive, and deliberately logged untagged anyway
|
|
159
|
+
*
|
|
160
|
+
* Neither changes what is printed. Prefer them to the `no-redact` comment the checker also honours,
|
|
161
|
+
* which silences a whole log statement and so also silences arguments added to it later.
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
#pragma once
|
|
165
|
+
|
|
166
|
+
#include "logger.hxx"
|
|
167
|
+
|
|
168
|
+
#include <spdlog/fmt/bundled/core.h>
|
|
169
|
+
#include <spdlog/fmt/bundled/format.h>
|
|
170
|
+
|
|
171
|
+
#include <cstddef>
|
|
172
|
+
#include <string>
|
|
173
|
+
#include <string_view>
|
|
174
|
+
|
|
175
|
+
namespace couchbase::core::logger
|
|
176
|
+
{
|
|
177
|
+
|
|
178
|
+
template<typename T>
|
|
179
|
+
struct redacted_user_data {
|
|
180
|
+
const T& value;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
template<typename T>
|
|
184
|
+
struct redacted_meta_data {
|
|
185
|
+
const T& value;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
template<typename T>
|
|
189
|
+
struct redacted_system_data {
|
|
190
|
+
const T& value;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
template<typename T>
|
|
194
|
+
struct conditionally_redacted_user_data {
|
|
195
|
+
const T& value;
|
|
196
|
+
bool sensitive;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
template<typename T>
|
|
200
|
+
struct not_sensitive_value {
|
|
201
|
+
const T& value;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
template<typename T>
|
|
205
|
+
struct not_redacted_value {
|
|
206
|
+
const T& value;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Tag a value as user data (<ud>): document keys and values, application usernames, query
|
|
211
|
+
* statements, email addresses, document xattrs.
|
|
212
|
+
*/
|
|
213
|
+
template<typename T>
|
|
214
|
+
auto
|
|
215
|
+
user_data(const T& value)
|
|
216
|
+
{
|
|
217
|
+
return redacted_user_data<T>{ value };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Tag a value as metadata (<md>): cluster, bucket, scope and collection names, design document,
|
|
222
|
+
* view and index names, and other Couchbase resource names.
|
|
223
|
+
*/
|
|
224
|
+
template<typename T>
|
|
225
|
+
auto
|
|
226
|
+
metadata(const T& value)
|
|
227
|
+
{
|
|
228
|
+
return redacted_meta_data<T>{ value };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Tag a value as system data (<sd>): IP addresses, hostnames, ports and DNS topology.
|
|
233
|
+
*/
|
|
234
|
+
template<typename T>
|
|
235
|
+
auto
|
|
236
|
+
system_data(const T& value)
|
|
237
|
+
{
|
|
238
|
+
return redacted_system_data<T>{ value };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Tag a value as user data (<ud>) only when `sensitive` holds, and print it unchanged otherwise.
|
|
243
|
+
*
|
|
244
|
+
* For an argument that is sensitive on one branch of a log statement and a constant on another.
|
|
245
|
+
* Tagging the constant hashes it to a fixed digest, which protects nothing -- the domain is one
|
|
246
|
+
* value, so anyone holding the salt recovers it immediately -- and costs the reader the diagnostic
|
|
247
|
+
* the constant was there to give. A body the SDK elided to "[hidden]" and a body it redacted are
|
|
248
|
+
* then indistinguishable in the output.
|
|
249
|
+
*/
|
|
250
|
+
template<typename T>
|
|
251
|
+
auto
|
|
252
|
+
user_data_if(bool sensitive, const T& value)
|
|
253
|
+
{
|
|
254
|
+
return conditionally_redacted_user_data<T>{ value, sensitive };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Mark a value the annotation checker flags but that is not sensitive, because the identifier
|
|
259
|
+
* suggests a category the value does not belong to. Formats exactly as the value would unwrapped,
|
|
260
|
+
* so this is an assertion for the reader and for the checker rather than a change in behaviour.
|
|
261
|
+
*/
|
|
262
|
+
template<typename T>
|
|
263
|
+
auto
|
|
264
|
+
not_sensitive(const T& value)
|
|
265
|
+
{
|
|
266
|
+
return not_sensitive_value<T>{ value };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Mark a sensitive value that is deliberately logged without a tag, because wrapping it here is
|
|
271
|
+
* either not possible or not wanted. Formats exactly as the value would unwrapped. Unlike
|
|
272
|
+
* not_sensitive() this asserts nothing about the content, so say at the call site why the value
|
|
273
|
+
* carries no tag, and reference a ticket when the answer is that it eventually should.
|
|
274
|
+
*/
|
|
275
|
+
template<typename T>
|
|
276
|
+
auto
|
|
277
|
+
not_redacted(const T& value)
|
|
278
|
+
{
|
|
279
|
+
return not_redacted_value<T>{ value };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Whether the entries of a tagged list render inside double quotes. The tag sits inside the quotes,
|
|
284
|
+
* never around them: a span that swallows the punctuation hashes to something matching no other
|
|
285
|
+
* line in the log.
|
|
286
|
+
*/
|
|
287
|
+
enum class list_entries {
|
|
288
|
+
bare,
|
|
289
|
+
quoted,
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
namespace detail
|
|
293
|
+
{
|
|
294
|
+
/*
|
|
295
|
+
* The tag sequences themselves, which must not survive inside a tagged value: a value carrying one
|
|
296
|
+
* would close its own span early, and whatever followed would sit outside any tag.
|
|
297
|
+
*/
|
|
298
|
+
inline constexpr std::string_view tag_sequences[]{
|
|
299
|
+
"<ud>", "</ud>", "<md>", "</md>", "<sd>", "</sd>",
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
constexpr auto
|
|
303
|
+
opens_tag_sequence(std::string_view value) -> bool
|
|
304
|
+
{
|
|
305
|
+
for (const auto sequence : tag_sequences) {
|
|
306
|
+
if (value.substr(0, sequence.size()) == sequence) {
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/*
|
|
314
|
+
* Replace what would otherwise break the span around a value.
|
|
315
|
+
*
|
|
316
|
+
* A newline splits it: the consumer of these tags is line-oriented, so an embedded newline leaves
|
|
317
|
+
* the opening tag and the closing tag on different lines, and the value is then passed through
|
|
318
|
+
* untouched instead of being redacted. A tag sequence inside the value closes the span early, with
|
|
319
|
+
* the same result for whatever follows it. Only the "<" of such a sequence is escaped, which is
|
|
320
|
+
* enough to break it; escaping it to "\<" would not be, because "\</ud>" still contains "</ud>".
|
|
321
|
+
*
|
|
322
|
+
* A "<" that does not begin a tag sequence is left alone, so ordinary markup in a logged body is
|
|
323
|
+
* still readable.
|
|
324
|
+
*/
|
|
325
|
+
template<typename OutputIt>
|
|
326
|
+
auto
|
|
327
|
+
write_escaped(OutputIt out, std::string_view value) -> OutputIt
|
|
328
|
+
{
|
|
329
|
+
// std::copy is deliberately not used here. fmt's appender does not satisfy MSVC's
|
|
330
|
+
// iterator_traits requirements, so std::copy over it fails to compile on Windows.
|
|
331
|
+
std::size_t copied = 0;
|
|
332
|
+
for (std::size_t index = 0; index < value.size(); ++index) {
|
|
333
|
+
std::string_view replacement{};
|
|
334
|
+
switch (value[index]) {
|
|
335
|
+
case '\n':
|
|
336
|
+
replacement = "\\n";
|
|
337
|
+
break;
|
|
338
|
+
case '\r':
|
|
339
|
+
replacement = "\\r";
|
|
340
|
+
break;
|
|
341
|
+
case '<':
|
|
342
|
+
if (!opens_tag_sequence(value.substr(index))) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
replacement = "\\u003c";
|
|
346
|
+
break;
|
|
347
|
+
default:
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
out = fmt::format_to(out, "{}{}", value.substr(copied, index - copied), replacement);
|
|
351
|
+
copied = index + 1;
|
|
352
|
+
}
|
|
353
|
+
return fmt::format_to(out, "{}", value.substr(copied));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
template<typename Container, typename Wrap>
|
|
357
|
+
auto
|
|
358
|
+
tagged_list(const Container& values, list_entries entries, std::string_view separator, Wrap wrap)
|
|
359
|
+
-> std::string
|
|
360
|
+
{
|
|
361
|
+
std::string result;
|
|
362
|
+
auto first = true;
|
|
363
|
+
for (const auto& value : values) {
|
|
364
|
+
if (!first) {
|
|
365
|
+
result.append(separator);
|
|
366
|
+
}
|
|
367
|
+
first = false;
|
|
368
|
+
if (entries == list_entries::quoted) {
|
|
369
|
+
result.append(fmt::format(R"("{}")", wrap(value)));
|
|
370
|
+
} else {
|
|
371
|
+
result.append(fmt::format("{}", wrap(value)));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
} // namespace detail
|
|
377
|
+
|
|
378
|
+
/*
|
|
379
|
+
* Tag every entry of a container and join them, so a list correlates entry by entry. One tag around
|
|
380
|
+
* the joined string would hash the whole list as a single token, matching nothing else in the log,
|
|
381
|
+
* not even the same value logged beside it in a span of its own.
|
|
382
|
+
*
|
|
383
|
+
* Unlike the wrappers above, these return a std::string rather than a view of the value, because
|
|
384
|
+
* there is nothing to view: the tagged entries do not exist until they are built. Call them inside
|
|
385
|
+
* the CB_LOG_* argument list, so they stay as lazy as the statement that needs them.
|
|
386
|
+
*/
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Tag each entry of a container as user data (<ud>) and join them.
|
|
390
|
+
*/
|
|
391
|
+
template<typename Container>
|
|
392
|
+
auto
|
|
393
|
+
user_data_list(const Container& values,
|
|
394
|
+
list_entries entries = list_entries::bare,
|
|
395
|
+
std::string_view separator = ", ") -> std::string
|
|
396
|
+
{
|
|
397
|
+
return detail::tagged_list(values, entries, separator, [](const auto& value) {
|
|
398
|
+
return user_data(value);
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Tag each entry of a container as metadata (<md>) and join them.
|
|
404
|
+
*/
|
|
405
|
+
template<typename Container>
|
|
406
|
+
auto
|
|
407
|
+
metadata_list(const Container& values,
|
|
408
|
+
list_entries entries = list_entries::bare,
|
|
409
|
+
std::string_view separator = ", ") -> std::string
|
|
410
|
+
{
|
|
411
|
+
return detail::tagged_list(values, entries, separator, [](const auto& value) {
|
|
412
|
+
return metadata(value);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Tag each entry of a container as system data (<sd>) and join them.
|
|
418
|
+
*/
|
|
419
|
+
template<typename Container>
|
|
420
|
+
auto
|
|
421
|
+
system_data_list(const Container& values,
|
|
422
|
+
list_entries entries = list_entries::bare,
|
|
423
|
+
std::string_view separator = ", ") -> std::string
|
|
424
|
+
{
|
|
425
|
+
return detail::tagged_list(values, entries, separator, [](const auto& value) {
|
|
426
|
+
return system_data(value);
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
} // namespace couchbase::core::logger
|
|
431
|
+
|
|
432
|
+
#ifndef COUCHBASE_CXX_CLIENT_DOXYGEN
|
|
433
|
+
/*
|
|
434
|
+
* The formatters inherit parse() from the underlying formatter, so format specifications keep
|
|
435
|
+
* working. Note that a specification applies to the value only, so "{:>10}" pads inside the tags.
|
|
436
|
+
*/
|
|
437
|
+
#define COUCHBASE_LOGGER_REDACTION_FORMATTER(wrapper, tag) \
|
|
438
|
+
template<typename T> \
|
|
439
|
+
struct fmt::formatter<couchbase::core::logger::wrapper<T>> : fmt::formatter<T> { \
|
|
440
|
+
template<typename FormatContext> \
|
|
441
|
+
auto format(const couchbase::core::logger::wrapper<T>& redacted, FormatContext& ctx) const \
|
|
442
|
+
{ \
|
|
443
|
+
if (!couchbase::core::logger::is_log_redaction_enabled()) { \
|
|
444
|
+
return fmt::formatter<T>::format(redacted.value, ctx); \
|
|
445
|
+
} \
|
|
446
|
+
fmt::memory_buffer buffer; \
|
|
447
|
+
/* The caller's arguments come along: a dynamic specification such as "{:{}}" resolves its \
|
|
448
|
+
* width through the context, so an empty argument store would throw here while the \
|
|
449
|
+
* unredacted branch worked. */ \
|
|
450
|
+
fmt::basic_format_context<fmt::appender, char> buffered{ fmt::appender(buffer), \
|
|
451
|
+
ctx.args(), \
|
|
452
|
+
ctx.locale() }; \
|
|
453
|
+
fmt::formatter<T>::format(redacted.value, buffered); \
|
|
454
|
+
ctx.advance_to(fmt::format_to(ctx.out(), "<" tag ">")); \
|
|
455
|
+
ctx.advance_to(couchbase::core::logger::detail::write_escaped( \
|
|
456
|
+
ctx.out(), std::string_view{ buffer.data(), buffer.size() })); \
|
|
457
|
+
return fmt::format_to(ctx.out(), "</" tag ">"); \
|
|
458
|
+
} \
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
COUCHBASE_LOGGER_REDACTION_FORMATTER(redacted_user_data, "ud");
|
|
462
|
+
COUCHBASE_LOGGER_REDACTION_FORMATTER(redacted_meta_data, "md");
|
|
463
|
+
COUCHBASE_LOGGER_REDACTION_FORMATTER(redacted_system_data, "sd");
|
|
464
|
+
|
|
465
|
+
#undef COUCHBASE_LOGGER_REDACTION_FORMATTER
|
|
466
|
+
|
|
467
|
+
/*
|
|
468
|
+
* Reuses the <ud> formatter for the tagged branch rather than repeating it, so the two cannot
|
|
469
|
+
* drift apart on escaping or on what a disabled redaction level prints.
|
|
470
|
+
*/
|
|
471
|
+
template<typename T>
|
|
472
|
+
struct fmt::formatter<couchbase::core::logger::conditionally_redacted_user_data<T>>
|
|
473
|
+
: fmt::formatter<couchbase::core::logger::redacted_user_data<T>> {
|
|
474
|
+
template<typename FormatContext>
|
|
475
|
+
auto format(const couchbase::core::logger::conditionally_redacted_user_data<T>& redacted,
|
|
476
|
+
FormatContext& ctx) const
|
|
477
|
+
{
|
|
478
|
+
if (!redacted.sensitive) {
|
|
479
|
+
return fmt::formatter<T>::format(redacted.value, ctx);
|
|
480
|
+
}
|
|
481
|
+
return fmt::formatter<couchbase::core::logger::redacted_user_data<T>>::format(
|
|
482
|
+
couchbase::core::logger::redacted_user_data<T>{ redacted.value }, ctx);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
/*
|
|
487
|
+
* The exclusion markers print their value and nothing else, whether or not redaction is enabled.
|
|
488
|
+
*/
|
|
489
|
+
#define COUCHBASE_LOGGER_EXCLUSION_FORMATTER(wrapper) \
|
|
490
|
+
template<typename T> \
|
|
491
|
+
struct fmt::formatter<couchbase::core::logger::wrapper<T>> : fmt::formatter<T> { \
|
|
492
|
+
template<typename FormatContext> \
|
|
493
|
+
auto format(const couchbase::core::logger::wrapper<T>& marked, FormatContext& ctx) const \
|
|
494
|
+
{ \
|
|
495
|
+
return fmt::formatter<T>::format(marked.value, ctx); \
|
|
496
|
+
} \
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
COUCHBASE_LOGGER_EXCLUSION_FORMATTER(not_sensitive_value);
|
|
500
|
+
COUCHBASE_LOGGER_EXCLUSION_FORMATTER(not_redacted_value);
|
|
501
|
+
|
|
502
|
+
#undef COUCHBASE_LOGGER_EXCLUSION_FORMATTER
|
|
503
|
+
#endif
|
|
@@ -54,6 +54,16 @@ enum class function_status {
|
|
|
54
54
|
* The function is currently being paused.
|
|
55
55
|
*/
|
|
56
56
|
pausing,
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The function is currently being resumed, after having been paused.
|
|
60
|
+
*/
|
|
61
|
+
resuming,
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The server reported an unrecognized function status.
|
|
65
|
+
*/
|
|
66
|
+
unknown,
|
|
57
67
|
};
|
|
58
68
|
|
|
59
69
|
enum class function_deployment_status {
|
|
@@ -72,6 +72,10 @@ struct traits<couchbase::core::management::eventing::status> {
|
|
|
72
72
|
function.status = couchbase::core::management::eventing::function_status::paused;
|
|
73
73
|
} else if (composite_status == "pausing") {
|
|
74
74
|
function.status = couchbase::core::management::eventing::function_status::pausing;
|
|
75
|
+
} else if (composite_status == "resuming") {
|
|
76
|
+
function.status = couchbase::core::management::eventing::function_status::resuming;
|
|
77
|
+
} else {
|
|
78
|
+
function.status = couchbase::core::management::eventing::function_status::unknown;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
if (const auto* function_scope = app.find("function_scope");
|
|
@@ -75,7 +75,7 @@ void
|
|
|
75
75
|
put_uint64(gsl::span<std::byte> bytes, std::uint64_t value)
|
|
76
76
|
{
|
|
77
77
|
for (std::size_t i = 0; i < 8; ++i) {
|
|
78
|
-
bytes[i] = static_cast<std::byte>(value >> (56 - i * 8));
|
|
78
|
+
bytes[i] = static_cast<std::byte>(value >> (56 - (i * 8)));
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
} // namespace couchbase::core::mcbp::big_endian
|
|
@@ -76,8 +76,7 @@ codec::encode_packet(const couchbase::core::mcbp::packet& packet) const
|
|
|
76
76
|
// It also doesn't expect the collection ID to be leb encoded.
|
|
77
77
|
extras.resize(sizeof(std::uint32_t));
|
|
78
78
|
big_endian::put_uint32(extras, packet.collection_id_);
|
|
79
|
-
}
|
|
80
|
-
if (packet.collection_id_ > 0) {
|
|
79
|
+
} else if (packet.collection_id_ > 0) {
|
|
81
80
|
CB_LOG_DEBUG("cannot encode collection id with a non-collection command");
|
|
82
81
|
return tl::unexpected(errc::common::invalid_argument);
|
|
83
82
|
}
|
|
@@ -432,11 +431,11 @@ codec::decode_packet(gsl::span<std::byte> header, gsl::span<std::byte> body) con
|
|
|
432
431
|
} else if (frame_type == mcbp::request_sync_durability &&
|
|
433
432
|
(frame_len == 1 || frame_len == 3)) {
|
|
434
433
|
pkt.durability_level_frame_ = mcbp::durability_level_frame{
|
|
435
|
-
static_cast<mcbp::durability_level>(body[frame_offset])
|
|
434
|
+
static_cast<mcbp::durability_level>(body[frame_offset]),
|
|
436
435
|
};
|
|
437
436
|
if (frame_len == 3) {
|
|
438
437
|
pkt.durability_timeout_frame_ = mcbp::durability_timeout_frame{
|
|
439
|
-
std::chrono::milliseconds{ big_endian::read_uint16(body, frame_offset + 1) }
|
|
438
|
+
std::chrono::milliseconds{ big_endian::read_uint16(body, frame_offset + 1) },
|
|
440
439
|
};
|
|
441
440
|
} else {
|
|
442
441
|
// We follow the semantic that duplicate frames overwrite previous ones, since the
|
|
@@ -445,39 +444,49 @@ codec::decode_packet(gsl::span<std::byte> header, gsl::span<std::byte> body) con
|
|
|
445
444
|
pkt.durability_timeout_frame_.reset();
|
|
446
445
|
}
|
|
447
446
|
} else if (frame_type == mcbp::request_stream_id && frame_len == 2) {
|
|
448
|
-
pkt.stream_id_frame_ =
|
|
449
|
-
|
|
447
|
+
pkt.stream_id_frame_ = mcbp::stream_id_frame{
|
|
448
|
+
big_endian::read_uint16(body, frame_offset),
|
|
449
|
+
};
|
|
450
450
|
} else if (frame_type == mcbp::request_open_tracing && frame_len > 0) {
|
|
451
|
-
pkt.open_tracing_frame_ =
|
|
452
|
-
|
|
451
|
+
pkt.open_tracing_frame_ = mcbp::open_tracing_frame{
|
|
452
|
+
big_endian::read(body, frame_offset, frame_len),
|
|
453
|
+
};
|
|
453
454
|
} else if (frame_type == mcbp::request_preserve_expiry && frame_len == 0) {
|
|
454
455
|
pkt.preserve_expiry_frame_ = mcbp::preserve_expiry_frame{};
|
|
455
456
|
} else if (frame_type == mcbp::request_user_impersonation && frame_len > 0) {
|
|
456
|
-
pkt.user_impersonation_frame_ =
|
|
457
|
-
|
|
457
|
+
pkt.user_impersonation_frame_ = mcbp::user_impersonation_frame{
|
|
458
|
+
big_endian::read(body, frame_offset, frame_len),
|
|
459
|
+
};
|
|
458
460
|
} else {
|
|
459
461
|
// If we don't understand this frame type, we record it as an UnsupportedFrame (as
|
|
460
462
|
// opposed to dropping it blindly)
|
|
461
463
|
pkt.unsupported_frames_.emplace_back(mcbp::unsupported_frame{
|
|
462
|
-
frame_type,
|
|
464
|
+
frame_type,
|
|
465
|
+
big_endian::read(body, frame_offset, frame_len),
|
|
466
|
+
});
|
|
463
467
|
}
|
|
464
468
|
break;
|
|
465
469
|
|
|
466
470
|
case protocol::magic::alt_client_response:
|
|
467
471
|
if (frame_type == mcbp::response_server_duration && frame_len == 2) {
|
|
468
|
-
pkt.server_duration_frame_ = mcbp::server_duration_frame{
|
|
469
|
-
big_endian::read_uint16(body, frame_offset))
|
|
472
|
+
pkt.server_duration_frame_ = mcbp::server_duration_frame{
|
|
473
|
+
mcbp::decode_server_duration(big_endian::read_uint16(body, frame_offset)),
|
|
474
|
+
};
|
|
470
475
|
} else if (frame_type == mcbp::response_read_units && frame_len == 2) {
|
|
471
|
-
pkt.read_units_frame_ =
|
|
472
|
-
|
|
476
|
+
pkt.read_units_frame_ = mcbp::read_units_frame{
|
|
477
|
+
big_endian::read_uint16(body, frame_offset),
|
|
478
|
+
};
|
|
473
479
|
} else if (frame_type == mcbp::response_write_units && frame_len == 2) {
|
|
474
|
-
pkt.write_units_frame_ =
|
|
475
|
-
|
|
480
|
+
pkt.write_units_frame_ = mcbp::write_units_frame{
|
|
481
|
+
big_endian::read_uint16(body, frame_offset),
|
|
482
|
+
};
|
|
476
483
|
} else {
|
|
477
484
|
// If we don't understand this frame type, we record it as an UnsupportedFrame (as
|
|
478
485
|
// opposed to dropping it blindly)
|
|
479
486
|
pkt.unsupported_frames_.emplace_back(mcbp::unsupported_frame{
|
|
480
|
-
frame_type,
|
|
487
|
+
frame_type,
|
|
488
|
+
big_endian::read(body, frame_offset, frame_len),
|
|
489
|
+
});
|
|
481
490
|
}
|
|
482
491
|
break;
|
|
483
492
|
|
|
@@ -77,7 +77,7 @@ operation_queue::push(std::shared_ptr<queue_request> request,
|
|
|
77
77
|
return errc::network::operation_queue_full;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
if (operation_queue
|
|
80
|
+
if (operation_queue* no_queue{ nullptr };
|
|
81
81
|
!request->queued_with_.compare_exchange_strong(no_queue, this)) {
|
|
82
82
|
return errc::network::request_already_queued;
|
|
83
83
|
}
|
|
@@ -102,7 +102,7 @@ operation_queue::remove(const std::shared_ptr<queue_request>& request) -> bool
|
|
|
102
102
|
return false;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
if (operation_queue
|
|
105
|
+
if (operation_queue* this_queue{ this };
|
|
106
106
|
!request->queued_with_.compare_exchange_strong(this_queue, nullptr)) {
|
|
107
107
|
return false;
|
|
108
108
|
}
|
|
@@ -43,8 +43,8 @@ class packet
|
|
|
43
43
|
public:
|
|
44
44
|
[[nodiscard]] auto debug_string() const -> std::string;
|
|
45
45
|
|
|
46
|
-
protocol::magic magic_;
|
|
47
|
-
protocol::client_opcode command_;
|
|
46
|
+
protocol::magic magic_{ protocol::magic::invalid };
|
|
47
|
+
protocol::client_opcode command_{ protocol::client_opcode::invalid };
|
|
48
48
|
std::byte datatype_{};
|
|
49
49
|
std::uint16_t status_{ 0x00 };
|
|
50
50
|
key_value_status_code status_code_{ key_value_status_code::success };
|