Posts Tagged ‘Apache’

Injecting server variables in a PHP script from an Apache module

January 21st, 2010

In case it help someone, here is a function that makes it possible to inject server variables in a PHP script so it is available in the $_SERVER array.

The function looks like this :

static void inject_server_variable(request_rec *r, const char *name, const char *value)
{
    apr_table_set(r->notes, name, value);
    apr_table_set(r->subprocess_env, name, value);
}

The line :

apr_table_set(r->notes, name, value);

makes it possible to fetch the variable by using the apache_note function.

The line :

apr_table_set(r->subprocess_env, name, value);

stores the variable in the $_SERVER array so it can be fetched only by doing a simple print($_SERVER['xxxx'])

:)

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Useful links for Apache module development

January 19th, 2010

If ever you plan to create your own Apache modules, here is a list of URLs which are helpful :

And last but not least the wonderful Apache Tutor website.

If you have other interesting links, feel free to post a comment with it and I will update this post.

‘Hope that helps.

:)

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Apache .htaccess and disk access, a quick but deeper look

October 30th, 2009

I was discussing (well twitting is more appropriate) with my friend Arnaud about .htaccess files and why they should not be used.

To be quick, using .htacess files is not good at all for disk performance because Apache will hit the disk for each HTTP request, so when the site is on production you can easily imagine this can quickly be an issue if you use those files.

But let’s have a look at how it actually work on the system.

Remember, for each HTTP request Apache will look on your file system if it finds a .htaccess file. So if we create the following virtual web application :

webproject
|-- cache
|-- design
|   |-- css
|   |-- html
|   |-- images
|   `-- javascript
`-- src
 |-- php
 `-- python

With the following directive in your Apache configuration file (wether a VirtualHost or not) :

<Directory "/path/to/webproject/">
 AllowOverride All
 [....]
 </Directory>

Now let’s have a look at how Apache handle AllowOverride on the Operating System, what happens if I visit the ‘webproject/src’ directory ?

Calling http://localhost/webproject/src generated the following system calls

1679/0x97c9998:  open("/Users/jerome/work/www/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/cache/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/design/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/src/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/src/python/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/src/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2
 1679/0x97c9998:  open("/Users/jerome/work/www/webproject/src/php/.htaccess\0", 0x0, 0x1B6)         = -1 Err#2

As you can see Apache looked for the .htaccess file for each directory I had to browse in order to go to the webfolder/src directory.

That is a simple example, but if you have a much more complex directory structure and a lot of traffic I guess you can imagine how much Apache is going to hit the disk in order to find a .htaccess file.

So in order to avoid that it is always recommended to configure everything in VirtualHosts and to avoid .htaccess files.

‘Hope that helped a bit

:)

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Parsing XML files with APR

August 17th, 2009

I wanted to write an XML parser for one of my personal projects, and I needed to use Apache APR for this. Since I did not find any example about doing this on the web I thought it might be a good idea to write a short tutorial about this. Maybe it could be helpful to someone else.

Let’s prepare the tutorial, we need a XML file, for example this one example.xml :
<?xml version="1.0" encoding="utf-8"?>
<document>
<a someattribute="attribute of A">
<b>the value of B</b>
</a>
</document>

And a Makefile, for example this one :

APR_CONFIG=$(shell which apr-1-config)
CC=gcc
CXX=g++
CFLAGS=$(shell ${APR_CONFIG} --cflags --cppflags --includes) -Wall
CXXFLAGS=$(shell ${APR_CONFIG} --cflags --cppflags --includes) -Wall
LDFLAGS=$(shell ${APR_CONFIG} --ldflags)
LDLIBS=$(shell ${APR_CONFIG} --libs --link-ld) -laprutil-1

Now the parser, parse.c:

#ifdef HAVE_CONFIG_H
#include
#endif

#include
#include

#include
#include

/**
* Dumps an XML document
*/
static void dump_xml( apr_xml_elem *e, apr_pool_t *pool )
{
apr_xml_elem *child_element;
const char *text;

if ( e->attr )
{
printf( "This tag has an attribute : <%s %s=%s>\n", e->name, e->attr->name, e->attr->value );
}

if (e->first_child)
{
child_element = e->first_child;

while (child_element)
{
printf( "<%s> --> ", child_element->name );
if( !APR_XML_ELEM_IS_EMPTY( child_element ) )
{
apr_xml_to_text( pool, child_element, APR_XML_X2T_INNER, NULL, NULL, &text, NULL);
printf( "%s\n", text );
}
dump_xml( child_element, pool );
child_element = child_element->next;
}
}
}

/**
* Process an XML file
* @return APR_SUCCESS if success, otherwise -1
*/
static int process_xml_file( const char *filename, apr_pool_t *pool )
{
apr_file_t *fp;
apr_status_t rv;
apr_xml_parser *parser;
apr_xml_doc *doc;
char *errbuf;

if ( ( rv = apr_file_open( &fp, filename, APR_FOPEN_READ, APR_OS_DEFAULT, pool ) ) != APR_SUCCESS ) {
return -1;
}

rv = apr_xml_parse_file( pool, &parser, &doc, fp, 2000 );

if( rv != APR_SUCCESS )
{
printf( "Error : %s", apr_xml_parser_geterror( parser, errbuf, 255 ) );
return -1;
}

dump_xml( doc->root, pool );

return APR_SUCCESS;
}

int main(int argc, char **argv)
{
apr_pool_t *pool;
const char *filename;

if ( argc == 2 )
{
filename = argv[1];
}
else
{
filename = "example.xml";
}

apr_initialize();
apr_pool_create( &pool, NULL );

process_xml_file( filename, pool );

apr_terminate();
return 0;
}

Now store example.xml and parse.c in the same directory and build parse.c

make parse && ./parse filename.xml

You should get the following result:
<a> -->
<b>the value of B</b>

This tag has an attribute : <a someattribute=attribute of A>
<b> --> the value of B

Some useful documentation :

You can dowload the files here

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)