diff --git a/.gitignore b/.gitignore index 9c78d650..e3cacf85 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,9 @@ *.pdb *.ilk +# Compilation database +compile_commands.json + # GitHub Actions # ################## .github/.release @@ -43,4 +46,5 @@ cgreen-src/ cgreen/ cucumber-cpp/ -cucumber-cpp-src/ \ No newline at end of file +cucumber-cpp-src/ + diff --git a/.pubnub.yml b/.pubnub.yml index 7660473b..c22d1808 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,8 +1,15 @@ name: c-core schema: 1 -version: "4.2.2" +version: "4.3.0" scm: github.com/pubnub/c-core changelog: + - date: 2023-07-24 + version: v4.3.0 + changes: + - type: feature + text: "Add `publisher` field into `pubnub_v2_message`." + - type: bug + text: "Fixed `flags` and `region` values that always equaled `0`." - date: 2023-05-24 version: v4.2.2 changes: @@ -720,7 +727,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -786,7 +793,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -852,7 +859,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -914,7 +921,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -975,7 +982,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -1031,7 +1038,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" @@ -1084,7 +1091,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.2.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.3.0 requires: - name: "miniz" diff --git a/CHANGELOG.md b/CHANGELOG.md index 252b148e..bf02b3d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## v4.3.0 +July 24 2023 + +#### Added +- Add `publisher` field into `pubnub_v2_message`. + +#### Fixed +- Fixed `flags` and `region` values that always equaled `0`. + ## v4.2.2 May 24 2023 diff --git a/core/Makefile b/core/Makefile index e1114001..42a7de94 100644 --- a/core/Makefile +++ b/core/Makefile @@ -1,7 +1,7 @@ PROJECT_SOURCEFILES = pbcc_set_state.c pubnub_pubsubapi.c pubnub_coreapi.c pubnub_ccore_pubsub.c pubnub_ccore.c pubnub_netcore.c pubnub_alloc_static.c pubnub_assert_std.c pubnub_json_parse.c pubnub_keep_alive.c pubnub_helper.c pubnub_url_encode.c ../lib/pb_strnlen_s.c ../lib/pb_strncasecmp.c ../lib/base64/pbbase64.c pubnub_coreapi_ex.c # TODO: move coreapi_ex to new module -all: pubnub_grant_token_api_unittest pubnub_proxy_unittest pubnub_timer_list_unittest unittest +all: pubnub_subscribe_v2_unittest pubnub_grant_token_api_unittest pubnub_proxy_unittest pubnub_timer_list_unittest unittest OS := $(shell uname) # Coverage doesn't seem to work on MacOS for some reason, but, since @@ -83,6 +83,14 @@ pubnub_grant_token_api_unittest: $(PROJECT_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILE #$(GCOVR) -r . --html --html-details -o coverage.html +SUBSCRIBE_V2_SOURCEFILES += pubnub_subscribe_v2.c pbcc_subscribe_v2.c + +pubnub_subscribe_v2_unittest: $(PROJECT_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) pubnub_subscribe_v2_unit_test.c + gcc -o pubnub_subscribe_v2_unit_test.so -shared $(CFLAGS) $(LDFLAGS) -D PUBNUB_ORIGIN_SETTABLE=1 -D PUBNUB_USE_SUBSCRIBE_V2=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) test/pubnub_test_mocks.c pubnub_subscribe_v2_unit_test.c -lcgreen -lm + $(CGREEN_RUNNER) ./pubnub_subscribe_v2_unit_test.so + #$(GCOVR) -r . --html --html-details -o coverage.html + + clean: find . -type d -iname "*.dSYM" -exec rm -rf {} \+ find . -type f -name "*.so" -o -name "*.gcda" -o -name "*.gcno" -o -name "*.html" | xargs -r rm -rf diff --git a/core/pbcc_subscribe_v2.c b/core/pbcc_subscribe_v2.c index d1ddbb37..5c8a84eb 100644 --- a/core/pbcc_subscribe_v2.c +++ b/core/pbcc_subscribe_v2.c @@ -92,6 +92,7 @@ enum pubnub_res pbcc_subscribe_v2_prep(struct pbcc_context* p, } #endif PUBNUB_LOG_DEBUG("pbcc_subscribe_v2_prep. REQUEST =%s\n", p->http_buf); + return (rslt != PNR_OK) ? rslt : PNR_STARTED; } @@ -311,5 +312,17 @@ struct pubnub_v2_message pbcc_get_msg_v2(struct pbcc_context* p) rslt.metadata.size = found.end - found.start; } + if (jonmpOK == pbjson_get_object_value(&el, "i", &found)) { + rslt.publisher.ptr = (char*)found.start + 1; + rslt.publisher.size = found.end - found.start - 2; + } + + if (jonmpOK == pbjson_get_object_value(&el, "f", &found)) { + rslt.flags = strtol(found.start, NULL, 0); + } + + rslt.region = p->region; + + return rslt; } diff --git a/core/pubnub_subscribe_v2_message.h b/core/pubnub_subscribe_v2_message.h index 42b2bd75..1a4a654d 100644 --- a/core/pubnub_subscribe_v2_message.h +++ b/core/pubnub_subscribe_v2_message.h @@ -50,6 +50,8 @@ struct pubnub_v2_message { struct pubnub_char_mem_block metadata; /** Indicates the message type: a signal, published, or something else */ enum pubnub_message_type message_type; + /** The message information about publisher */ + struct pubnub_char_mem_block publisher; }; diff --git a/core/pubnub_subscribe_v2_unit_test.c b/core/pubnub_subscribe_v2_unit_test.c new file mode 100644 index 00000000..eb89c06e --- /dev/null +++ b/core/pubnub_subscribe_v2_unit_test.c @@ -0,0 +1,105 @@ +/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ +#include "pubnub_memory_block.h" +#include +#if defined PUBNUB_USE_SUBSCRIBE_V2 + +#include "cgreen/assertions.h" +#include "cgreen/cgreen.h" +#include "cgreen/mocks.h" +#include "cgreen/constraint_syntax_helpers.h" + +#include "pubnub_alloc.h" +#include "pubnub_grant_token_api.h" +#include "pubnub_pubsubapi.h" +#include "pubnub_internal.h" +#include "pubnub_internal_common.h" +#include "pubnub_assert.h" +#include "pubnub_log.h" +#include "pubnub_subscribe_v2_message.h" +#include "pubnub_subscribe_v2.h" +#include "test/pubnub_test_mocks.h" + +static pubnub_t* pbp; + +Describe(subscribe_v2); + +BeforeEach(subscribe_v2) { + pubnub_setup_mocks(&pbp); + printf("B address=%p\n", pbp); + + pubnub_origin_set(pbp, NULL); + pubnub_init(pbp, "pub_key", "sub_key"); + pubnub_set_user_id(pbp, "test_id"); +} + +AfterEach(subscribe_v2) { + pubnub_cleanup_mocks(pbp); +} + +void assert_char_mem_block(struct pubnub_char_mem_block block, char const* expected) { + char* str = malloc(block.size + 1); + memcpy((void*)str, block.ptr, block.size); + + str[block.size] = '\0'; + + assert_that(str, is_equal_to_string(expected)); + + free((void*)str); +} + +Ensure(subscribe_v2, should_parse_response_correctly) { + assert_that(pubnub_last_time_token(pbp), is_equal_to_string("0")); + + assert_that(pubnub_auth_get(pbp), is_equal_to_string(NULL)); + expect_have_dns_for_pubnub_origin_on_ctx(pbp); + expect_outgoing_with_url_on_ctx(pbp, + "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=0&tr=0&uuid=test_id&heartbeat=270"); + incoming("HTTP/1.1 200\r\nContent-Length: " + "44\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[]}", + NULL); + + expect(pbntf_lost_socket, when(pb, is_equal_to(pbp))); + expect(pbntf_trans_outcome, when(pb, is_equal_to(pbp))); + + assert_that(pubnub_subscribe_v2(pbp, "my-channel", pubnub_subscribe_v2_defopts()), + is_equal_to(PNR_OK)); + + assert_that(pubnub_last_http_code(pbp), is_equal_to(200)); + assert_that(pubnub_last_time_token(pbp), is_equal_to_string("15628652479932717")); + + expect(pbntf_enqueue_for_processing, when(pb, is_equal_to(pbp)), will_return(0)); + expect(pbntf_got_socket, when(pb, is_equal_to(pbp)), will_return(0)); + + expect_outgoing_with_url_on_ctx(pbp, + "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=15628652479932717&tr=4&uuid=test_id&heartbeat=270"); + incoming("HTTP/1.1 220\r\nContent-Length: " + "183\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[{\"a\":\"1\",\"f\":514,\"i\":\"publisher_id\",\"s\":1,\"p\":{\"t\":\"15628652479933927\",\"r\":4},\"k\":\"demo\",\"c\":\"my-channel\",\"d\":\"mymessage\",\"b\":\"my-channel\"}]}", + NULL); + + expect(pbntf_lost_socket, when(pb, is_equal_to(pbp))); + expect(pbntf_trans_outcome, when(pb, is_equal_to(pbp))); + + assert_that(pubnub_subscribe_v2(pbp, "my-channel", pubnub_subscribe_v2_defopts()), + is_equal_to(PNR_OK)); + + struct pubnub_v2_message msg = pubnub_get_v2(pbp); + + assert_char_mem_block(msg.tt, "15628652479933927"); + assert_char_mem_block(msg.channel, "my-channel"); + assert_char_mem_block(msg.payload, "\"mymessage\""); + assert_char_mem_block(msg.publisher, "publisher_id"); + + assert_that(msg.region, is_equal_to(4)); + assert_that(msg.flags, is_equal_to(514)); + assert_that(msg.message_type, is_equal_to(pbsbPublished)); +} + +#if 0 +int main(int argc, char *argv[]) { + TestSuite *suite = create_test_suite(); + add_test_with_context(suite, token_parsing); + run_test_suite(suite, create_text_reporter()); +} +#endif // 0 +#endif // defined PUBNUB_USE_SUBSCRIBE_V2 + diff --git a/core/pubnub_version_internal.h b/core/pubnub_version_internal.h index 9b695dc0..00937355 100644 --- a/core/pubnub_version_internal.h +++ b/core/pubnub_version_internal.h @@ -3,7 +3,7 @@ #define INC_PUBNUB_VERSION_INTERNAL -#define PUBNUB_SDK_VERSION "4.2.2" +#define PUBNUB_SDK_VERSION "4.3.0" #endif /* !defined INC_PUBNUB_VERSION_INTERNAL */ diff --git a/core/samples/metadata.c b/core/samples/metadata.c index daa051bc..300efd3e 100644 --- a/core/samples/metadata.c +++ b/core/samples/metadata.c @@ -58,6 +58,8 @@ static int printout_subscribe_v2_outcome(pubnub_t* pbp, enum pubnub_res res) printf(" Metadata = '%.*s'\n", (int)msg.metadata.size, msg.metadata.ptr); printf(" Payload = '%.*s'\n", (int)msg.payload.size, msg.payload.ptr); printf(" MessageType= '%s'\n", pubnub_msg_type_to_str(msg.message_type)); + printf(" Publisher = '%.*s'\n", (int)msg.publisher.size, msg.publisher.ptr); + printf(" Region = '%d'\n", msg.region); } return 0; } diff --git a/core/test/pubnub_test_mocks.c b/core/test/pubnub_test_mocks.c index 63726083..993e8450 100644 --- a/core/test/pubnub_test_mocks.c +++ b/core/test/pubnub_test_mocks.c @@ -562,3 +562,35 @@ void pubnub_cleanup_mocks(pubnub_t* pbp) attest(pubnub_free(pbp), equals(0)); free_m_msgs(m_string_msg_array); } + + +void expect_have_dns_for_pubnub_origin_on_ctx(pubnub_t* pbp) +{ + expect(pbntf_enqueue_for_processing, when(pb, equals(pbp)), returns(0)); + expect(pbpal_resolv_and_connect, + when(pb, equals(pbp)), + returns(pbpal_connect_success)); + expect(pbntf_got_socket, when(pb, equals(pbp)), returns(0)); +} + + +void expect_outgoing_with_url_on_ctx(pubnub_t* pbp, char const* url) +{ + expect(pbpal_send_str, when(s, streqs("GET ")), returns(0)); + expect(pbpal_send_status, returns(0)); + expect(pbpal_send_str, when(s, streqs(url)), returns(0)); + expect(pbpal_send_status, returns(0)); + expect(pbpal_send, when(data, streqs(" HTTP/1.1\r\nHost: ")), returns(0)); + expect(pbpal_send_status, returns(0)); + expect(pbpal_send_str, when(s, streqs(PUBNUB_ORIGIN)), returns(0)); + expect(pbpal_send_status, returns(0)); + expect(pbpal_send_str, + when(s, + streqs("\r\nUser-Agent: POSIX-PubNub-C-core/" PUBNUB_SDK_VERSION + "\r\n" ACCEPT_ENCODING "\r\n")), + returns(0)); + expect(pbpal_send_status, returns(0)); + expect(pbntf_watch_in_events, when(pb, equals(pbp)), returns(0)); +} + + diff --git a/core/test/pubnub_test_mocks.h b/core/test/pubnub_test_mocks.h index 345c0adc..5eccc790 100644 --- a/core/test/pubnub_test_mocks.h +++ b/core/test/pubnub_test_mocks.h @@ -34,4 +34,8 @@ void pubnub_setup_mocks(pubnub_t** pbp); void pubnub_cleanup_mocks(pubnub_t* pbp); +void expect_have_dns_for_pubnub_origin_on_ctx(pubnub_t* pbp); + +void expect_outgoing_with_url_on_ctx(pubnub_t* pbp, char const* url); + #endif // INC_PUBNUB_TEST_MOCKS diff --git a/cpp/pubnub_v2_message.hpp b/cpp/pubnub_v2_message.hpp index cb949bc8..da2fc362 100644 --- a/cpp/pubnub_v2_message.hpp +++ b/cpp/pubnub_v2_message.hpp @@ -26,6 +26,7 @@ class v2_message { } std::string payload() const { return std::string(d_.payload.ptr, d_.payload.size); } std::string metadata() const { return std::string(d_.metadata.ptr, d_.metadata.size); } + std::string publisher() const { return std::string(d_.publisher.ptr, d_.publisher.size); } pubnub_message_type message_type() const { return d_.message_type; } /** Message structure is considered empty if there is no timetoken info(whose existence is obligatory for any valid v2 message)