Forum Discussion

Roman_80473's avatar
Roman_80473
Icon for Nimbostratus rankNimbostratus
Nov 29, 2011

Redirect to another URL from inside HTTP::REQUEST after timeout detected

Hi guys,

 

 

I have setup the timer using the 'after' command inside HTTP_REQUEST which I then cancel in HTTP_RESPONSE. I detect timeout and take node out of the mix. I then need to redirect request to another url, however both HTTP::redirect and HTTP::response give me the following errors:

 

 

- Illegal argument. Can't execute in the current context. (line 1) invoked from within "HTTP::redirect $theUrl"

 

- Illegal argument. Can't execute in the current context. (line 1) invoked from within "HTTP::respond 302 Location "$theUrl""

 

 

 

Is there a way around it?

 

 

Thank you, Roman
  • can you try this?

     

     

    ...

     

    log local0.debug "2. Redirecting to $theUrl"

     

    both redirect and respond give "Illegal argument. Can't execute in the current context. (line 1)", TCP::respond has no effect

     

    HTTP::redirect $theUrl

     

    HTTP::respond 302 Location "$theUrl"

     

    TCP::respond "HTTP/1.1 302 Found\r\nLocation: $theUrl\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"

     

    }\

     

    ...

     

     

    this is mine.

     

     

    [root@ve1023:Active] config curl -I http://172.28.19.79

     

    HTTP/1.1 302 Found

     

    Location:

     

    Connection: close

     

    Content-Length: 0

     

    [root@ve1023:Active] config

     

    Nov 30 11:47:19 local/tmm debug tmm[23027]: Rule myrule HTTP_REQUEST: F5 Host: 172.28.19.79, /, 80 ... Server: :

     

    Nov 30 11:47:19 local/tmm debug tmm[23027]: Rule myrule LB_SELECTED: In lb_selected, server is 200.200.200.101:80 ...

     

    Nov 30 11:47:19 local/tmm info tmm[23027]: Rule myrule HTTP_REQUEST: *** Timeout after 3 ms ***

     

    Nov 30 11:47:19 local/tmm debug tmm[23027]: Rule myrule HTTP_REQUEST: 1. Taking node 200.200.200.101:80 out of the mix ...

     

    Nov 30 11:47:19 local/tmm err tmm[23027]: 01010028:3: No members available for pool foo

     

    Nov 30 11:47:19 local/tmm debug tmm[23027]: Rule myrule HTTP_REQUEST: 2. Redirecting to

     

    Nov 30 11:47:19 local/ve1023 err mcpd[21973]: 01070809:3: iRule has marked pool member 200.200.200.101:80 down, no monitor to mark up.

     

    Nov 30 11:47:19 local/ve1023 notice mcpd[21973]: 01070638:5: Pool member 200.200.200.101:80 monitor status iRule down.

     

  • Hi Roman,

     

     

    I have been looking at your iRule. The first thing that I am noticing is that you are setting variables in the RULE_INIT event that are being reset in the CLIENT_ACCEPTED Event and then again in the HTTP_REQUEST Event.

     

     

    The RULE_INIT is triggered when an iRule is added or is modified.

     

    The CLIENT_ACCEPTED is triggered for each client when they connect to the Virtual Server hosting the iRule the first time.

     

    The HTTP_REQUEST for each individual request.

     

     

    So you are doing some work twice for nothing when you could just do them in the HTTP_REQUEST event (since you are resetting them for each individual request anyway).

     

     

    These are the ones I am referring to:

     

    set theUrl ""

     

    set retry 0

     

    set server_addr ""

     

    set server_port ""

     

    set host_name ""

     

    set host_uri ""

     

    set host_port ""

     

    set host_port_str ""

     

    set host_protocol ""

     

    set postBackUrl ""

     

     

    As far as your error, can reproduce the error, but I am wondering if the illegal argument error that you are getting is due to something missing.

     

     

    What does the logging statement show in your LTM Log:

     

    log local0.debug "2. Redirecting to $theUrl"

     

     

    Does it appear to be the correct URL that it should be?

     

  • Hi nitass,

     

     

    Thanks for your reply. Yes, I've tried the "&", and LTM has choked on the syntax:

     

    Rule Smart_LB_Rule : 1. Taking node 10.2.178.121:8001 out of the mix ...

     

    TCL error: Smart_LB_Rule - invalid command name "host=10.2.178.121&" while executing "host=$server_addr&"

     

     

    Funny thing is that this scenario works fine inside LB_FAILED (when server is down), and I do get redirected to the controller url. The same goes for HTTP_RESPONSE when I detect http code > 500. I have a feeling it's the "after" command pecularities which prevent me from doing redirect.

     

     

    Thank you,

     

    Roman

     

     

    PS: You must have edited your post while I've been trying your suggestion :)
  • Yes, I've tried the "&", and LTM has choked on the syntax:sorry, have you tried TCP::respond i posted? it seems working in my lab unit.

     

     

    TCP::respond "HTTP/1.1 302 Found\r\nLocation: $theUrl\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"

     

     

    PS: You must have edited your post while I've been trying your suggestion :)yes, it seems devcentral does not like triangle bracket. so, i had to edit my post. :-)
  • Hi Michael,

     

     

    Thank you very much for looking into my messy rule. Yes, you're abs right, and I do need a lot of cleaning to do. I will as soon as I get it working, I promise.

     

     

    As far as the url, this is what I see in the logs (masking sensitive data):

     

    Rule Smart_LB_Rule : In lb_selected, server is server.ip.address:8001 ...

     

    Rule Smart_LB_Rule : *** Timeout after 15000 ms ***

     

    Rule Smart_LB_Rule : 1. Taking node server.ip.address:8001 out of the mix ...

     

    Rule Smart_LB_Rule : 2. Redirecting to http://domain_name.company_name.com/controller/?source=ltm&action=restart&host=server.ip.address&service=/bad/&port=8001&name=&cause=no_response_from_server_after_15000_ms&postBack=http://domain_name.company_name.com/bad/

     

    TCL error: Smart_LB_Rule - Illegal argument. Can't execute in the current context. (line 1) invoked from within "HTTP::redirect $theUrl "

     

     

    The url is valid, and if I put it in the browser, it works just fine. It also works (the HTTP::redirect $theUrl command) from inside both LB_FAILED and HTTP_RESPONSE events (as I've described to nitass). I have a sneaky suspicion it's the "after" timer that is giving me a trouble.

     

     

    Thank you,

     

    Roman
  • Hi nitass,

     

     

    Sorry, I didn't see TCP::respond in your post. I've tested my rule with it a dozen times, and it seems to be working fine! I'm pretty sure I've tried the TCP::respond beforehand, but I guess I didn't have the complete syntax

     

     

    Thank you very much for your help!

     

    Roman
  • The solution is there, but did anyone ever determine why the HTTP::redirect is being executed within the CLIENT_ACCEPTED context, as the error message states? Why isn't it being executed only within the HTTP_RESPONSE or HTTP_REQUEST contexts?

     

     

    What is it about using "after" and a timeout period that seems to cause the code to be run in the CLIENT_ACCEPTED context?

     

     

    I have a similar rule that uses an after that periodically triggers a similar error (only difference is that I'm trying to use HTTP::respond). I put the command in the HTTP_REQUEST context, yet it's being triggered in the CLIENT_ACCEPTED context.
  • not sure if i catch you correctly. anyway, i am also wondering what context after's script is running is.

     

     

    for example, when using HTTP::redirect instead of TCP::respond in the following example, i got context error.

     

     

    send response from BigIP if server does not respond within a specified amount of time

     

    https://devcentral.f5.com/wiki/iRules.after.ashx

     

     

    /var/log/ltm

     

    Aug 10 15:30:03 local/tmm info tmm[4860]: Rule myrule : Timeout 1000 milliseconds elapsed without server response. 1344583803

     

    Aug 10 15:30:03 local/tmm err tmm[4860]: 01220001:3: TCL error: myrule - Illegal argument. Can't execute in the current context. (line 1) invoked from within "HTTP::redirect "http://www.google.com/""

     

     

    i think i will open a case to verify unless someone here can give me a shot. :-)