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_Arroyo
Cirrus
Eric,
I just tried your script on v11.4.1 and it worked perfectly. Thanks!!!
- Buddy_Edwards_1
Nimbostratus
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_Chen
Employee
Awesome! Thank you for sharing.
- scyonix_360392
Nimbostratus
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_Chen
Employee
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_360392
Nimbostratus
no luck, does the braces need to be escaped?
- Eric_Chen
Employee
In your curl example above was it http or https? Similar question about whether your monitor was configured to match the same protocol.
- scyonix_360392
Nimbostratus
Curl is http and the protocol monitor is also http
- Eric_Chen
Employee
Weird. It looks fine. tcpdump could verify whether any differences. Sending to the same port?
- Eric_Chen
Employee
Also. What is the response size?