Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Creating an Apache module

Reply
Thread Tools

Creating an Apache module

 
 
mydancake@googlemail.com
Guest
Posts: n/a
 
      02-06-2009
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
};
 
Reply With Quote
 
 
 
 
Guest
Posts: n/a
 
      02-07-2009
wrote:
> 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.

--
-----BEGIN GEEK CODE BLOCK-----
GCS/CM/CC/E/IT/LS/M d-(--) C++++$ UBL++++$ P++++ L+++++$ E--- W+++ w--
PS+++ PE-- Y++ PGP+++ R++ tv-- b++>+++ D+ G>+++ e++>+++++ h* r++ z+++
------END GEEK CODE BLOCK------
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      02-07-2009
On Fri, 6 Feb 2009 15:37:18 -0800 (PST),
wrote:

>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?

--
Remove del for email
 
Reply With Quote
 
Antoninus Twink
Guest
Posts: n/a
 
      02-07-2009
On 7 Feb 2009 at 1:30, Barry Schwarz wrote:
> On Fri, 6 Feb 2009 15:37:18 -0800 (PST),
> wrote:
>> 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.


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.

>>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?


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.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Apache Tomcat5.5 clustering problem with Apache HTTP server 2.2.4 tanmoy.b81 Java 0 02-04-2009 08:46 AM
Problems running Apache FOP: org.apache.fop.fo.FOTreeBuilder fatalError Pablo Java 0 03-28-2007 02:31 PM
org/apache/xpath/objects/XObject incompatible with org/apache/xpath/objects/XNodeSet duduch_1er@hotmail.com XML 4 08-10-2006 01:38 PM
Apache FileUpload - java.lang.NoClassDefFoundError: org/apache/commons/io/FileCleaner kebabkongen@hotmail.com Java 2 03-16-2006 09:20 AM
AXIS jars org.apache.axis.wsi.* and org.apache.axis.transport.jms.* unkwb@web.de Java 0 02-23-2005 04:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57