Colm MacCarthaigh wrote:
On Wed, Aug 24, 2005 at 09:18:54AM -0500, Parin Shah wrote:
I have fixed that memory leak problem. also added script to include
libcurl whenever this module is included.
I hope that it doesn't mean that libcurl is going to be a permanent
solution, when subrequests (with minor changes) could serve the same
purpose.
Certainly not, We would have mod-c-requester which uses sub-requests
and not libcurl eventually. but my initial reaction after going
through the subrequest code was that it may require significant
refactoring.
Will it work if you mark the subrequests as proxy requests? IE, the same
approach as mod_rewrite and the P flag.
It introduces a dependency on mod_proxy, but curl introduces a
dependency on libcurl, so that's not so bad.
I've been through this loop a few times, and not really found a
satisfactory solution. Most recently for mod_publisher, which includes
what could perhaps become an apr_http_client module. But that's not
a path I want to embark on in isolation, when we have proxy and
subrequest code already there.
When I wrote that, I did look at the existing code, but reusing it
seemed more trouble than it was worth (this was before last year's
major refactoring of the proxy, FWIW). AFAICT none of the existing
modules exports an API for it.
My code is basically HTTP/1.1 with keepalives and connection pooling,
but no asynchronous operation. It's also DIY-with-fudges, and bugs
like not supporting HTTP 3xx responses that aren't redirects.
I think libcurl offers much richer capabilities, doesn't it?
So, is it time we introduced a general-purpose apr_http_client?
I'd be prepared to offer my code as a startingpoint, but I'd rather
not take the driving seat for further development and documentation.
Alternatively, maybe someone could post an executive summary of the
problems and benefits of standardising on libcurl?
--
Nick Kew
#ifndef APX_HTTP
#define APX_HTTP
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_hash.h>
#include <apr_uri.h>
#include <apr_strings.h>
#include <apr_network_io.h>
#include <apr_buckets.h>
typedef struct apx_http_entity apx_http_entity ;
typedef struct apx_http_request apx_http_request ;
typedef struct apx_http_response apx_http_response ;
typedef struct apx_http_connection apx_http_connection ;
typedef struct apx_http_connection_pool apx_http_connection_pool ;
struct apx_http_entity {
const char* type ;
size_t length ;
void* data ;
} ;
typedef enum {
HTTP_NONE ,
HTTP_READY ,
HTTP_SENDING_FIXED_DATA ,
HTTP_SENDING_CHUNKED_DATA ,
HTTP_REQUEST_SENT ,
HTTP_READING_DATA ,
HTTP_READING_FIXED_DATA ,
HTTP_READING_CHUNKED_DATA ,
HTTP_ERROR
} apx_conn_state_t ;
#define BUFLEN 4096
struct apx_http_connection {
const char* host ;
int port ;
apx_conn_state_t state ;
int is_proxy ;
apr_socket_t* sock ;
unsigned int timeout ;
size_t length ;
size_t bytes ;
size_t header_bytes ;
size_t clen ;
char buf[BUFLEN] ;
char savebuf[16] ;
} ;
struct apx_http_connection_pool {
const char* proxy_host ;
int proxy_port ;
union {
apx_http_connection* proxy_conn ;
apr_hash_t* connections ;
} conn ;
} ;
struct apx_http_request {
const char* method ;
apr_uri_t uri ;
apr_table_t* headers ;
int sent ;
const char* errmsg ;
apx_http_entity* contents ;
} ;
struct apx_http_response {
int status ;
const char* reason ;
apr_table_t* headers ;
};
int apx_uri_resolve_relative(apr_pool_t *p,
const apr_uri_t *base, apr_uri_t *uptr);
int apx_uri_parse_relative(apr_pool_t *p,
const apr_uri_t *base, const char* uri, apr_uri_t* uptr);
const char* apx_http_new_request(apr_pool_t* pool, apx_http_request* req,
const char* method, const char* url, const apr_uri_t* base) ;
apx_http_connection* apx_http_make_connection(apr_pool_t* pool,
apx_http_connection_pool* connpool, apx_http_request* req) ;
void apx_http_connection_set_timeout(apx_http_connection* conn, unsigned int timeout) ;
void apx_http_send(apx_http_connection* conn, const char* str) ;
const char* apx_http_send_request(apr_pool_t* pool, apx_http_request* req,
apx_http_connection* conn) ;
const char* apx_http_get_response(apr_pool_t* pool, apx_http_connection* conn,
apx_http_response* resp) ;
apx_http_connection_pool* apx_http_new_connection_pool(apr_pool_t* pool,
const char* host, int port) ;
apr_status_t apx_http_close_connection(void* conn) ;
apr_bucket* apx_http_get_data(apr_pool_t* pool, apr_bucket_alloc_t* alloc,
apx_http_connection* conn) ;
const char* apx_http_do(apr_pool_t* pool, apx_http_connection_pool* cpool,
const char* method, const char* url, const apr_uri_t* base,
apx_http_connection** connp, apx_http_response* resp,
apr_bucket_alloc_t* alloc, int depth) ;
#endif