mirror of
https://github.com/curlconverter/curlconverter.git
synced 2022-05-22 02:35:29 +03:00
Python generator: Properly quote/escape all data
This commit is contained in:
@@ -4,9 +4,9 @@ headers = {
|
||||
'Authorization': 'Bearer ACCESS_TOKEN',
|
||||
}
|
||||
|
||||
files = {
|
||||
'attributes': '{"name":"tigers.jpeg", "parent":{"id":"11446498"}}',
|
||||
'file': open('myfile.jpg', 'rb')
|
||||
}
|
||||
files = [
|
||||
('attributes', '{"name":"tigers.jpeg", "parent":{"id":"11446498"}}'),
|
||||
('file', open('myfile.jpg', 'rb')),
|
||||
]
|
||||
|
||||
requests.post('https://upload.box.com/api/2.0/files/content', headers=headers, files=files)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'grant_type': 'client_credentials'
|
||||
}
|
||||
data = [
|
||||
('grant_type', 'client_credentials'),
|
||||
]
|
||||
|
||||
requests.post('http://localhost/api/oauth/token/', data=data, auth=('foo', 'bar'))
|
||||
|
||||
@@ -44,7 +44,7 @@ params = (
|
||||
('AC', '1'),
|
||||
)
|
||||
|
||||
data = '{"__type":"CreateItemJsonRequest:#Exchange","Header":{"__type":"JsonRequestHeaders:#Exchange","RequestServerVersion":"Exchange2013","TimeZoneContext":{"__type":"TimeZoneContext:#Exchange","TimeZoneDefinition":{"__type":"TimeZoneDefinitionType:#Exchange","Id":"France Standard Time"}}},"Body":{"__type":"CreateItemRequest:#Exchange","Items":[{"__type":"Message:#Exchange","Subject":"API","Body":{"__type":"BodyContentType:#Exchange","BodyType":"HTML","Value":"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><style type=\"text/css\" style=\"display:none\"><!-- p { margin-top: 0px; margin-bottom: 0px; }--></style></head><body dir=\"ltr\" style=\"font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;\"><p>API Test for NickC<br></p></body></html>"},"Importance":"Normal","From":null,"ToRecipients":[{"Name":"George LUCAS","EmailAddress":"George.LUCAS@nih.mail.edu.fr","RoutingType":"SMTP","MailboxType":"Mailbox","OriginalDisplayName":"George.LUCAS@nih.mail.edu.fr","SipUri":" "}],"CcRecipients":[],"BccRecipients":[],"Sensitivity":"Normal","IsDeliveryReceiptRequested":false,"IsReadReceiptRequested":false}],"ClientSupportsIrm":true,"OutboundCharset":"AutoDetect","MessageDisposition":"SendAndSaveCopy","ComposeOperation":"newMail"}}'
|
||||
data = '{"__type":"CreateItemJsonRequest:#Exchange","Header":{"__type":"JsonRequestHeaders:#Exchange","RequestServerVersion":"Exchange2013","TimeZoneContext":{"__type":"TimeZoneContext:#Exchange","TimeZoneDefinition":{"__type":"TimeZoneDefinitionType:#Exchange","Id":"France Standard Time"}}},"Body":{"__type":"CreateItemRequest:#Exchange","Items":[{"__type":"Message:#Exchange","Subject":"API","Body":{"__type":"BodyContentType:#Exchange","BodyType":"HTML","Value":"<html><head><meta http-equiv=\\"Content-Type\\" content=\\"text/html; charset=UTF-8\\"><style type=\\"text/css\\" style=\\"display:none\\"><!-- p { margin-top: 0px; margin-bottom: 0px; }--></style></head><body dir=\\"ltr\\" style=\\"font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;\\"><p>API Test for NickC<br></p></body></html>"},"Importance":"Normal","From":null,"ToRecipients":[{"Name":"George LUCAS","EmailAddress":"George.LUCAS@nih.mail.edu.fr","RoutingType":"SMTP","MailboxType":"Mailbox","OriginalDisplayName":"George.LUCAS@nih.mail.edu.fr","SipUri":" "}],"CcRecipients":[],"BccRecipients":[],"Sensitivity":"Normal","IsDeliveryReceiptRequested":false,"IsReadReceiptRequested":false}],"ClientSupportsIrm":true,"OutboundCharset":"AutoDetect","MessageDisposition":"SendAndSaveCopy","ComposeOperation":"newMail"}}'
|
||||
|
||||
requests.post('https://localhost/api/service.svc', headers=headers, params=params, cookies=cookies, data=data)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'foo': '\"bar\"'
|
||||
}
|
||||
data = [
|
||||
('foo', '\\"bar\\"'),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'foo': '\\\'bar\\\''
|
||||
}
|
||||
data = [
|
||||
('foo', '\\\'bar\\\''),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
7
fixtures/python_output/post_quotes_inside_data.py
Normal file
7
fixtures/python_output/post_quotes_inside_data.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = [
|
||||
('field', 'don\'t you like quotes'),
|
||||
]
|
||||
|
||||
requests.post('google.com', data=data)
|
||||
@@ -3,7 +3,7 @@ import requests
|
||||
data = [
|
||||
('foo', 'bar'),
|
||||
('foo', ''),
|
||||
('foo', 'barbar')
|
||||
('foo', 'barbar'),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'foo': '"bar"'
|
||||
}
|
||||
data = [
|
||||
('foo', '"bar"'),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'foo': '"bar"'
|
||||
}
|
||||
data = [
|
||||
('foo', '"bar"'),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'foo': '\'bar\''
|
||||
}
|
||||
data = [
|
||||
('foo', '\'bar\''),
|
||||
]
|
||||
|
||||
requests.post('http://example.com/', data=data)
|
||||
|
||||
@@ -12,9 +12,9 @@ headers = {
|
||||
'Connection': 'keep-alive',
|
||||
}
|
||||
|
||||
data = {
|
||||
'msg1': 'wow',
|
||||
'msg2': 'such'
|
||||
}
|
||||
data = [
|
||||
('msg1', 'wow'),
|
||||
('msg2', 'such'),
|
||||
]
|
||||
|
||||
requests.post('http://fiddle.jshell.net/echo/html/', headers=headers, data=data)
|
||||
|
||||
@@ -11,28 +11,28 @@ headers = {
|
||||
'Connection': 'keep-alive',
|
||||
}
|
||||
|
||||
data = {
|
||||
'CultureId': '1',
|
||||
'ApplicationId': '1',
|
||||
'RecordsPerPage': '200',
|
||||
'MaximumResults': '200',
|
||||
'PropertyTypeId': '300',
|
||||
'TransactionTypeId': '2',
|
||||
'StoreyRange': '0-0',
|
||||
'BuildingTypeId': '1',
|
||||
'BedRange': '0-0',
|
||||
'BathRange': '0-0',
|
||||
'LongitudeMin': '-79.3676805496215',
|
||||
'LongitudeMax': '-79.27300930023185',
|
||||
'LatitudeMin': '43.660358732823845',
|
||||
'LatitudeMax': '43.692390574029936',
|
||||
'SortOrder': 'A',
|
||||
'SortBy': '1',
|
||||
'viewState': 'm',
|
||||
'Longitude': '-79.4107246398925',
|
||||
'Latitude': '43.6552047278685',
|
||||
'ZoomLevel': '13',
|
||||
'CurrentPage': '1'
|
||||
}
|
||||
data = [
|
||||
('CultureId', '1'),
|
||||
('ApplicationId', '1'),
|
||||
('RecordsPerPage', '200'),
|
||||
('MaximumResults', '200'),
|
||||
('PropertyTypeId', '300'),
|
||||
('TransactionTypeId', '2'),
|
||||
('StoreyRange', '0-0'),
|
||||
('BuildingTypeId', '1'),
|
||||
('BedRange', '0-0'),
|
||||
('BathRange', '0-0'),
|
||||
('LongitudeMin', '-79.3676805496215'),
|
||||
('LongitudeMax', '-79.27300930023185'),
|
||||
('LatitudeMin', '43.660358732823845'),
|
||||
('LatitudeMax', '43.692390574029936'),
|
||||
('SortOrder', 'A'),
|
||||
('SortBy', '1'),
|
||||
('viewState', 'm'),
|
||||
('Longitude', '-79.4107246398925'),
|
||||
('Latitude', '43.6552047278685'),
|
||||
('ZoomLevel', '13'),
|
||||
('CurrentPage', '1'),
|
||||
]
|
||||
|
||||
requests.post('http://www.realtor.ca/api/Listing.svc/PropertySearch_Post', headers=headers, data=data)
|
||||
|
||||
@@ -4,22 +4,110 @@ var querystring = require('querystring')
|
||||
|
||||
require('string.prototype.startswith')
|
||||
|
||||
function pythonReprString (value) {
|
||||
function repr (value) {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
if (!value) {
|
||||
return "''"
|
||||
} else {
|
||||
return "'" + value.replace('\\', '\\\\').replace("'", "\\'") + "'"
|
||||
return "'" + jsesc(value, { quotes: 'single' }) + "'"
|
||||
}
|
||||
}
|
||||
|
||||
function getQueryDict (request) {
|
||||
var queryDict = 'params = (\n'
|
||||
for (var paramName in request.query) {
|
||||
var rawValue = request.query[paramName]
|
||||
var paramValue
|
||||
if (Array.isArray(rawValue)) {
|
||||
paramValue = rawValue.map(repr).join(', ')
|
||||
} else {
|
||||
paramValue = repr(rawValue)
|
||||
}
|
||||
queryDict += ' (' + repr(paramName) + ', ' + paramValue + '),\n'
|
||||
}
|
||||
queryDict += ')\n'
|
||||
return queryDict
|
||||
}
|
||||
|
||||
function getDataString (request) {
|
||||
if (request.data.startsWith('@')) {
|
||||
var filePath = request.data.slice(1)
|
||||
if (request.isDataBinary) {
|
||||
return 'data = open(\'' + filePath + '\', \'rb\').read()'
|
||||
} else {
|
||||
return 'data = open(\'' + filePath + '\')'
|
||||
}
|
||||
}
|
||||
|
||||
var parsedQueryString = querystring.parse(request.data)
|
||||
var keyCount = Object.keys(parsedQueryString).length
|
||||
var singleKeyOnly = keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]]
|
||||
var singularData = request.isDataBinary || singleKeyOnly
|
||||
if (singularData) {
|
||||
return 'data = ' + repr(request.data) + '\n'
|
||||
} else {
|
||||
return getMultipleDataString(request, parsedQueryString)
|
||||
}
|
||||
}
|
||||
|
||||
function getMultipleDataString (request, parsedQueryString) {
|
||||
var repeatedKey = false
|
||||
for (var key in parsedQueryString) {
|
||||
var value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
repeatedKey = true
|
||||
}
|
||||
}
|
||||
|
||||
var dataString
|
||||
if (repeatedKey) {
|
||||
dataString = 'data = [\n'
|
||||
for (key in parsedQueryString) {
|
||||
value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
dataString += ' (' + repr(key) + ', ' + repr(value[i]) + '),\n'
|
||||
}
|
||||
} else {
|
||||
dataString += ' (' + repr(key) + ', ' + repr(value) + '),\n'
|
||||
}
|
||||
}
|
||||
dataString += ']\n'
|
||||
} else {
|
||||
dataString = 'data = [\n'
|
||||
for (key in parsedQueryString) {
|
||||
value = parsedQueryString[key]
|
||||
dataString += ' (' + repr(key) + ', ' + repr(value) + '),\n'
|
||||
}
|
||||
dataString += ']\n'
|
||||
}
|
||||
|
||||
return dataString
|
||||
}
|
||||
|
||||
function getFilesString (request) {
|
||||
// http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
|
||||
var filesString = 'files = [\n'
|
||||
for (var multipartKey in request.multipartUploads) {
|
||||
var multipartValue = request.multipartUploads[multipartKey]
|
||||
if (multipartValue.startsWith('@')) {
|
||||
filesString += ' (' + repr(multipartKey) + ', open(' + repr(multipartValue.slice(1)) + ", 'rb')),\n"
|
||||
} else {
|
||||
filesString += ' (' + repr(multipartKey) + ', ' + repr(multipartValue) + '),\n'
|
||||
}
|
||||
}
|
||||
filesString += ']\n'
|
||||
|
||||
return filesString
|
||||
}
|
||||
|
||||
var toPython = function (curlCommand) {
|
||||
var request = util.parseCurlCommand(curlCommand)
|
||||
var cookieDict
|
||||
if (request.cookies) {
|
||||
cookieDict = 'cookies = {\n'
|
||||
for (var cookieName in request.cookies) {
|
||||
cookieDict += " '" + cookieName + "': '" + request.cookies[cookieName] + "',\n"
|
||||
cookieDict += ' ' + repr(cookieName) + ': ' + repr(request.cookies[cookieName]) + ',\n'
|
||||
}
|
||||
cookieDict += '}\n'
|
||||
}
|
||||
@@ -27,114 +115,22 @@ var toPython = function (curlCommand) {
|
||||
if (request.headers) {
|
||||
headerDict = 'headers = {\n'
|
||||
for (var headerName in request.headers) {
|
||||
headerDict += " '" + headerName + "': '" + request.headers[headerName] + "',\n"
|
||||
headerDict += ' ' + repr(headerName) + ': ' + repr(request.headers[headerName]) + ',\n'
|
||||
}
|
||||
headerDict += '}\n'
|
||||
}
|
||||
|
||||
var queryDict
|
||||
if (request.query) {
|
||||
queryDict = 'params = (\n'
|
||||
for (var paramName in request.query) {
|
||||
var rawValue = request.query[paramName]
|
||||
var paramValue
|
||||
if (Array.isArray(rawValue)) {
|
||||
paramValue = rawValue.map(pythonReprString).join(', ')
|
||||
} else {
|
||||
paramValue = pythonReprString(rawValue)
|
||||
}
|
||||
queryDict += ' (' + pythonReprString(paramName) + ', ' + paramValue + '),\n'
|
||||
}
|
||||
queryDict += ')\n'
|
||||
queryDict = getQueryDict(request)
|
||||
}
|
||||
|
||||
var dataString
|
||||
var filesString
|
||||
if (request.data) {
|
||||
if (request.data.startsWith('@')) {
|
||||
var filePath = request.data.slice(1)
|
||||
if (request.isDataBinary) {
|
||||
dataString = 'data = open(\'' + filePath + '\', \'rb\').read()'
|
||||
} else {
|
||||
dataString = 'data = open(\'' + filePath + '\')'
|
||||
}
|
||||
} else {
|
||||
var escapedData = request.data.replace(/'/g, "\\'")
|
||||
if (escapedData.indexOf("'") > -1) {
|
||||
escapedData = jsesc(request.data)
|
||||
}
|
||||
var parsedQueryString = querystring.parse(escapedData)
|
||||
var keyCount = Object.keys(parsedQueryString).length
|
||||
if (request.isDataBinary) {
|
||||
dataString = "data = '" + request.data + "'\n"
|
||||
} else if (keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]]) {
|
||||
dataString = "data = '" + request.data + "'\n"
|
||||
} else {
|
||||
var dataIndex = 0
|
||||
var repeatedKey = false
|
||||
var valueCount = 0
|
||||
for (var key in parsedQueryString) {
|
||||
var value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
repeatedKey = true
|
||||
valueCount += value.length
|
||||
} else {
|
||||
valueCount++
|
||||
}
|
||||
}
|
||||
if (repeatedKey) {
|
||||
dataString = 'data = [\n'
|
||||
for (key in parsedQueryString) {
|
||||
value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
dataString += " ('" + key + "', '" + value[i] + "')"
|
||||
if (dataIndex < valueCount - 1) {
|
||||
dataString += ',\n'
|
||||
}
|
||||
dataIndex++
|
||||
}
|
||||
} else {
|
||||
dataString += " ('" + key + "', '" + value + "')"
|
||||
if (dataIndex < keyCount - 1) {
|
||||
dataString += ',\n'
|
||||
}
|
||||
dataIndex++
|
||||
}
|
||||
}
|
||||
dataString += '\n]\n'
|
||||
} else {
|
||||
dataString = 'data = {\n'
|
||||
for (key in parsedQueryString) {
|
||||
value = parsedQueryString[key]
|
||||
dataString += " '" + key + "': '" + value + "'"
|
||||
if (dataIndex < keyCount - 1) {
|
||||
dataString += ',\n'
|
||||
}
|
||||
dataIndex++
|
||||
}
|
||||
dataString += '\n}\n'
|
||||
}
|
||||
}
|
||||
}
|
||||
dataString = getDataString(request)
|
||||
} else if (request.multipartUploads) {
|
||||
// http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
|
||||
filesString = 'files = {\n'
|
||||
var filesIndex = 0
|
||||
var filesCount = Object.keys(request.multipartUploads).length
|
||||
for (var multipartKey in request.multipartUploads) {
|
||||
var multipartValue = request.multipartUploads[multipartKey]
|
||||
if (multipartValue.startsWith('@')) {
|
||||
filesString += " '" + multipartKey + "': open('" + multipartValue.slice(1) + "', 'rb')"
|
||||
} else {
|
||||
filesString += " '" + multipartKey + "': '" + multipartValue + "'"
|
||||
}
|
||||
if (filesIndex < filesCount - 1) {
|
||||
filesString += ',\n'
|
||||
}
|
||||
filesIndex++
|
||||
}
|
||||
filesString += '\n}\n'
|
||||
filesString = getFilesString(request)
|
||||
}
|
||||
|
||||
var requestLineWithUrlParams = 'requests.' + request.method + '(\'' + request.urlWithoutQuery + '\''
|
||||
@@ -162,7 +158,7 @@ var toPython = function (curlCommand) {
|
||||
var splitAuth = request.auth.split(':')
|
||||
var user = splitAuth[0] || ''
|
||||
var password = splitAuth[1] || ''
|
||||
requestLineBody += ", auth=('" + user + "', '" + password + "')"
|
||||
requestLineBody += ', auth=(' + repr(user) + ', ' + repr(password) + ')'
|
||||
}
|
||||
requestLineBody += ')'
|
||||
|
||||
|
||||
6
util.js
6
util.js
@@ -31,8 +31,8 @@ var parseCurlCommand = function (curlCommand) {
|
||||
var cookieString
|
||||
var cookies
|
||||
var url = parsedArguments._[1]
|
||||
// if url argument wasn't where we expected it, check other places
|
||||
// it shows up
|
||||
// if url argument wasn't where we expected it, check other places
|
||||
// it shows up
|
||||
if (!url && parsedArguments['L']) {
|
||||
url = parsedArguments['L']
|
||||
}
|
||||
@@ -63,7 +63,7 @@ var parseCurlCommand = function (curlCommand) {
|
||||
parsedArguments.F = [parsedArguments.F]
|
||||
}
|
||||
parsedArguments.F.forEach(function (multipartArgument) {
|
||||
// input looks like key=value. value could be json or a file path prepended with an @
|
||||
// input looks like key=value. value could be json or a file path prepended with an @
|
||||
var splitArguments = multipartArgument.split('=', 2)
|
||||
var key = splitArguments[0]
|
||||
var value = splitArguments[1]
|
||||
|
||||
Reference in New Issue
Block a user