blob: d37aa6876221a1958cc84c67afcdb9204a713e2c [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AXIS2_APACHE2_REQUEST_PROCESSOR_H
#define AXIS2_APACHE2_REQUEST_PROCESSOR_H
#include <axutil_env.h>
#include <axis2_msg_ctx.h>
#include <httpd.h>
#include <http_request.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @file axis2_apache2_request_processor.h
* @brief Apache2 Request Processor Interface - Java-style interface pattern in C
*
* This interface enables protocol-specific request processing for Apache Axis2/C,
* separating SOAP and JSON processing concerns while maintaining thread safety
* for HTTP/2 multiplexed requests.
*
* Similar to Java interface:
* public interface Apache2RequestProcessor {
* ProcessingResult processAcceptHeaders(HttpRequest request, MessageContext ctx);
* ProcessingResult processRequestBody(HttpRequest request, MessageContext ctx);
* void cleanup();
* }
*
* Implementations:
* - SoapRequestProcessor: Handles traditional SOAP/HTTP 1.1 with existing logic
* - JsonRequestProcessor: Thread-safe HTTP/2 JSON processing with proper concurrency
*
* Benefits:
* ✅ Zero risk to existing apache2_worker.c (no modifications needed)
* ✅ Thread-safe HTTP/2 processing through isolated contexts
* ✅ Protocol specialization (SOAP vs JSON optimizations)
* ✅ Extensible design for future protocols (GraphQL, gRPC)
*/
/** Forward declaration of the interface */
typedef struct axis2_apache2_request_processor axis2_apache2_request_processor_t;
/**
* @brief Processing result status codes
*
* Provides detailed feedback on processing outcomes for better error handling
* and debugging in HTTP/2 multiplexed environments.
*/
typedef enum axis2_apache2_processing_result
{
AXIS2_APACHE2_PROCESSING_SUCCESS = 0, /**< Processing completed successfully */
AXIS2_APACHE2_PROCESSING_FAILURE = -1, /**< Processing failed - general error */
AXIS2_APACHE2_PROCESSING_CONCURRENT_ERROR = -2,/**< Thread safety violation detected */
AXIS2_APACHE2_PROCESSING_PROTOCOL_ERROR = -3, /**< Protocol-specific error (SOAP vs JSON) */
AXIS2_APACHE2_PROCESSING_MEMORY_ERROR = -4 /**< Memory allocation failure */
} axis2_apache2_processing_result_t;
/**
* @brief Request processing context for thread isolation
*
* Each HTTP/2 stream gets its own processing context to prevent
* concurrent modification issues that caused the original array bounds errors.
*/
typedef struct axis2_apache2_processing_context
{
/** Private accept header list - no sharing between streams */
axutil_array_list_t* accept_records;
/** Private accept-charset list - no sharing between streams */
axutil_array_list_t* accept_charset_records;
/** Private accept-language list - no sharing between streams */
axutil_array_list_t* accept_language_records;
/** Stream ID for debugging and tracing */
axis2_char_t* stream_id;
/** Processing start timestamp for performance monitoring */
axutil_date_time_t* processing_start;
/** Error context for detailed diagnostics */
axutil_error_t* processing_error;
} axis2_apache2_processing_context_t;
/**
* @brief Apache2 Request Processor Interface
*
* This interface abstracts HTTP request processing to enable protocol-specific
* implementations while maintaining clean separation of concerns.
*
* The pattern eliminates the dangerous concurrent array modification that caused
* "Array list index out of bounds" errors by providing thread-safe implementations.
*/
struct axis2_apache2_request_processor
{
/**
* @brief Process HTTP Accept headers in a thread-safe manner
*
* This method handles Accept, Accept-Charset, and Accept-Language headers
* without the dangerous concurrent modification patterns found in the original
* apache2_worker.c code.
*
* @param processor The request processor instance
* @param env Axis2 environment
* @param request Apache request record
* @param msg_ctx Axis2 message context
* @param processing_ctx Thread-isolated processing context
* @return Processing result status
*/
axis2_apache2_processing_result_t (*process_accept_headers)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env,
request_rec* request,
axis2_msg_ctx_t* msg_ctx,
axis2_apache2_processing_context_t* processing_ctx);
/**
* @brief Process HTTP request body with protocol-specific logic
*
* Delegates to appropriate protocol handler (SOAP vs JSON) based on
* Content-Type and other request characteristics.
*
* @param processor The request processor instance
* @param env Axis2 environment
* @param request Apache request record
* @param msg_ctx Axis2 message context
* @param processing_ctx Thread-isolated processing context
* @return Processing result status
*/
axis2_apache2_processing_result_t (*process_request_body)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env,
request_rec* request,
axis2_msg_ctx_t* msg_ctx,
axis2_apache2_processing_context_t* processing_ctx);
/**
* @brief Validate request processor state for thread safety
*
* Performs runtime checks to ensure no shared state exists that could
* cause concurrent modification issues under HTTP/2 load.
*
* @param processor The request processor instance
* @param env Axis2 environment
* @return AXIS2_TRUE if thread-safe, AXIS2_FALSE otherwise
*/
axis2_bool_t (*is_thread_safe)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env);
/**
* @brief Get processor protocol identifier
*
* Returns protocol type for debugging and performance monitoring.
* Examples: "SOAP/HTTP1.1", "JSON/HTTP2", "REST/HTTP1.1"
*
* @param processor The request processor instance
* @param env Axis2 environment
* @return Protocol identifier string
*/
const axis2_char_t* (*get_protocol_id)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env);
/**
* @brief Create thread-isolated processing context
*
* Factory method for creating processing contexts that prevent the
* concurrent modification issues found in the original apache2_worker.c.
*
* @param processor The request processor instance
* @param env Axis2 environment
* @param stream_id Optional HTTP/2 stream identifier
* @return New processing context or NULL on failure
*/
axis2_apache2_processing_context_t* (*create_processing_context)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env,
const axis2_char_t* stream_id);
/**
* @brief Free processing context and associated resources
*
* Ensures proper cleanup of thread-isolated resources to prevent
* memory leaks in high-concurrency HTTP/2 environments.
*
* @param processor The request processor instance
* @param env Axis2 environment
* @param processing_ctx Processing context to free
*/
void (*free_processing_context)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env,
axis2_apache2_processing_context_t* processing_ctx);
/**
* @brief Interface cleanup and resource deallocation
*
* Implements proper resource management following RAII-like patterns for C.
*
* @param processor The request processor instance to free
* @param env Axis2 environment
*/
void (*free)(
struct axis2_apache2_request_processor* processor,
const axutil_env_t* env);
};
/**
* @brief Create SOAP-compatible request processor
*
* This implementation wraps the existing apache2_worker.c logic for backward
* compatibility while providing the interface abstraction.
*
* Handles:
* - Traditional SOAP/HTTP 1.1 requests
* - REST API calls
* - Existing Accept header processing (with original patterns)
*
* Thread Safety: Limited (uses original code paths)
* Performance: Same as current implementation
* Compatibility: 100% backward compatible
*
* @param env Axis2 environment
* @return New SOAP processor instance or NULL on failure
*/
AXIS2_EXTERN axis2_apache2_request_processor_t* AXIS2_CALL
axis2_apache2_request_processor_create_soap_impl(
const axutil_env_t* env);
/**
* @brief Create JSON HTTP/2 optimized request processor
*
* This implementation provides thread-safe processing for HTTP/2 JSON requests
* without the concurrent modification issues of the original code.
*
* Features:
* - Thread-safe Accept header processing
* - HTTP/2 stream isolation
* - JSON-optimized request handling
* - Performance monitoring and tracing
* - Proper error reporting (JSON errors, not SOAP faults)
*
* Thread Safety: Full (isolated processing contexts)
* Performance: Optimized for HTTP/2 multiplexing
* Compatibility: New feature, no backward compatibility concerns
*
* @param env Axis2 environment
* @return New JSON processor instance or NULL on failure
*/
AXIS2_EXTERN axis2_apache2_request_processor_t* AXIS2_CALL
axis2_apache2_request_processor_create_json_impl(
const axutil_env_t* env);
/**
* @brief Factory method for creating appropriate processor based on request
*
* Analyzes incoming request characteristics to select the optimal processor:
* - Content-Type: application/json → JSON processor
* - Content-Type: text/xml, application/soap+xml → SOAP processor
* - HTTP Version: 2.0 + JSON content → JSON processor
* - Default: SOAP processor (backward compatibility)
*
* This factory enables zero-impact migration where existing requests continue
* using the original code paths while new JSON HTTP/2 requests get the
* optimized, thread-safe implementation.
*
* @param env Axis2 environment
* @param request Apache request record (for Content-Type analysis)
* @return Appropriate processor instance or NULL on failure
*/
AXIS2_EXTERN axis2_apache2_request_processor_t* AXIS2_CALL
axis2_apache2_request_processor_factory_create(
const axutil_env_t* env,
request_rec* request);
/**
* @brief Utility function to determine if request is HTTP/2 JSON
*
* Helper function for the factory to identify requests that should use
* the thread-safe JSON processor instead of the legacy SOAP processor.
*
* @param request Apache request record
* @return AXIS2_TRUE if HTTP/2 JSON request, AXIS2_FALSE otherwise
*/
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_apache2_request_processor_is_json_http2_request(
request_rec* request);
/**
* @brief Get processor implementation statistics
*
* Provides runtime statistics for monitoring and performance analysis:
* - Total requests processed
* - Average processing time
* - Thread safety violations detected
* - Memory allocation patterns
*
* @param processor The request processor instance
* @param env Axis2 environment
* @return Statistics hash table or NULL if not supported
*/
AXIS2_EXTERN axutil_hash_t* AXIS2_CALL
axis2_apache2_request_processor_get_statistics(
axis2_apache2_request_processor_t* processor,
const axutil_env_t* env);
#ifdef __cplusplus
}
#endif
#endif /* AXIS2_APACHE2_REQUEST_PROCESSOR_H */