Search code examples
apacheapache2httpserverapache2.4apache2-module

How to filter based on request URL in Apache HTTP server


I want to have a apache http server in between my application and client.

A query parameter has to be passed on accessing by client. For example, if my client is running in http://myhost:myport/myapp then it has to be accessed only by passing the parameter myparam. Like http://myhost:myport/myapp?myparam=123.

So in my apache http server I want to filter the requests which does not contain the query parameter myparam.

I tried using filters. It has some predefined filters but none of the filters satisfy my requirement. I tried using mod_ext_filter. But it seems the entire content being passed to my program, not the URL. Since I need to filter based on the parameter present in URL I don't think it satisfy my requirement.

Is there any http server module which can be be used to filter based on parameter being passed in URL?

EDIT

In addition, I need to get the value from query param and validate it as well. The validation is a REST service call


Solution

  • In 2.4 you can do something as simple as:

    <Location /myapp>
      Require expr %{QUERY_STRING} =~ /myparam/
    </location>
    

    You can probably do this with <if> and captures, but I don't know how you can get it to lookup a "map" of context root to query param.

    If you have many myapp->myparam pairs, you might want to go to old school mod_rewrite and store them in a txt-based rewritemap. Here is an example that has a couple of "interesting" rewrite tricks to accomplish what you described:

    RewriteMap foo txt:/tmp/rewrite.map
    RewriteEngine ON
    # Fancy way to check two variables are equal in a RewriteCond
    RewriteCond %{QUERY_STRING},${foo:$1} !^([^,]+),\1
    # grab the first segment
    RewriteRule ^/([^/]+)/ - [F]
    

    But (if as discussed later in comments) you need to retrieve the map from some kind of remote web service you will need to implement a C or Lua module inside of httpd. The difficult part there becomes retrieving the remote response, the other parts are trivial:

    You could write your own access_checker module that finds r->uri and r->args pretty easily. But you need your own http client to make the outgoing REST call -- there is no API for this in the core. – covener Aug 24 at 13:27