You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/26 15:06:01 UTC
(axis-axis2-c-core) 03/04: Add custom User-Agent header support via message context property (AXIS2C-1612)
This is an automated email from the ASF dual-hosted git repository.
robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git
commit b15b11b4c73ace35efeeeb79e8418d9ca3507053
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Mon Jan 26 04:04:41 2026 -1000
Add custom User-Agent header support via message context property (AXIS2C-1612)
Allow users to specify a custom User-Agent string by setting the
"User-Agent" property on the message context. When this property is set,
both the libcurl and non-libcurl HTTP transports will use the custom value
instead of the default "Axis2C/<version>".
Usage:
axutil_property_t *ua = axutil_property_create(env);
axutil_property_set_value(ua, env, "MyApp/1.0");
axis2_msg_ctx_set_property(msg_ctx, env, "User-Agent", ua);
Changes:
- axis2_libcurl.c: Check for User-Agent property before setting header
- http_sender.c: Same logic for non-libcurl transport
- test_http_transport.cc: Add unit tests for property mechanism
Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
src/core/transport/http/sender/http_sender.c | 27 +++++-
.../transport/http/sender/libcurl/axis2_libcurl.c | 44 ++++++++-
test/core/transport/http/test_http_transport.cc | 100 +++++++++++++++++++++
3 files changed, 168 insertions(+), 3 deletions(-)
diff --git a/src/core/transport/http/sender/http_sender.c b/src/core/transport/http/sender/http_sender.c
index 62045961f..9cdd47203 100644
--- a/src/core/transport/http/sender/http_sender.c
+++ b/src/core/transport/http/sender/http_sender.c
@@ -761,8 +761,31 @@ axis2_http_sender_send(
axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_COOKIE, cookie_str);
}
- /* User-Agent:Axis2/C header */
- axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_USER_AGENT, AXIS2_USER_AGENT);
+ /* AXIS2C-1612: User-Agent header - check for custom value */
+ {
+ axutil_property_t *user_agent_property = NULL;
+ axis2_char_t *user_agent_value = NULL;
+
+ user_agent_property = (axutil_property_t *)axis2_msg_ctx_get_property(
+ msg_ctx, env, AXIS2_HTTP_HEADER_USER_AGENT);
+
+ if (user_agent_property)
+ {
+ user_agent_value = (axis2_char_t *)axutil_property_get_value(
+ user_agent_property, env);
+ }
+
+ if (user_agent_value)
+ {
+ axis2_http_sender_util_add_header(env, request,
+ AXIS2_HTTP_HEADER_USER_AGENT, user_agent_value);
+ }
+ else
+ {
+ axis2_http_sender_util_add_header(env, request,
+ AXIS2_HTTP_HEADER_USER_AGENT, AXIS2_USER_AGENT);
+ }
+ }
http_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_HEADER_PROPERTY);
if(http_property)
diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.c b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
index f6afd82c2..d20afbe2e 100644
--- a/src/core/transport/http/sender/libcurl/axis2_libcurl.c
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
@@ -148,7 +148,49 @@ axis2_libcurl_send(
handler = data->handler;
curl_easy_reset(handler);
curl_easy_setopt(handler, CURLOPT_ERRORBUFFER, data->errorbuffer);
- headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C);
+
+ /* AXIS2C-1612: Check for custom User-Agent property */
+ {
+ axutil_property_t *user_agent_property = NULL;
+ axis2_char_t *user_agent_value = NULL;
+
+ user_agent_property = (axutil_property_t *)axis2_msg_ctx_get_property(
+ msg_ctx, env, AXIS2_HTTP_HEADER_USER_AGENT);
+
+ if (user_agent_property)
+ {
+ user_agent_value = (axis2_char_t *)axutil_property_get_value(
+ user_agent_property, env);
+ }
+
+ if (user_agent_value)
+ {
+ axis2_char_t *user_agent_header = NULL;
+ int header_len = axutil_strlen(AXIS2_HTTP_HEADER_USER_AGENT) +
+ axutil_strlen(user_agent_value) + 3;
+
+ user_agent_header = AXIS2_MALLOC(env->allocator,
+ header_len * sizeof(axis2_char_t));
+ if (user_agent_header)
+ {
+ sprintf(user_agent_header, "%s: %s",
+ AXIS2_HTTP_HEADER_USER_AGENT, user_agent_value);
+ headers = curl_slist_append(headers, user_agent_header);
+ /* curl_slist_append copies the string, so free our copy */
+ AXIS2_FREE(env->allocator, user_agent_header);
+ }
+ else
+ {
+ /* Fallback to default on allocation failure */
+ headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C);
+ }
+ }
+ else
+ {
+ headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C);
+ }
+ }
+
headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_ACCEPT_);
headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_EXPECT_);
diff --git a/test/core/transport/http/test_http_transport.cc b/test/core/transport/http/test_http_transport.cc
index 79fc16cc9..45c66e5ec 100644
--- a/test/core/transport/http/test_http_transport.cc
+++ b/test/core/transport/http/test_http_transport.cc
@@ -39,6 +39,8 @@
#endif
#include <axis2_simple_http_svr_conn.h>
#include <axis2_http_transport_utils.h>
+#include <axis2_msg_ctx.h>
+#include <axis2_http_transport.h>
#include "../../../cutest/include/cut_http_server.h"
@@ -1221,3 +1223,101 @@ TEST_F(TestHTTPTransport, DISABLED_test_AXIS2C_1480_large_body)
printf("Finished AXIS2C-1480 large body test ..........\n\n");
}
+
+/**
+ * Test for AXIS2C-1612: Custom HTTP HEADER USER AGENT
+ *
+ * This test verifies that custom User-Agent strings can be set via
+ * the message context property AXIS2_HTTP_HEADER_USER_AGENT ("User-Agent").
+ * When this property is set, the HTTP transport should use it instead of
+ * the default "Axis2C/<version>" User-Agent string.
+ *
+ * This test validates the property setting/retrieval mechanism. Full
+ * integration testing (verifying the header is actually sent) would require
+ * a mock server that captures request headers.
+ */
+TEST_F(TestHTTPTransport, test_AXIS2C_1612_custom_user_agent_property)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_property_t *user_agent_property = NULL;
+ axutil_property_t *retrieved_property = NULL;
+ axis2_char_t *custom_user_agent = (axis2_char_t *)"MyApp/1.0 (Custom User Agent)";
+ axis2_char_t *retrieved_value = NULL;
+
+ printf("Starting AXIS2C-1612 test (custom User-Agent property)\n");
+
+ /* Create a message context */
+ msg_ctx = axis2_msg_ctx_create(m_env, NULL, NULL, NULL);
+ ASSERT_NE(msg_ctx, nullptr) << "Failed to create msg_ctx";
+
+ /* Create property with custom User-Agent value */
+ user_agent_property = axutil_property_create(m_env);
+ ASSERT_NE(user_agent_property, nullptr) << "Failed to create property";
+
+ /* Set the property value - don't let property own it since it's a string literal */
+ axutil_property_set_value(user_agent_property, m_env, custom_user_agent);
+ axutil_property_set_own_value(user_agent_property, m_env, AXIS2_FALSE);
+
+ /* Set the property on msg_ctx using the standard User-Agent key */
+ axis2_msg_ctx_set_property(msg_ctx, m_env, AXIS2_HTTP_HEADER_USER_AGENT, user_agent_property);
+
+ /* Retrieve the property and verify it matches */
+ retrieved_property = (axutil_property_t *)axis2_msg_ctx_get_property(
+ msg_ctx, m_env, AXIS2_HTTP_HEADER_USER_AGENT);
+ ASSERT_NE(retrieved_property, nullptr)
+ << "AXIS2C-1612: User-Agent property should be retrievable from msg_ctx";
+
+ retrieved_value = (axis2_char_t *)axutil_property_get_value(retrieved_property, m_env);
+ ASSERT_NE(retrieved_value, nullptr)
+ << "AXIS2C-1612: User-Agent property value should not be NULL";
+
+ ASSERT_STREQ(retrieved_value, custom_user_agent)
+ << "AXIS2C-1612: Retrieved User-Agent should match set value";
+
+ printf(" Custom User-Agent set: '%s'\n", custom_user_agent);
+ printf(" Retrieved User-Agent: '%s'\n", retrieved_value);
+ printf(" Property mechanism verified successfully\n");
+
+ /* Verify the default constant is what we expect */
+ printf(" Default User-Agent constant: '%s'\n", AXIS2_USER_AGENT);
+ ASSERT_NE(strstr(AXIS2_USER_AGENT, "Axis2C"), nullptr)
+ << "Default User-Agent should contain 'Axis2C'";
+
+ /* Cleanup - msg_ctx_free will free the property */
+ axis2_msg_ctx_free(msg_ctx, m_env);
+
+ printf("Finished AXIS2C-1612 test ..........\n\n");
+}
+
+/**
+ * Test for AXIS2C-1612: Verify default User-Agent when property not set
+ *
+ * This test verifies that when the User-Agent property is NOT set,
+ * the default value is used (no property should be returned).
+ */
+TEST_F(TestHTTPTransport, test_AXIS2C_1612_default_user_agent_when_not_set)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_property_t *retrieved_property = NULL;
+
+ printf("Starting AXIS2C-1612 default User-Agent test\n");
+
+ /* Create a message context without setting User-Agent property */
+ msg_ctx = axis2_msg_ctx_create(m_env, NULL, NULL, NULL);
+ ASSERT_NE(msg_ctx, nullptr);
+
+ /* Try to retrieve User-Agent property - should be NULL (not set) */
+ retrieved_property = (axutil_property_t *)axis2_msg_ctx_get_property(
+ msg_ctx, m_env, AXIS2_HTTP_HEADER_USER_AGENT);
+
+ /* When not set, the transport code falls back to AXIS2_USER_AGENT constant */
+ ASSERT_EQ(retrieved_property, nullptr)
+ << "AXIS2C-1612: When not set, property should be NULL (code uses default)";
+
+ printf(" No custom User-Agent property set\n");
+ printf(" Transport will use default: '%s'\n", AXIS2_USER_AGENT);
+
+ axis2_msg_ctx_free(msg_ctx, m_env);
+
+ printf("Finished AXIS2C-1612 default test ..........\n\n");
+}