Forum Moderators: phranque

Message Too Old, No Replies

Duplicating a request

Can I duplicate a request?

         

Scott_M

7:13 pm on May 26, 2010 (gmt 0)

10+ Year Member



Newbie question......

I have an Apache server with Perl handlers supporting the incoming requests. I'd like to
test some new code that will eventually replace the handlers.

Is there a way to duplicate/replicate the incoming request, with the Perl handlers continuing
to support the incoming requests, and a copy of the request coming to my new code?

My hope is to run the new code in parallel until the bugs are out of it, validating the
output against the output of the Perl handlers.

jdMorgan

2:04 pm on May 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've never done such a thing, but for lack of any other responses, you could try something like this:

Rewrite (i.e. use mod_rewrite) all requests to a "wrapper" script. In the script, "include" the originally-requested resource (this is a "call" to your old code.) Send that response to the client and save it to a uniquely-named file, then invoke "a call from the server to itself" using something like WGET. You will have to "tag" this request somehow -- perhaps with a custom request header, to prevent an infinite recursion.

You could in fact pass the old script's saved response filename in the custom HTTP request header, and use that "tag" for both purposes -- to indicate that the request is for the new code to handle, and to indicate to the invoked script that this is a "new-script" request whose output should be compared against the previously-stored "old script" response saved at the specified location.

The "wrapper" script must check this "tag" before invoking the WGET function -- It should detect this tag in the request, and if present, invoke the new code, saving the response and then comparing it with that of the old script, based on the previously-saved uniquely-named file. If the tag is not present, then that means the request is the "first one" that is coming from the actual client.

Once the comparison of old-script and new-script responses is accomplished, the 'saved' old-script response file should probably be deleted unless you have fairly low traffic and lots of disk space available.

Note that if needed, any HTTP request header can be checked by mod_rewrite using a RewriteCond with a construct like:

RewriteCond %{HTTP:[i]custom-header-name[/i]} ^[i]literal-header-value-or-pattern-to-match-the-value[/i]$

Also, a "check for blank" can be easily done with a pattern of ="" or ^$, while a "check for not blank" can be done with !="" or ^. or !^$

However, I suggest that you use the "wrapper script" for all complex functions, instead of splitting the control logic across both mod_rewrite code and this wrapper script.

Whether this will work or not is largely affected by what you want to test. If you are testing functions that depend largely on the nature of the client request, then you may need to 'copy' a lot of the client's original request headers into the WGET request. But you won't be able to 'spoof' the requesting IP address, except by passing it as a custom request header, and using that custom request headers value instead of the actual REMOTE_ADDR value if the 'tag' header is also set...

I hope this is clear -- It would likely be simpler to explain if I could draw a flowchart here... :)

Jim

Scott_M

3:39 pm on May 27, 2010 (gmt 0)

10+ Year Member



Would it be simpler if Apache was pushing a copy of the request to a Tomcat server? Then the Apache handlers would continue to support requests and the code on Tomcat would run independently.

jdMorgan

3:44 pm on May 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Probably, because it simplifies the "recursion problem." However, you may still need to 'equip' the recipient of the 'second request' with the ability to detect it and use and log the substitute REMOTE_ADDR instead of the front-end server's address.

In a way, generating the "second request" resembles a "smart" reverse-proxy through-put... If that concept is helpful. You could in fact use the X-Forwarded-For header to pass the actual client IP address, since your back-end server is likely already set up to use it.

Jim