mturk 2004/07/30 01:26:37 Modified: ajp/ajplib/test httpd_wrap.h httpd_wrap.c Log: Added client_block functions for reading post data. Revision Changes Path 1.7 +59 -1 jakarta-tomcat-connectors/ajp/ajplib/test/httpd_wrap.h Index: httpd_wrap.h =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/ajplib/test/httpd_wrap.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- httpd_wrap.h 29 Jul 2004 06:52:32 -0000 1.6 +++ httpd_wrap.h 30 Jul 2004 08:26:37 -0000 1.7 @@ -337,6 +337,11 @@ /** The handler string that we use to call a handler function */ const char *handler; /* What we *really* dispatch on */ + /** Remaining bytes left to read from the request body */ + apr_off_t remaining; + /** Number of bytes that have been read from the request body */ + apr_off_t read_length; + /** How to encode the data */ const char *content_encoding; /** Array of strings representing the content languages */ @@ -366,7 +371,7 @@ void *per_dir_config; /** Notes on *this* request */ void *request_config; - + }; /** Structure to store things which are per connection */ @@ -402,6 +407,8 @@ void *sbh; /** The bucket allocator to use for all bucket/brigade creations */ struct apr_bucket_alloc_t *bucket_alloc; + /** This doesn't exists in the original, but it is here to simulate the network */ + apr_bucket_brigade *bb; }; /** A structure to be used for Per-vhost config */ @@ -621,6 +628,57 @@ */ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip); +/* Reading a block of data from the client connection (e.g., POST arg) */ + +/** + * Setup the client to allow Apache to read the request body. + * @param r The current request + * @param read_policy How the server should interpret a chunked + * transfer-encoding. One of: <pre> + * REQUEST_NO_BODY Send 413 error if message has any body + * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length + * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me. + * </pre> + * @return either OK or an error code + * @deffunc int ap_setup_client_block(request_rec *r, int read_policy) + */ +AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy); + +/** + * Determine if the client has sent any data. This also sends a + * 100 Continue response to HTTP/1.1 clients, so modules should not be called + * until the module is ready to read content. + * @warning Never call this function more than once. + * @param r The current request + * @return 0 if there is no message to read, 1 otherwise + * @deffunc int ap_should_client_block(request_rec *r) + */ +AP_DECLARE(int) ap_should_client_block(request_rec *r); + +/** + * Call this in a loop. It will put data into a buffer and return the length + * of the input block + * @param r The current request + * @param buffer The buffer in which to store the data + * @param bufsiz The size of the buffer + * @return Number of bytes inserted into the buffer. When done reading, 0 + * if EOF, or -1 if there was an error + * @deffunc long ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz) + */ +AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz); + +/** + * In HTTP/1.1, any method can have a body. However, most GET handlers + * wouldn't know what to do with a request body if they received one. + * This helper routine tests for and reads any message body in the request, + * simply discarding whatever it receives. We need to do this because + * failing to read the request body would cause it to be interpreted + * as the next request on a persistent connection. + * @param r The current request + * @return error status if request is malformed, OK otherwise + * @deffunc int ap_discard_request_body(request_rec *r) + */ +AP_DECLARE(int) ap_discard_request_body(request_rec *r); /** * create the request_rec structure from fake client connection 1.9 +69 -2 jakarta-tomcat-connectors/ajp/ajplib/test/httpd_wrap.c Index: httpd_wrap.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/ajplib/test/httpd_wrap.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- httpd_wrap.c 29 Jul 2004 06:52:32 -0000 1.8 +++ httpd_wrap.c 30 Jul 2004 08:26:37 -0000 1.9 @@ -555,7 +555,74 @@ apr_table_addn(r->headers_in, "Accept-Charset", "iso-8859-2"); apr_table_addn(r->headers_in, "Accept-Language", "hr"); - /* TODO: create bucket brigade for post data */ - + /* Create a simple bucket brigade for post data inside connection */ + if (content) { + apr_bucket *e; + if (!r->connection->bucket_alloc) + r->connection->bucket_alloc = apr_bucket_alloc_create(r->connection->pool); + r->connection->bb = apr_brigade_create(r->connection->pool, + r->connection->bucket_alloc); + e = apr_bucket_transient_create(content, content_length, r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(r->connection->bb, e); + + } return APR_SUCCESS; } + +AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy) +{ + const char *lenp = apr_table_get(r->headers_in, "Content-Length"); + + r->remaining = 0; + r->read_length = 0; + if (lenp) + r->remaining = atoi(lenp); + return OK; +} + +AP_DECLARE(int) ap_should_client_block(request_rec *r) +{ + /* First check if we have already read the request body */ + + if (r->read_length || r->remaining <= 0) + return 0; + else + return 1; +} + +AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, + apr_size_t bufsiz) +{ + apr_status_t rv; + + if (r->remaining < 0 || r->remaining == 0) + return 0; + + rv = apr_brigade_flatten(r->connection->bb, buffer, &bufsiz); + + if (rv != APR_SUCCESS) { + return -1; + } + + r->read_length += bufsiz; + r->remaining -= bufsiz; + + /* Remove the readed part */ + if (bufsiz) { + apr_bucket *e; + e = APR_BRIGADE_FIRST(r->connection->bb); + apr_bucket_split(e, bufsiz); + e = APR_BRIGADE_FIRST(r->connection->bb); + APR_BUCKET_REMOVE(e); + } + + return (long)bufsiz; + +} + +/* No op */ +AP_DECLARE(int) ap_discard_request_body(request_rec *r) +{ + return OK; +} +
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]