Reputation: 87
I want to parse the POST data from browser in Apache module using "C". As per Apache API documentation, the function ap_parse_form_data can be used for this. The function is declared in httpd.h, and I have included it in my module:
...
#include <httpd.h>
#include <apr_tables.h>
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
...
keyValuePair* readPost(request_rec* r) {
...
apr_array_header_t *pairs=NULL;
int res;
...
res = ap_parse_form_data(r, NULL, &pairs, -1, 8192);
The program is compiled successfully using apxs2 command and the module was installed in the proper path. But, when I start Apache server, it throws error like:
apache2: Syntax error on line 204 of /etc/apache2/apache2.conf:
Syntax error on line 1 of /etc/apache2/mods-enabled/apache_post.load:
Cannot load /usr/lib/apache2/modules/mod_apache_post.so into server:
/usr/lib/apache2/modules/mod_apache_post.so: undefined symbol:
ap_parse_form_data
undefined symbol:ap_parse_form_data
Any tips to figure this out?
Upvotes: 2
Views: 1217
Reputation: 7820
I update this thread because somebody wants answer for this it will help.
#include "httpd.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_request.h"
#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_dbd.h"
#include <apr_file_info.h>
#include <apr_file_io.h>
#include <apr_tables.h>
#include "util_script.h"
typedef struct {
const char* key;
const char* value;
} keyValuePair;
/* Define prototypes of our functions in this module */
static void register_hooks(apr_pool_t *pool);
static int example_handler(request_rec *r);
keyValuePair* readPost(request_rec* r);
/* Define our module as an entity and assign a function for registering hooks */
module AP_MODULE_DECLARE_DATA example_module =
{
STANDARD20_MODULE_STUFF,
NULL, // Per-directory configuration handler
NULL, // Merge handler for per-directory configurations
NULL, // Per-server configuration handler
NULL, // Merge handler for per-server configurations
NULL, // Any directives we may have for httpd
register_hooks // Our hook registering function
};
/* register_hooks: Adds a hook to the httpd process */
static void register_hooks(apr_pool_t *pool)
{
/* Hook the request handler */
ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
}
/* The handler function for our module.
* This is where all the fun happens!
*/
keyValuePair* readPost(request_rec* r) {
apr_array_header_t *pairs = NULL;
apr_off_t len;
apr_size_t size;
int res;
int i = 0;
char *buffer;
keyValuePair* kvp;
res = ap_parse_form_data(r, NULL, &pairs, -1, HUGE_STRING_LEN);
if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */
kvp = apr_pcalloc(r->pool, sizeof(keyValuePair) * (pairs->nelts + 1));
while (pairs && !apr_is_empty_array(pairs)) {
ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
apr_brigade_length(pair->value, 1, &len);
size = (apr_size_t) len;
buffer = apr_palloc(r->pool, size + 1);
apr_brigade_flatten(pair->value, buffer, &size);
buffer[len] = 0;
kvp[i].key = apr_pstrdup(r->pool, pair->name);
kvp[i].value = buffer;
i++;
}
return kvp;
}
static int example_handler(request_rec *r)
{
/*~~~~~~~~~~~~~~~~~~~~~~*/
keyValuePair* formData;
/*~~~~~~~~~~~~~~~~~~~~~~*/
formData = readPost(r);
if (formData) {
int i;
for (i = 0; &formData[i]; i++) {
if (formData[i].key && formData[i].value) {
ap_rprintf(r, "%s = %s\n", formData[i].key, formData[i].value);
} else if (formData[i].key) {
ap_rprintf(r, "%s\n", formData[i].key);
} else if (formData[i].value) {
ap_rprintf(r, "= %s\n", formData[i].value);
} else {
break;
}
}
}
return OK;
}
so after saving above code with some name (mod_example.c) then you can compile this using apxs like this
apxs -i -a -c mod_example.c
then in apache2.conf(etc/apache2/) file add this one.
<Location "/exampleDir">
SetHandler example-handler
</Location>
then try to send post request to derectory /exampleDir.Follow this tutorial http://httpd.apache.org/docs/2.4/developer/modguide.html for more information.
Upvotes: 2