mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-22 12:15:38 +00:00
Merge pull request #3178 from pietrygamat/bugfix/571
fix: unable to set request bodies with colon characters in their names
This commit is contained in:
@@ -56,7 +56,13 @@ const grammar = ohm.grammar(`Bru {
|
||||
// Dictionary Blocks
|
||||
dictionary = st* "{" pairlist? tagend
|
||||
pairlist = optionalnl* pair (~tagend stnl* pair)* (~tagend space)*
|
||||
pair = st* key st* ":" st* value st*
|
||||
pair = st* (quoted_key | key) st* ":" st* value st*
|
||||
disable_char = "~"
|
||||
quote_char = "\\""
|
||||
esc_char = "\\\\"
|
||||
esc_quote_char = esc_char quote_char
|
||||
quoted_key_char = ~(quote_char | esc_quote_char | nl) any
|
||||
quoted_key = disable_char? quote_char (esc_quote_char | quoted_key_char)* quote_char
|
||||
key = keychar*
|
||||
value = list | multilinetextblock | valuechar*
|
||||
|
||||
@@ -301,6 +307,14 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
res[key.ast] = value.ast ? value.ast.trim() : '';
|
||||
return res;
|
||||
},
|
||||
esc_quote_char(_1, quote) {
|
||||
// unescape
|
||||
return quote.sourceString;
|
||||
},
|
||||
quoted_key(disabled, _1, chars, _2) {
|
||||
// unquote
|
||||
return (disabled? disabled.sourceString : "") + chars.ast.join("");
|
||||
},
|
||||
key(chars) {
|
||||
return chars.sourceString ? chars.sourceString.trim() : '';
|
||||
},
|
||||
@@ -364,6 +378,9 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
tagend(_1, _2) {
|
||||
return '';
|
||||
},
|
||||
_terminal(){
|
||||
return this.sourceString;
|
||||
},
|
||||
multilinetextblockdelimiter(_) {
|
||||
return '';
|
||||
},
|
||||
|
||||
@@ -4,6 +4,10 @@ const { indentString } = require('./utils');
|
||||
|
||||
const enabled = (items = [], key = "enabled") => items.filter((item) => item[key]);
|
||||
const disabled = (items = [], key = "enabled") => items.filter((item) => !item[key]);
|
||||
const quoteKey = (key) => {
|
||||
const quotableChars = [':', '"', '{', '}', ' '];
|
||||
return quotableChars.some(char => key.includes(char)) ? ('"' + key.replaceAll('"', '\\"') + '"') : key;
|
||||
}
|
||||
|
||||
// remove the last line if two new lines are found
|
||||
const stripLastLine = (text) => {
|
||||
@@ -121,7 +125,7 @@ const jsonToBru = (json) => {
|
||||
if (enabled(queryParams).length) {
|
||||
bru += `\n${indentString(
|
||||
enabled(queryParams)
|
||||
.map((item) => `${item.name}: ${item.value}`)
|
||||
.map((item) => `${quoteKey(item.name)}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
}
|
||||
@@ -129,7 +133,7 @@ const jsonToBru = (json) => {
|
||||
if (disabled(queryParams).length) {
|
||||
bru += `\n${indentString(
|
||||
disabled(queryParams)
|
||||
.map((item) => `~${item.name}: ${item.value}`)
|
||||
.map((item) => `~${quoteKey(item.name)}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
}
|
||||
@@ -151,7 +155,7 @@ const jsonToBru = (json) => {
|
||||
if (enabled(headers).length) {
|
||||
bru += `\n${indentString(
|
||||
enabled(headers)
|
||||
.map((item) => `${item.name}: ${item.value}`)
|
||||
.map((item) => `${quoteKey(item.name)}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
}
|
||||
@@ -159,7 +163,7 @@ const jsonToBru = (json) => {
|
||||
if (disabled(headers).length) {
|
||||
bru += `\n${indentString(
|
||||
disabled(headers)
|
||||
.map((item) => `~${item.name}: ${item.value}`)
|
||||
.map((item) => `~${quoteKey(item.name)}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
}
|
||||
@@ -246,7 +250,7 @@ ${indentString(`domain: ${auth?.ntlm?.domain || ''}`)}
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
if (auth && auth.oauth2) {
|
||||
switch (auth?.oauth2?.grantType) {
|
||||
@@ -496,14 +500,14 @@ ${indentString(body.sparql)}
|
||||
|
||||
if (enabled(body.formUrlEncoded).length) {
|
||||
const enabledValues = enabled(body.formUrlEncoded)
|
||||
.map((item) => `${item.name}: ${getValueString(item.value)}`)
|
||||
.map((item) => `${quoteKey(item.name)}: ${getValueString(item.value)}`)
|
||||
.join('\n');
|
||||
bru += `${indentString(enabledValues)}\n`;
|
||||
}
|
||||
|
||||
if (disabled(body.formUrlEncoded).length) {
|
||||
const disabledValues = disabled(body.formUrlEncoded)
|
||||
.map((item) => `~${item.name}: ${getValueString(item.value)}`)
|
||||
.map((item) => `~${quoteKey(item.name)}: ${getValueString(item.value)}`)
|
||||
.join('\n');
|
||||
bru += `${indentString(disabledValues)}\n`;
|
||||
}
|
||||
@@ -524,7 +528,7 @@ ${indentString(body.sparql)}
|
||||
item.contentType && item.contentType !== '' ? ' @contentType(' + item.contentType + ')' : '';
|
||||
|
||||
if (item.type === 'text') {
|
||||
return `${enabled}${item.name}: ${getValueString(item.value)}${contentType}`;
|
||||
return `${enabled}${quoteKey(item.name)}: ${getValueString(item.value)}${contentType}`;
|
||||
}
|
||||
|
||||
if (item.type === 'file') {
|
||||
@@ -532,7 +536,7 @@ ${indentString(body.sparql)}
|
||||
const filestr = filepaths.join('|');
|
||||
|
||||
const value = `@file(${filestr})`;
|
||||
return `${enabled}${item.name}: ${value}${contentType}`;
|
||||
return `${enabled}${quoteKey(item.name)}: ${value}${contentType}`;
|
||||
}
|
||||
})
|
||||
.join('\n')
|
||||
|
||||
@@ -81,6 +81,25 @@ headers {
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should parse single header with empty key', () => {
|
||||
const input = `
|
||||
headers {
|
||||
: world
|
||||
}`;
|
||||
|
||||
const output = parser(input);
|
||||
const expected = {
|
||||
headers: [
|
||||
{
|
||||
name: '',
|
||||
value: 'world',
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
};
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should parse multi headers', () => {
|
||||
const input = `
|
||||
headers {
|
||||
|
||||
@@ -17,6 +17,11 @@ get {
|
||||
params:query {
|
||||
apiKey: secret
|
||||
numbers: 998877665
|
||||
"key with spaces": is allowed
|
||||
"colon:parameter": is allowed
|
||||
"nested escaped \"quote\"": is allowed
|
||||
"{braces}": is allowed
|
||||
~"disabled:colon:parameter": is allowed
|
||||
~message: hello
|
||||
}
|
||||
|
||||
@@ -27,6 +32,11 @@ params:path {
|
||||
headers {
|
||||
content-type: application/json
|
||||
Authorization: Bearer 123
|
||||
"key with spaces": is allowed
|
||||
"colon:header": is allowed
|
||||
"{braces}": is allowed
|
||||
"nested escaped \"quote\"": is allowed
|
||||
~"disabled:colon:header": is allowed
|
||||
~transaction-id: {{transactionId}}
|
||||
}
|
||||
|
||||
@@ -104,13 +114,23 @@ body:sparql {
|
||||
body:form-urlencoded {
|
||||
apikey: secret
|
||||
numbers: +91998877665
|
||||
"key with spaces": is allowed
|
||||
"colon:parameter": is allowed
|
||||
"nested escaped \"quote\"": is allowed
|
||||
"{braces}": is allowed
|
||||
~message: hello
|
||||
~"disabled colon:parameter": is allowed
|
||||
}
|
||||
|
||||
body:multipart-form {
|
||||
apikey: secret
|
||||
numbers: +91998877665
|
||||
"key with spaces": is allowed
|
||||
"colon:part": is allowed
|
||||
"nested escaped \"quote\"": is allowed
|
||||
"{braces}": is allowed
|
||||
~message: hello
|
||||
~"disabled colon:part": is allowed
|
||||
}
|
||||
|
||||
body:file {
|
||||
|
||||
115
packages/bruno-lang/v2/tests/fixtures/request.json
vendored
115
packages/bruno-lang/v2/tests/fixtures/request.json
vendored
@@ -24,6 +24,36 @@
|
||||
"type": "query",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "key with spaces",
|
||||
"value": "is allowed",
|
||||
"type": "query",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name" : "colon:parameter",
|
||||
"value" : "is allowed",
|
||||
"type": "query",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name" : "nested escaped \"quote\"",
|
||||
"value" : "is allowed",
|
||||
"type": "query",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "{braces}",
|
||||
"value": "is allowed",
|
||||
"type": "query",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name" : "disabled:colon:parameter",
|
||||
"value" : "is allowed",
|
||||
"type": "query",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"value": "hello",
|
||||
@@ -48,6 +78,31 @@
|
||||
"value": "Bearer 123",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "key with spaces",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "colon:header",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "{braces}",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "nested escaped \"quote\"",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "disabled:colon:header",
|
||||
"value": "is allowed",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "transaction-id",
|
||||
"value": "{{transactionId}}",
|
||||
@@ -118,10 +173,35 @@
|
||||
"value": "+91998877665",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "key with spaces",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "colon:parameter",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "nested escaped \"quote\"",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "{braces}",
|
||||
"value": "is allowed",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"value": "hello",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "disabled colon:parameter",
|
||||
"value": "is allowed",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"multipartForm": [
|
||||
@@ -139,12 +219,47 @@
|
||||
"enabled": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "key with spaces",
|
||||
"value": "is allowed",
|
||||
"enabled": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "colon:part",
|
||||
"value": "is allowed",
|
||||
"enabled": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "nested escaped \"quote\"",
|
||||
"value": "is allowed",
|
||||
"enabled": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "{braces}",
|
||||
"value": "is allowed",
|
||||
"enabled": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "message",
|
||||
"value": "hello",
|
||||
"enabled": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"contentType": "",
|
||||
"name": "disabled colon:part",
|
||||
"value": "is allowed",
|
||||
"enabled": false,
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"file" : [
|
||||
|
||||
Reference in New Issue
Block a user