Generate HTTP(S) requests from Tcl shell

A few days ago, a reader sent me an e-mail titled “Telnet Automation from a Cisco Router” and complained that IOS Tcl does not support the expect commands (spawn, send and expect). Since Expect is a Tcl extension, not part of the core Tcl, it’s not included in Cisco IOS, which was the only answer I could give.

You might be able to port Expect to IOS as a Tcl package if it doesn’t require external libraries.

However, it turned out that the reader actually wanted to trigger HTTP requests from the router. Cisco IOS Tcl has some built-in client-side HTTP support, but it’s far simpler to rely on the built-in http: file system. For example, to do a HTTP GET request, use the following Tcl command:

rtr#tclsh
rtr(tcl)#set result [exec {more http://webServer/index.html}]
<h1>Empty</h1>

As always, there are a few caveats:

  • You can trigger HTTP GET requests, but not the PUT or POST requests.
  • The server-side script should always return the HTTP status 200 (successful), otherwise the more command will fail. The actual status can be passed in the HTML response.

You can use the same trick to trigger HTTPS requests from Tcl.

14 comments:

  1. on the same note can you trigger HTTP requests from EEM.

    I'll give an example/reason, I generally get sms alerts for some alarms eg bgp neighbor going down/up, these are sent out to syslog, some scripts pick it up, and call a url (using kannel) and an sms is sent. Lately we did the same with our nms; ie the nms calls up a script when some alert gets picked up.....

    If EEM can call/trigger http, then i could just do it directly from the router.

    thanks...
    Gitau
  2. Of course you can do the same from the EEM applet (you might have problems with URL escaping though). Will write a proof-of-concept code.
  3. Hi Ivan,

    Only for info, the builtin HTTP seems to be blocked by "default" Modsecurity which results in "permission denied" on cisco client-side.

    Best regards,

    [Mon Jan 19 13:50:49 2009] [error] [client 1.2.3.4] ModSecurity: Access denied with code 403 (phase 2). Match of "rx ^OPTIONS$" against "REQUEST_METHOD" required. [file "/etc/modsecurity/modsecurity_crs_21_protocol_anomalies.conf"] [line "41"] [id "960015"] [msg "Request Missing an Accept Header"] [severity "CRITICAL"] [tag "PROTOCOL_VIOLATION/MISSING_HEADER"] [hostname "4.3.2.1"] [uri "/index.html"] [unique_id "X0F35H8AAQEAAGL@ligAAAAJ"]
  4. @Francois: Am I right in assuming you've taken the log from an Apache server?
  5. @Ivan: You are correct :)
  6. In this case, it's ModSecurity's fault. Just checked the RFC2616 (HTTP) and the Accept header is not mandatory (but it's true that it's sent by all browsers and obviously not by some bots).
  7. Can you trap for an error if the server replies with a code other than 200?
  8. The "more" command probably fails and you could try to catch that.
  9. When issuing an HTTP request from IOS CLI (using more, or something else), is it possible to specify the source IP address?

    The goal is to try to emulate a host's HTTP GET using the router than a PC.

    Frank
  10. Use the "ip http client source-interface" global configuration command.
  11. Hi Ivan,
    I need to make a GET to a URL but when this fail, I throw shutdown a interface router for switched traffic, as I do?
    Thanks.
  12. Hi Ivan,

    Did you ever write a POC to see if you could re-route on http status? I have a similar requirement and came across this post on a google search.

    Thanks
    bruce
  13. Is there any chance that you can validate the the https side works. I have tried every approach I can think of and it still fails. There must be an avenue since services such as WAAS Express register via https. The intent would be to post info to a web site that has a sef signed certificate as most services are being encrypted with SSL now.
Add comment
Sidebar