You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Anthony J. Biacco" <ab...@formatdynamics.com> on 2009/06/05 01:26:06 UTC

custom header

Is there a way to set a custom HTTP header from tomcat/mod_jk for the
AJP connector? Short of changing the tomcat/mod_jk source code, that is.
I have requests go from apache -> mod_jk -> tomcat, multiple servers,
and I want to see in a Response header what tomcat my request is getting
processed by.

Thanx,

-Tony
---------------------------
Manager, IT Operations
Format Dynamics, Inc.
303-573-1800x27
abiacco@formatdynamics.com
http://www.formatdynamics.com



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: custom header

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

André,

On 6/5/2009 11:59 AM, André Warnier wrote:
> you should be able to do that with a servlet filter at the Tomcat
> level.

+1

At first read, it sounded like the OP was trying to set a header in
mod_jk so that Tomcat could read it. But it looks like exactly the
opposite is true: Tomcat should be setting the header in the response
before it goes back to httpd (and, ultimately, the client).

> Maybe have a look at the usual toolbox for this kind of thing : 
> urlrewritefilter at tuckey.org ? It should allow you to add a custom
> response header without any reprogramming.

Cool! André, you're quickly becoming our resident expert on url-rewrite.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkopQx4ACgkQ9CaO5/Lv0PDifACgrq3NZA0taKGnMUwFj6IU/Llv
+ukAoLEmLwf4PCkHR7xgYUkfQ63ZIGQ9
=uzOK
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: custom header

Posted by André Warnier <aw...@ice-sa.com>.
Anthony J. Biacco wrote:
> Thanx for that, that sets the header for me, but to something static.
> Only problem I have is I can't seem to figure out how to set it to the hostname of the tomcat server, or a tomcat variable (set from the hostname of the server - i.e. -Dmyjvmroute=`/bin/hostname -s` and then trying to use ${myjvmroute} in a rule such as:
> 
I must be missing something here.  Why would you want it to be "dynamic" ?

If you have several Tomcat instances as back-ends, then each one has its 
own webapps, and each one of these webapps has its own web.xml, which is 
where you configure its own urlrewrite filter.  So what is the problem 
in having it static in there ?

Or, wait, is it purely because you would like to be able to always 
distribute the same identical web.xml to all instances ?
That would then become a more generic issue like "how do I distribute 
the same war-file to several Tomcat instances, but have each instance 
pick up something instance-specific to include in its web.xml at load 
time ?"

Now, in this case I do believe that the urlrewrite filter uses a 
separate config file, in which maybe there is a way to specify something 
like that.  Maybe then just that file would need to be instance-specific ?


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: custom header

Posted by "Anthony J. Biacco" <ab...@formatdynamics.com>.
Thanx for that, that sets the header for me, but to something static.
Only problem I have is I can't seem to figure out how to set it to the hostname of the tomcat server, or a tomcat variable (set from the hostname of the server - i.e. -Dmyjvmroute=`/bin/hostname -s` and then trying to use ${myjvmroute} in a rule such as:

<urlrewrite>
<rule>
<from>.*</from>
<set type="response-header" name="X-appserver">${myjvmroute}</set>
</rule>
</urlrewrite>

Unofrtunately, I really don't have anything in the http request headers to base a condition off of to say what tomcat server I'm on.

-Tony
---------------------------
Manager, IT Operations
Format Dynamics, Inc.
303-573-1800x27
abiacco@formatdynamics.com
http://www.formatdynamics.com


> -----Original Message-----
> From: André Warnier [mailto:aw@ice-sa.com]
> Sent: Friday, June 05, 2009 10:00 AM
> To: Tomcat Users List
> Subject: Re: custom header
> 
> Anthony J. Biacco wrote:
> > Is there a way to set a custom HTTP header from tomcat/mod_jk for the
> > AJP connector? Short of changing the tomcat/mod_jk source code, that
> is.
> > I have requests go from apache -> mod_jk -> tomcat, multiple servers,
> > and I want to see in a Response header what tomcat my request is
> getting
> > processed by.
> >
> I am not sure that this is the quickest/easiest solution, but you
> should
> be able to do that with a servlet filter at the Tomcat level.
> Maybe have a look at the usual toolbox for this kind of thing :
> urlrewritefilter at tuckey.org ?
> It should allow you to add a custom response header without any
> reprogramming.
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: custom header

Posted by André Warnier <aw...@ice-sa.com>.
Anthony J. Biacco wrote:
> Is there a way to set a custom HTTP header from tomcat/mod_jk for the
> AJP connector? Short of changing the tomcat/mod_jk source code, that is.
> I have requests go from apache -> mod_jk -> tomcat, multiple servers,
> and I want to see in a Response header what tomcat my request is getting
> processed by.
> 
I am not sure that this is the quickest/easiest solution, but you should 
be able to do that with a servlet filter at the Tomcat level.
Maybe have a look at the usual toolbox for this kind of thing : 
urlrewritefilter at tuckey.org ?
It should allow you to add a custom response header without any 
reprogramming.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: custom header

Posted by Martin Gainty <mg...@hotmail.com>.

to run a test harness you can probably try this test harness for Ajp13 subbing header and header value here
        p.appendInt(3);

        p.appendString("my header");

        p.appendString("my header value");

/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.ajp.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.apache.ajp.Ajp13;
import org.apache.ajp.Ajp13Packet;
import org.apache.ajp.RequestHandler;
import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.MimeHeaders;

public class TestAjp13 extends TestCase {

    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( TestAjp13.class );

    Ajp13Server server = null;

    public TestAjp13(String name) {
        super(name);
    }

    public static Test suite() {
        return new TestSuite(TestAjp13.class);
    }

    protected void setUp() {
        println("setup...");

        server = new Ajp13Server();
        server.start();
    }

    protected void tearDown() {
        println("tear down...");

        server.shutdown();
    }

    public void test1() throws Exception {
        println("running test1");

        Socket s = new Socket("localhost", 8009);

        Ajp13Packet p = new Ajp13Packet(Ajp13.MAX_PACKET_SIZE);
        p.appendInt(0x1234);
        p.appendInt(0);
        p.setByteOff(4);
        p.appendByte(RequestHandler.JK_AJP13_FORWARD_REQUEST);
        p.appendByte((byte)2);
        p.appendString("http");
        p.appendString("/test_uri");
        p.appendString("remote_addr");
        p.appendString("remote_host");
        p.appendString("server_name");
        p.appendInt(80);
        p.appendBool(false);
        p.appendInt(3);
        p.appendString("my header");
        p.appendString("my header value");
        p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_AUTHORIZATION);
        p.appendString("some auth string");
        p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_USER_AGENT);
        p.appendString("TestAjp13 User Agent");
        p.appendByte(RequestHandler.SC_A_ARE_DONE);

        int len = p.getByteOff() - 4;
        p.setByteOff(2);
        p.appendInt(len);

        OutputStream os = s.getOutputStream();
        os.write(p.getBuff(), 0, len + 4);

        InputStream is = s.getInputStream();

        println("decoding response...");
        
        boolean done = false;
        while (!done) {
            int b1, b2;
            // read a packet

            // first 2 bytes should be AB
            b1 = is.read();
            assertTrue("byte 1 was " + (char)b1, b1 == (int)'A');
            b2 = is.read();
            assertTrue("byte 2 was " + (char)b2, b2 == (int)'B');

            println("b1 = " + (char)b1 + "; b2 = " + (char)b2);
            
            // next is length
            b1 = is.read();
            b1 &= 0xFF;
            b2 = is.read();
            b2 &= 0xFF;
            
            int l = (b1 << 8) + b2;

            println("length = " + l);

            // now get data
            byte[] buf = new byte[l];
            int n = 0;
            int off = 0;
            int total = 0;
            while ((n = is.read(buf, off, l - off)) != -1 && (l - off != 0)) {
                total += n;
                off += n;
            }

            println("read " + total);

            assertTrue("total read was " + total +
                       ", should have been " + l,
                       total == l);

            

            int code = (int)buf[0];

            switch (code) {
            case 3:
                println("AJP13_SEND_BODY_CHUNK ");
                break;
            case 4:
                println("AJP13_SEND_HEADERS ");
                break;
            case 5:
                println("AJP13_END_RESPONSE ");
                done = true;
                break;
            case 6:
                println("AJP13_GET_BODY_CHUNK ");
                break;
            default:
                assertTrue("invalid prefix code:  " + code, false);
                break;
            }
        }

        println("shutting down socket...");
        s.shutdownOutput();
        s.shutdownInput();
        s.close();

        println("done test1...");
    }

    protected static void println(String msg) {
        if (log.isDebugEnabled())
            log.debug("[TestAjp13] " + msg);
    }

    public static void main(String[] args) throws Exception {
    }
}

class Ajp13Server extends Thread {
    boolean shutdown = false;
    void shutdown() {
        this.shutdown = true;
        this.interrupt();
    }
    public void run() {
        try {
            ServerSocket server = new ServerSocket(8009);
            TestAjp13.println("Ajp13Server running...");
            Socket socket = server.accept();
            Ajp13 ajp13 = new Ajp13();
            MimeHeaders headers = new MimeHeaders();
            BaseRequest request = new BaseRequest();
            ajp13.setSocket(socket);

            boolean moreRequests = true;
            while (moreRequests && !shutdown) {
            
                int status = 0;
                try {
                    status = ajp13.receiveNextRequest(request);
                } catch (IOException e) {
                    if (shutdown) {
                        TestAjp13.println("Ajp13Server told to shutdown");
                        break;
                    }
                    TestAjp13.println("process: ajp13.receiveNextRequest -> " + e);
                }
            
                if( status==-2) {
                    // special case - shutdown
                    // XXX need better communication, refactor it
                    //                  if( !doShutdown(socket.getLocalAddress(),
                    //                                  socket.getInetAddress())) {
                    //                      moreRequests = false;
                    //                      continue;
                    //                  }
                    break;
                }
            
                // Special low level request allready handled (ie: PING/PONG)
                if( status == 999 )
                {
                    request.recycle();
                    continue;
                }
                
                if( status != 200 )
                    break;

                TestAjp13.println(request.toString());

                String message =
                    "<html><body><pre>" +
                    "hello from ajp13:  " +
                    System.getProperty("line.separator") +
                    request.toString() +
                    "</pre></body></html>";

                headers.addValue("content-type").setString( "text/html");
                headers.addValue("content-length").setInt(message.length());
                headers.addValue("my-header").setString( "my value");
                ajp13.sendHeaders(200, headers);

                byte[] b = message.getBytes();
                ajp13.doWrite(b, 0, b.length);

                ajp13.finish();

                request.recycle();
                headers.recycle();
            }

            try {
                ajp13.close();
            } catch (IOException e) {
                TestAjp13.println("process: ajp13.close ->" + e);
            }

            try {
                socket.close();
            } catch (IOException e) {
                TestAjp13.println("process: socket.close ->" + e);
            }
            socket = null;

            TestAjp13.println("process:  done");

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.toString());
        }
    }
}

HTH
Martin Gainty 
______________________________________________ 
Verzicht und Vertraulichkeitanmerkung
 
Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.






> Subject: custom header
> Date: Thu, 4 Jun 2009 17:26:06 -0600
> From: abiacco@formatdynamics.com
> To: users@tomcat.apache.org
> 
> Is there a way to set a custom HTTP header from tomcat/mod_jk for the
> AJP connector? Short of changing the tomcat/mod_jk source code, that is.
> I have requests go from apache -> mod_jk -> tomcat, multiple servers,
> and I want to see in a Response header what tomcat my request is getting
> processed by.
> 
> Thanx,
> 
> -Tony
> ---------------------------
> Manager, IT Operations
> Format Dynamics, Inc.
> 303-573-1800x27
> abiacco@formatdynamics.com
> http://www.formatdynamics.com
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 

_________________________________________________________________
Windows Live™: Keep your life in sync. 
http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009