Posts tagged ‘Python’

Apache external filter to emulate mod_qos

For one of our highly critical web-service we use mod_qos to add more security rules inside Apache in front the Application Server. I’ve been trying to recreate a similar environement on my work station and it was quite hard to get a windows version of mod_qos and mod_security. The feature I was trying to setup on Windows is the follwing :

- A client sends a soap request. The request shall contain a particular string, a client code, say XXX

- Apache, using mod_qos shall only allow requests with specific client codes, and reject anything else

- In case of a rejected request, Apache shall sends a specific XML response (rather than a HTTP code, etc.)

The production solution uses mod_qos directives :

QS_SetEnvIfBody “<code>(XXX|YYY|ZZZ)</code>” code=$1
QS_ErrorResponseCode 503
QS_DenyEvent +InvalidCode deny !code
ErrorDocument 503 myresponse.xml

That is : if the incoming request does not contain something like <code>XXX</code>, emit an HTTP 503 response code wich is finally translated into a custom XML response sent back to the client.

Getting the some implementation on a windows system is hard to come by. However, I managed getting some other dirty way to do it :

- Define an external filter for the web-service endpoint

- Create a small program (I wrote it first in PHP than move it to python to make it even more concise) that will be called in two ways  :

1.  As an input filter :

* Read the request body from stdin
* Check for the client code
* If found, write “OK” to a temp file, otherwise write “KO”
* Rewrite the request to stdout (forwarding it to the next filter in Apache chain)

2.  As an output filter :

* Read the response body from stdin
* Read the temp file
* if the temp file gives “OK”, write the response body as is to stdout, otherwise, read the custom xml response file and write its content to stdout.

Seen from the client, it gets the desired behavior : if it doesn’t send a client code in its soap request, it gets a specific XML response sent by Apache.

here is the Apache configuration :

ExtFilterDefine MyFilterIN   mode=input   cmd=”C:\\python\\python.exe C:\\my_filter.py IN”
ExtFilterDefine MyFilterOUT  mode=output  cmd=”C:\\python\\python.exe C:\\my_filter.py OUT”
<Location /Myservices/MyServiceEndPoint>
ExtFilterOptions DebugLevel=9 LogStderr
SetInputFilter  MyFilterIN
SetOutputFilter MyFilterOUT
</Location>

And this is the python piece of code doing the trick :


import sys
import re
TEMP_FILE    = "C:/my_temp.txt"
MY_XML        = "C:/503.xml"
soapData=''.join([x.strip() for x in sys.stdin.readlines()])
if( "IN" == sys.argv[1] ) :
        match = re.compile('.*<code>(XX|YY|ZZZ)</code>.*').match(soapData)
        f = open(TEMP_FILE,'w')
        f.write( "OK" if match else "KO" )
        f.close()
        print soapData
else :
        f = open(TEMP_FILE,'r')
        if( 'OK' == f.read().strip() ):
                print soapData
        else:
                custom = open(MY_XML,'r')
                print custom.read()
                custom.close()
        f.close()

I should confess that I was quite proud of the hack despite the dirtiness of the solution…

Java source highlighting

Here is a simple practical solution for highlighting source code served from an Apache web server. The motivation behind this was when I wondered how to allow syntax highlight for my SVN hosted source code when viwed with a browser. I came across a very useful tool written in python, pygmentize. Once this python module downloaded and installed, the following settings should be put in Apache httpd.conf file:

Action highlight /cgi-bin/highlight.py
AddHandler highlight .java

the highlight.py is a python script using pygmentise, and here’s the simplicity :


#!/bin/python
import cgi
import cgitb; cgitb.enable()
import os
from pygments import highlight
from pygments.lexers import JavaLexer
from pygments.formatters import HtmlFormatter

def main():
   print "Content-type: text/html\n"
   print highlight(open(os.environ['PATH_TRANSLATED']).read(), JavaLexer(), HtmlFormatter(full=True))

main()

Obviously, this will hilight java or whatever source code, but will not touch files served via WebDAV/SVN (Hopefully!)