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/14 13:27:14 UTC
(axis-axis2-c-core) 04/04: AXIS2C-1312/1555: Add proxy authentication support for HTTPS CONNECT
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 e98d6364610929d15a8990427e3e843774658f8c
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Wed Jan 14 03:18:57 2026 -1000
AXIS2C-1312/1555: Add proxy authentication support for HTTPS CONNECT
When connecting to an HTTPS endpoint through a proxy, the HTTP client
sends a CONNECT request to establish an SSL tunnel. This request may
require proxy authentication (HTTP 407 response).
Changes:
- Add proxy_auth_username and proxy_auth_password fields to http_client struct
- Add axis2_http_client_set_proxy_auth() function to set proxy credentials
- Modify axis2_http_client_connect_ssl_host() to include Proxy-Authorization
header with Basic auth in the CONNECT request when credentials are set
- Return HTTP 407 status code (instead of generic failure) when proxy
requires authentication, allowing caller to handle appropriately
- Update axis2_http_sender_configure_proxy() to pass proxy credentials
from message context to the HTTP client
- Properly free proxy auth credentials in axis2_http_client_free()
Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
include/axis2_http_client.h | 15 ++++
src/core/transport/http/sender/http_client.c | 121 +++++++++++++++++++++++++--
src/core/transport/http/sender/http_sender.c | 21 +++++
3 files changed, 149 insertions(+), 8 deletions(-)
diff --git a/include/axis2_http_client.h b/include/axis2_http_client.h
index edbfc3f1f..27c936582 100644
--- a/include/axis2_http_client.h
+++ b/include/axis2_http_client.h
@@ -145,6 +145,21 @@ extern "C"
const axis2_http_client_t * client,
const axutil_env_t * env);
+ /**
+ * AXIS2C-1312/1555: Set proxy authentication credentials for HTTPS CONNECT
+ * @param client pointer to client
+ * @param env pointer to environment struct
+ * @param username proxy authentication username
+ * @param password proxy authentication password
+ * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
+ */
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_http_client_set_proxy_auth(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ const axis2_char_t * username,
+ const axis2_char_t * password);
+
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_connect_ssl_host(
diff --git a/src/core/transport/http/sender/http_client.c b/src/core/transport/http/sender/http_client.c
index 6eb1edff8..024cce315 100644
--- a/src/core/transport/http/sender/http_client.c
+++ b/src/core/transport/http/sender/http_client.c
@@ -54,6 +54,10 @@ struct axis2_http_client
int req_body_size;
axis2_bool_t validate_ssl_hostname;
+ /* AXIS2C-1312/1555: Proxy authentication for HTTPS CONNECT */
+ axis2_char_t *proxy_auth_username;
+ axis2_char_t *proxy_auth_password;
+
/* These are for mtom case */
axutil_array_list_t *mime_parts;
axis2_bool_t doing_mtom;
@@ -119,6 +123,15 @@ axis2_http_client_free(
{
AXIS2_FREE(env->allocator, http_client->proxy_host_port);
}
+ /* AXIS2C-1312/1555: Free proxy authentication credentials */
+ if(http_client->proxy_auth_username)
+ {
+ AXIS2_FREE(env->allocator, http_client->proxy_auth_username);
+ }
+ if(http_client->proxy_auth_password)
+ {
+ AXIS2_FREE(env->allocator, http_client->proxy_auth_password);
+ }
if(http_client->url)
{
axutil_url_free(http_client->url, env);
@@ -815,6 +828,46 @@ axis2_http_client_get_proxy(
return client->proxy_host_port;
}
+/* AXIS2C-1312/1555: Set proxy authentication credentials for HTTPS CONNECT */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_proxy_auth(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ const axis2_char_t * username,
+ const axis2_char_t * password)
+{
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+
+ if(client->proxy_auth_username)
+ {
+ AXIS2_FREE(env->allocator, client->proxy_auth_username);
+ client->proxy_auth_username = NULL;
+ }
+ if(client->proxy_auth_password)
+ {
+ AXIS2_FREE(env->allocator, client->proxy_auth_password);
+ client->proxy_auth_password = NULL;
+ }
+
+ if(username)
+ {
+ client->proxy_auth_username = axutil_strdup(env, username);
+ if(!client->proxy_auth_username)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ if(password)
+ {
+ client->proxy_auth_password = axutil_strdup(env, password);
+ if(!client->proxy_auth_password)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_connect_ssl_host(
axis2_http_client_t * client,
@@ -851,9 +904,50 @@ axis2_http_client_connect_ssl_host(
return AXIS2_FAILURE;
}
- connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) * sizeof(axis2_char_t) + 30
- * sizeof(axis2_char_t));
- sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+ /* AXIS2C-1312/1555: Build CONNECT request with optional proxy authentication */
+ if(client->proxy_auth_username && client->proxy_auth_password)
+ {
+ /* Build Basic authentication header for proxy */
+ axis2_char_t *credentials = NULL;
+ axis2_char_t *encoded = NULL;
+ int credentials_len;
+ int encoded_len;
+
+ credentials_len = axutil_strlen(client->proxy_auth_username) +
+ axutil_strlen(client->proxy_auth_password) + 2;
+ credentials = AXIS2_MALLOC(env->allocator, credentials_len);
+ sprintf(credentials, "%s:%s", client->proxy_auth_username, client->proxy_auth_password);
+
+ /* Base64 encode the credentials */
+ encoded_len = axutil_base64_encode_len(axutil_strlen(credentials));
+ encoded = AXIS2_MALLOC(env->allocator, encoded_len + 1);
+ if(encoded)
+ {
+ axutil_base64_encode(encoded, credentials, axutil_strlen(credentials));
+ encoded[encoded_len] = '\0';
+ }
+ AXIS2_FREE(env->allocator, credentials);
+
+ if(encoded)
+ {
+ int connect_len = axutil_strlen(host) + axutil_strlen(encoded) + 100;
+ connect_string = AXIS2_MALLOC(env->allocator, connect_len);
+ sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n",
+ host, port, encoded);
+ AXIS2_FREE(env->allocator, encoded);
+ }
+ else
+ {
+ /* Fallback to no auth if encoding fails */
+ connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) + 30);
+ sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+ }
+ }
+ else
+ {
+ connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) + 30);
+ sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+ }
axutil_stream_write(tmp_stream, env, connect_string, axutil_strlen(connect_string)
* sizeof(axis2_char_t));
@@ -893,12 +987,23 @@ axis2_http_client_connect_ssl_host(
axutil_stream_free(tmp_stream, env);
return AXIS2_FAILURE;
}
- if(200 != axis2_http_status_line_get_status_code(status_line, env))
+ /* AXIS2C-1312/1555: Handle proxy authentication response */
{
- AXIS2_FREE(env->allocator, connect_string);
- axis2_http_status_line_free(status_line, env);
- axutil_stream_free(tmp_stream, env);
- return AXIS2_FAILURE;
+ int status_code = axis2_http_status_line_get_status_code(status_line, env);
+ if(200 != status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Proxy CONNECT failed with status code %d", status_code);
+ AXIS2_FREE(env->allocator, connect_string);
+ axis2_http_status_line_free(status_line, env);
+ axutil_stream_free(tmp_stream, env);
+ /* Return 407 status code so caller can handle proxy auth */
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ return AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL;
+ }
+ return AXIS2_FAILURE;
+ }
}
/* We need to empty the stream before we return
*/
diff --git a/src/core/transport/http/sender/http_sender.c b/src/core/transport/http/sender/http_sender.c
index 32a6f4a6e..6e1195784 100644
--- a/src/core/transport/http/sender/http_sender.c
+++ b/src/core/transport/http/sender/http_sender.c
@@ -1890,6 +1890,27 @@ axis2_http_sender_configure_proxy(
if(proxy_port && proxy_host)
{
axis2_http_client_set_proxy(sender->client, env, proxy_host, AXIS2_ATOI(proxy_port));
+
+ /* AXIS2C-1312/1555: Set proxy authentication credentials for HTTPS CONNECT */
+ {
+ axutil_property_t *proxy_auth_un = NULL;
+ axutil_property_t *proxy_auth_pw = NULL;
+ axis2_char_t *proxy_uname = NULL;
+ axis2_char_t *proxy_passwd = NULL;
+
+ proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+
+ if(proxy_auth_un && proxy_auth_pw)
+ {
+ proxy_uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env);
+ proxy_passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env);
+ if(proxy_uname && proxy_passwd)
+ {
+ axis2_http_client_set_proxy_auth(sender->client, env, proxy_uname, proxy_passwd);
+ }
+ }
+ }
}
return AXIS2_SUCCESS;
}