Convert curl command to BIG-IP Monitor Send String
Problem this snippet solves:
Convert curl commands into a HTTP or HTTPS monitor Send String.
How to use this snippet:
Save this code into a Python script and run as a replacement for curl.
Related Article: How to create custom HTTP monitors with Postman, curl, and Python
An example would be:
% python curl_to_send_string.py -X POST -H "Host: api.example.com" -H "User-Agent: Custom BIG-IP Monitor" -H "Accept-Encoding: identity" -H "Connection: Close" -H "Content-Type: application/json" -d '{ "hello": "world" } ' "http://10.1.10.135:8080/post?show_env=1" SEND STRING: POST /post?show_env=1 HTTP/1.1\r\nHost: api.example.com\r\nUser-Agent: Custom BIG-IP Monitor\r\nAccept-Encoding: identity\r\nConnection: Close\r\nContent-Type: application/json\r\n\r\n{\n \"hello\":\n \"world\"\n}\n
Code :
Python 2.x
import getopt import sys import urllib optlist, args = getopt.getopt(sys.argv[1:], 'X:H:d:') flat_optlist = dict(optlist) method = flat_optlist.get('-X','GET') (host,uri) = urllib.splithost(urllib.splittype(args[0])[1]) protocol = 'HTTP/1.1' headers = ["%s %s %s" %(method, uri, protocol)] headers.extend([h[1] for h in optlist if h[0] == '-H']) if not filter(lambda x: 'host:' in x.lower(),headers): headers.insert(1,'Host: %s' %(host)) send_string = "\\r\\n".join(headers) send_string += "\\r\\n\\r\\n" if '-d' in flat_optlist: send_string += flat_optlist['-d'].replace('\n','\\n') send_string = send_string.replace("\"", "\\\"") print "SEND STRING:" print send_string
Python 3.x
import getopt
import sys
from urllib.parse import splittype, urlparse
optlist, args = getopt.getopt(sys.argv[1:], 'X:H:d:')
flat_optlist = dict(optlist)
method = flat_optlist.get('-X','GET')
parts = urlparse(splittype(args[0])[1])
(host,uri) = (parts.hostname,parts.path)
protocol = 'HTTP/1.1'
headers = ["%s %s %s" %(method, uri, protocol)]
headers.extend([h[1] for h in optlist if h[0] == '-H'])
if not filter(lambda x: 'host:' in x.lower(),headers):
headers.insert(1,'Host: %s' %(host))
send_string = "\\r\\n".join(headers)
send_string += "\\r\\n\\r\\n"
if '-d' in flat_optlist:
send_string += flat_optlist['-d'].replace('\n','\\n')
send_string = send_string.replace("\"", "\\\"")
print("SEND STRING:")
print(send_string)
Tested this on version:
11.5
- Danny_ArroyoCirrus
Eric,
I just tried your script on v11.4.1 and it worked perfectly. Thanks!!!
- Buddy_Edwards_1Nimbostratus
I'd like to say first that this is a great piece of code that has saved me a lot of headaches so thank you for creating it. The original script runs great in Python2 but had need for it to run natively in Python3 as the interpreter. This is a modified version that works in Python3.
Code import getopt import sys from urllib.parse import splithost, splittype optlist, args = getopt.getopt(sys.argv[1:], 'X:H:d:') flat_optlist = dict(optlist) method = flat_optlist.get('-X', 'GET') (host, uri) = splithost(splittype(args[0])[1]) protocol = 'HTTP/1.1' headers = ["%s %s %s" % (method, uri, protocol)] headers.extend([h[1] for h in optlist if h[0] == '-H']) if not fil`text`ter(lambda x: 'host:' in x.lower(), headers): headers.insert(1, 'Host: %s' % (host)) send_string = "\\r\\n".join(headers) send_string += "\\r\\n\\r\\n" if '-d' in flat_optlist: send_string += flat_optlist['-d'].replace('\n', '\\n') send_string = send_string.replace("\"", "\\\"") print("SEND STRING: " + send_string)
- Eric_ChenEmployee
Awesome! Thank you for sharing.
- scyonix_360392Nimbostratus
Hi I tried this but health monitoring is showing down, Logs says its a malformed request
this is my curl command which works as expected:
curl -X POST -H 'content-type: application/json' -H 'host: host.domain.com' -d '{"queryParam":"cleaning","start":"0","rows":"20","searchType":["ALL"],"facetSelection":["SC:catalogs"],"userRoles":[""]}'
here is the equivalent send string created using the script which is not working:
POST /globalSearch/basicSearch HTTP/1.1\r\ncontent-type: application/json\r\nhost: host.domain.com\r\n\r\n{\“queryParam\“:\“cleaning\“,\“start\“:\“0\“,\“rows\“:\“20\“,\“searchType\“:[\“ALL\“],\“facetSelection\“:[\“SC:catalogs\“],\“userRoles\“:[\“\”]}
Can anyone find out what the issue is?
- Eric_ChenEmployee
I wonder whether your web server is expecting a content-length. Try
POST /globalSearch/basicSearch HTTP/1.1\r\ncontent-type: application/json\r\nhost: host.domain.com\r\nContent-Length: 120\r\n\r\n{\“queryParam\“:\“cleaning\“,\“start\“:\“0\“,\“rows\“:\“20\“,\“searchType\“:[\“ALL\“],\“facetSelection\“:[\“SC:catalogs\“],\“userRoles\“:[\“\”]}
- scyonix_360392Nimbostratus
no luck, does the braces need to be escaped?
- Eric_ChenEmployee
In your curl example above was it http or https? Similar question about whether your monitor was configured to match the same protocol.
- scyonix_360392Nimbostratus
Curl is http and the protocol monitor is also http
- Eric_ChenEmployee
Weird. It looks fine. tcpdump could verify whether any differences. Sending to the same port?
- Eric_ChenEmployee
Also. What is the response size?