Creating an Apache module

M

mydancake

I need to create an apache module which simply connects to a mysql
database, does some processing and returns some data to the users
browser.

I bet your wondering why I want to use an apache module rather than
PHP or Perl. I did some tests and PHP can handle around 30-40 requests
per second where as an apache module

it can handle 200+.

The code below is just a simple and crude test. I've had some some
trouble with the mysql part, for example, if I try to use
mysql_real_query I get undefined symbol:

mysql_real_query.

Also what would be the best way to handle connections to a mysql
database and where should I connect and close connections. Obviously I
don't want to connect on each request

received. Any example code would be appreciated.

Please be gentle, I'm fairly new to C.

#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
#include <mysql.h>

static int mytest_handler(request_rec* r)
{
if (!r->handler || strcmp(r->handler, "mytest"))
return DECLINED;

if (r->method_number != M_GET)
return HTTP_METHOD_NOT_ALLOWED;

MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;

char *server = "localhost";
char *user = "root";
char *password = "";
char *database = "mydatabase";

if (!mysql_real_connect(conn, server, user, password, database, 0,
NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
}

ap_set_content_type(r, "text/html;charset=ascii");

/* send SQL query */
if (mysql_real_query(conn, "SELECT * FROM mytable LIMIT 0, 10", 39))
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}

res = mysql_use_result(conn);

while ((row = mysql_fetch_row(res)) != NULL) {
ap_rputs("Got a row", r);
}

/* Release memory used to store results and close connection */
mysql_free_result(res);
mysql_close(conn);

return OK;
}

static void register_hooks(apr_pool_t* pool)
{
ap_hook_handler(mytest_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA mytest_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks
};
 
G

Guest

I need to create an apache module which simply connects to a mysql
database, does some processing and returns some data to the users
browser.

I bet your wondering why I want to use an apache module rather than
PHP or Perl. I did some tests and PHP can handle around 30-40 requests
per second where as an apache module

it can handle 200+.

The code below is just a simple and crude test. I've had some some
trouble with the mysql part, for example, if I try to use
mysql_real_query I get undefined symbol:

mysql_real_query.

Also what would be the best way to handle connections to a mysql
database and where should I connect and close connections. Obviously I
don't want to connect on each request

received. Any example code would be appreciated.

Please be gentle, I'm fairly new to C.

I think this is mostly a question for Apache or MySQL newsgroups.
Anyway, have you tried compiling your source linking libmysqlclient? On
gcc you should use -lmysqlclient option, on other systems or compilers
you may have to manually link libmysqlclient.a, libmysqlclient.so,
libmysqlclient.dll or something like that.
 
B

Barry Schwarz

I need to create an apache module which simply connects to a mysql
database, does some processing and returns some data to the users
browser.

I bet your wondering why I want to use an apache module rather than
PHP or Perl. I did some tests and PHP can handle around 30-40 requests
per second where as an apache module

it can handle 200+.

The code below is just a simple and crude test. I've had some some
trouble with the mysql part, for example, if I try to use
mysql_real_query I get undefined symbol:

mysql_real_query.

Also what would be the best way to handle connections to a mysql
database and where should I connect and close connections. Obviously I
don't want to connect on each request

received. Any example code would be appreciated.

Please be gentle, I'm fairly new to C.

Your sql or apache questions will get better responses in a newsgroup
that deals with those products. However, you have some C problems
also which this group can help with.
#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
#include <mysql.h>

static int mytest_handler(request_rec* r)
{
if (!r->handler || strcmp(r->handler, "mytest"))
return DECLINED;

if (r->method_number != M_GET)
return HTTP_METHOD_NOT_ALLOWED;

MYSQL *conn;

Unless you have C99, you need your declarations to appear before your
statements.
MYSQL_RES *res;
MYSQL_ROW row;

char *server = "localhost";
char *user = "root";
char *password = "";
char *database = "mydatabase";

if (!mysql_real_connect(conn, server, user, password, database, 0,
NULL, 0)) {

conn was never assigned a value. This statement invokes undefined
behavior by trying to pass that (non-existent) value to the function.
fprintf(stderr, "%s\n", mysql_error(conn));

You need to include stdio.h to use fprintf.
}

ap_set_content_type(r, "text/html;charset=ascii");

/* send SQL query */
if (mysql_real_query(conn, "SELECT * FROM mytable LIMIT 0, 10", 39))
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}

res = mysql_use_result(conn);

while ((row = mysql_fetch_row(res)) != NULL) {

Is row (type MYSQL_ROW) really a pointer. If not, use 0 instead of
NULL.
ap_rputs("Got a row", r);
}

/* Release memory used to store results and close connection */
mysql_free_result(res);
mysql_close(conn);

return OK;
}

static void register_hooks(apr_pool_t* pool)
{
ap_hook_handler(mytest_handler, NULL, NULL, APR_HOOK_MIDDLE);

Shouldn't this function use the parameter in some way?
}

module AP_MODULE_DECLARE_DATA mytest_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks
};

Is there a reason this file scope object appears at the end of your
source?
 
A

Antoninus Twink

conn was never assigned a value. This statement invokes undefined
behavior by trying to pass that (non-existent) value to the function.

As the OP described himself as "fairly new to C", it's probably worth
unpacking that rather cryptic statement written in standardese, as this
is a very common setup in C APIs.

Very frequently, libraries need to work with compound data structures -
what in other languages would be classes. Of course, C doesn't have
constructors, destructors, methods and the rest, so a very common way of
"doing OO programming in C" is for the library to deal in struct
pointers.

The relevant struct, let's say struct foo, will be defined in the header
file you #include to use the library. Then in your code, you'll create a
struct foo variable, say myfoo (statically, on the stack, or got from
malloc() at your choice). The library then provides a function with a
name like foo_init(), which is effectively the constructor. You call it
like

foo_init(&myfoo); /* maybe you need to pass some parameters too */

The library then fills in the fields in the struct pointed to by myfoo,
allocates any resources it needs, and generally does everything you'd
expect a class ctor to do.

And from then on, you can pass the address of myfoo to the other library
functions to manipulate it as you want:

foo_work_magic(&myfoo, 42); /* morally, this is myfoo->work_magic(42); */
foo_print_answer(&myfoo, stdout);
etc.

Finally, you call a function like foo_clear(), which is the destructor
that frees any memory that foo_init() allocated, etc.

It's the fact that your program clearly violates this paradigm by
defining a pointer to MYSQL directly, rather than having an actual MYSQL
and taking its address, that rang alarm bells for Barry.
Shouldn't this function use the parameter in some way?

I don't know about this particular function, but it's very common in
general for event handling functions to ignore some of their parameters,
so it's probably OK.

I agree with the suggestion that your direct problem (symbol not found)
is likely to be a linking problem caused by not linking with the
appropriate mysql library.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top