Kong / httpsnippet

HTTP Request snippet generator for many languages & libraries
Apache License 2.0
1.15k stars 227 forks source link

Please use double quotes in the generated CURL command for windows support #115

Open JaneX8 opened 6 years ago

JaneX8 commented 6 years ago

The generated curl command used single quotes but that doesn't work for Windows users that have shell. Linux supports both single and double quotes. Changing --header='' to --header="" will enable windows users with curl to use it too :).

darrenjennings commented 5 years ago

@ElleshaHackett seems like a good idea. @ahmadnassri do you have any history/justification on the single quotes?

darrenjennings commented 5 years ago

Related: #106, https://github.com/Kong/httpsnippet/pull/29

jgiovaresco commented 4 years ago

I plan to work on this issue, but I've found something that borrows me: https://github.com/Kong/httpsnippet/blob/master/src/helpers/shell.js#L6-L9

/**

This utility function is used for all shell targets. I'm wondering if

Any thoughts? @develohpanda @darrenjennings

develohpanda commented 4 years ago

Hmm, kind of on the fence about this one. Looks like there has been a conscious decision to use strong quoting (single quotes), instead of weak quoting (double quotes), as per #29.

I would be inclined to make the minimum change > only updating the curl target. But, it seems this is an issue with shell targets instead of curl specifically. I'm guessing strong quoting doesn't work at all on Windows? Strong quoting does feel like the safer option, reading the docs here.

Is there something smarter we can do, for example detecting the OS and deciding the type of quote to apply automatically, and allow that to be overridden with a user provided option? This way shell targets would work on Windows automatically, have no impact to Linux/macOS and current behavior, but allow users to override it.

jgiovaresco commented 4 years ago

Deciding the type of quote automatically is a great idea.

This should resolve the issue when using the httpsnippet cli but what about when the lib is used in a web-based environment (I was thinking about apiembeded)

To manage both uses (cli + lib), I would suggest adding an option in convert named platform. We could use the values windows, macos, linux

We would be able to detect the platform in bin/httpsnippet and set the option automatically. For web-based use, we would let the user set the option if needed.

develohpanda commented 4 years ago

That sounds like a reasonable approach.

What is your opinion on introducing a quotes option with the values single, double, instead of platform? It's a little more explicit, and can automatically be set to the correct value by the CLI bin/httpsnippet.

dimitropoulos commented 2 years ago

@pimterry are you able to comment on what to do here?

pimterry commented 2 years ago

Ok, so just to summarize the above:

I've done a bunch of tests on a Windows 11 cmd shell vs bash on Linux (collapsed here because there's lots) * No quotes, no spaces: `curl -Htest:value example.com` * Both: Sends the correct `test: value` header * Unquoted spaces: `curl -Htest: value example.com` * Both: Sends a request to 'value' (which fails) and a request to example.com, with no 'test' header anywhere (I guess because an empty value was provided?) * Double-quoted, no spaces: `curl -H"test:value" example.com` * Both: Sends the correct header * Double-quoted spaces: `curl -H"test: value" example.com` * Both: Sends the correct header * Single-quoted spaces: `curl -H'test: value' example.com` * Windows: Sends the request, but with no 'test' header, and no request to `value`? Very odd * Linux: works correctly * Single-quoted, no spaces: `curl -H'test:value' example.com` * Windows: Sends the request with a `'test: value'` header (i.e. incorrectly puts the single quote at the start of the header name and the end of the header value) * Linux: works correctly * Double-quoted, containing escaped quotes: `curl -H"test: header with \"quoted value\"" example.com` * Both: Sends the correct header, with the quotes sent literally without the slashes. * Double-quoted, containing real variables: `curl -H"test: %PATH%" example.com` ($PATH for linux) * Both: Sends a header containing the whole value of the PATH env var * Double-quoted, not a real variable: `curl -H"test: value-%SOMETHINGELSE%" example.com` * Windows: Sends a header literally containing `value-%SOMETHINGELSE%`. * Linux: Sends a header containing `value-` (i.e. `$SOMETHINGELSE` for unrecognized variables disappears) * Double-quoted, slash-escaped variable: `curl -H"test: \%PATH\%" example.com` (`\$PATH` for linux) * Windows: Sends a header literally containing `\%PATH\%` (i.e. including the slashes, so incorrect) * Linux: Sends the correct `test: $PATH` header * Double-quoted, ^-escaped variable: `curl -H"test: ^%PATH^%" example.com` * Windows: Same thing - sends a header literally containing `^%PATH^%`. Weird, because this _does_ work correctly with `echo ^%PATH^%` * Linux: Sends `test: ^` + the real contents of the $PATH variable (as expected) * Double-quoted, selection of unescaped special characters: ``curl -H"test: $!`" example.com`` * Windows: Sent correctly, all characters preserved * Linux: `$` and `` ` `` both cause errors that make commands totally unrunnable. `!` causes errors for Zsh only on my machine (I think this is a bash feature that's optionally enabled though?) * Double-quoted, escaping various special characters: ``curl -H"test: \$\!\`" example.com`` * Windows: All sent with the extra slash, i.e. the resulting header is `` test: \$\!\` ``. * Linux: All sent correctly, without the escaping slash

So:

That means there is no combination of quote + escaping rules that will ever produce snippets that work correctly everywhere.

I think that means a quotes option is problematic - for a big chunk of users (everybody on Windows) single quotes will always be broken, and that probably won't be obvious to them initially, and for double quotes the escaping rules are very different for the two platforms in complicated ways that will cause weird issues.

A platform option would make this possible OTOH. I think this would be a bit better as shell though, supporting bash & cmd values, because it's totally possible to run bash on Windows (Git on Windows installs a Bash terminal by default, so it's very common), and because that would leave space for supporting shells that have their own unique issues in future.

With that, we could use single quotes in bash (i.e. strong quotes, so no need to escape anything except other single quotes, super easy) and double quotes in cmd. The only leftover case is real %variable% names in snippets, which are always inescapably (!!!) replaced with the real variable value, and AFAICT there's nothing we can do about that. If we ever find a solution it'd be easy to add it though without breaking anything else

A shell option wouldn't help bash users who want double quotes for easier variable usage (https://github.com/Kong/httpsnippet/issues/106). That seems like a separate problem tbh - we could add an additional quotes option for that, to switch quote types and add escaping logic for bash special characters (throwing an error if you ever try to use cmd + single-quotes). But I think that's more like a nice-to-have, I'd ignore it for now.

How does that sound?