mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-12-08 00:00:58 -05:00
several improvs, added pre-baked commands
This commit is contained in:
parent
07dc8726d4
commit
d239e40b72
@ -1,3 +1,7 @@
|
|||||||
|
.buttons {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.75em 1.25em;
|
padding: 0.75em 1.25em;
|
||||||
@ -17,6 +21,12 @@
|
|||||||
svg {
|
svg {
|
||||||
vertical-align: -1px;
|
vertical-align: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.btn-small {
|
||||||
|
background-color: green;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
padding: 0 0.4em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
|
|||||||
@ -57,10 +57,11 @@
|
|||||||
|
|
||||||
code, #curl-command {
|
code, #curl-command {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px;
|
padding: 0 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
color: white;
|
color: white;
|
||||||
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
#curl-command:before {
|
#curl-command:before {
|
||||||
@ -69,19 +70,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#curl-command input,
|
#curl-command input,
|
||||||
#curl-command textarea {
|
#curl-command pre {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#curl-command input {
|
||||||
|
padding: 10px;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#curl-command textarea {
|
#curl-command pre {
|
||||||
|
width: 100%;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
rgba(0, 70, 0, 0.75), black 120%
|
||||||
|
);
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
font-family: monospace;
|
font-family: Inconsolata, monospace;
|
||||||
|
text-shadow: 0 0 5px #C8C8C8;
|
||||||
color: #87cefa;
|
color: #87cefa;
|
||||||
&.error {
|
&.error {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
&::selection {
|
||||||
|
background: #0080FF;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,9 +23,17 @@ layout: default
|
|||||||
</div>
|
</div>
|
||||||
<div class="code-preview">
|
<div class="code-preview">
|
||||||
<p><span class="text">Convert curl commands into httpx</span></p>
|
<p><span class="text">Convert curl commands into httpx</span></p>
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="btn btn-small" onclick="javascript: setexample('simple')">Simple</button>
|
||||||
|
<button class="btn btn-small" onclick="javascript: setexample('basicauth')">Basic Auth</button>
|
||||||
|
<button class="btn btn-small" onclick="javascript: setexample('json')">JSON</button>
|
||||||
|
<button class="btn btn-small" onclick="javascript: setexample('complexjson')">Complex JSON</button>
|
||||||
|
<button class="btn btn-small" onclick="javascript: setexample('formdata')">Form Data</button>
|
||||||
|
</div>
|
||||||
|
<label for="curl-command-input">"insert curl command here..."</label>
|
||||||
<div id="curl-command">
|
<div id="curl-command">
|
||||||
<input id="curl-command-input" type="text" placeholder="insert curl command here..."/>
|
<input id="curl-command-input" type="text" placeholder="curl http://..."/>
|
||||||
<textarea id="curl-command-output" rows=0 style="display:none"></textarea>
|
<pre id="curl-command-output" style="display:none"></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn" href="{{ '/posts/index.html' | prepend: site.baseurl }}">
|
<a class="btn" href="{{ '/posts/index.html' | prepend: site.baseurl }}">
|
||||||
|
|||||||
@ -22,6 +22,7 @@ def parse_options(command, options)
|
|||||||
# end
|
# end
|
||||||
opts.on("--basic") do # Use HTTP Basic Authentication
|
opts.on("--basic") do # Use HTTP Basic Authentication
|
||||||
options[:auth] = :basic_authentication
|
options[:auth] = :basic_authentication
|
||||||
|
options[:auth_method] = :basic_auth
|
||||||
end
|
end
|
||||||
opts.on("--cacert FILE") do |path| # CA certificate to verify peer against
|
opts.on("--cacert FILE") do |path| # CA certificate to verify peer against
|
||||||
options[:options][:ssl][:ca_file] = "OpenSSL::X509::Certificate.new(File.read(#{path.inspect}))"
|
options[:options][:ssl][:ca_file] = "OpenSSL::X509::Certificate.new(File.read(#{path.inspect}))"
|
||||||
@ -57,43 +58,62 @@ def parse_options(command, options)
|
|||||||
# opts.on("--crlf") # Convert LF to CRLF in upload
|
# opts.on("--crlf") # Convert LF to CRLF in upload
|
||||||
# opts.on("--crlfile FILE") # Get a CRL list in PEM format from the given file
|
# opts.on("--crlfile FILE") # Get a CRL list in PEM format from the given file
|
||||||
opts.on("-d", "--data DATA") do |data|
|
opts.on("-d", "--data DATA") do |data|
|
||||||
|
data = data.sub(/\A'(.*)'\z/, '\\1')
|
||||||
options[:verb] ||= :post
|
options[:verb] ||= :post
|
||||||
if data.start_with?("@")
|
if data.start_with?("@")
|
||||||
options[:body] = "File.open(#{data[1..-1].inspect})"
|
options[:body] = "File.open(#{data[1..-1].inspect})"
|
||||||
else
|
else
|
||||||
options[:form] ||= []
|
|
||||||
k, v = data.split("=")
|
k, v = data.split("=")
|
||||||
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v.inspect
|
if v
|
||||||
options[:form] << [k, v]
|
options[:form] ||= []
|
||||||
|
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
|
||||||
|
options[:form] << [k, v]
|
||||||
|
else
|
||||||
|
options[:body] = k
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end # HTTP POST data
|
end # HTTP POST data
|
||||||
opts.on("--data-ascii DATA") do |data|
|
opts.on("--data-ascii DATA") do |data|
|
||||||
|
data = data.sub(/\A'(.*)'\z/, '\\1')
|
||||||
options[:verb] ||= :post
|
options[:verb] ||= :post
|
||||||
if data.start_with?("@")
|
if data.start_with?("@")
|
||||||
options[:body] = "File.open(#{data[1..-1].inspect})"
|
options[:body] = "File.open(#{data[1..-1].inspect})"
|
||||||
else
|
else
|
||||||
options[:form] ||= []
|
|
||||||
k, v = data.split("=")
|
k, v = data.split("=")
|
||||||
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v.inspect
|
if v
|
||||||
options[:form] << [k, v]
|
options[:form] ||= []
|
||||||
|
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
|
||||||
|
options[:form] << [k, v]
|
||||||
|
else
|
||||||
|
options[:body] = k
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end # HTTP POST ASCII data
|
end # HTTP POST ASCII data
|
||||||
opts.on("--data-binary DATA") do |data|
|
opts.on("--data-binary DATA") do |data|
|
||||||
|
data = data.sub(/\A'(.*)'\z/, '\\1')
|
||||||
options[:verb] ||= :post
|
options[:verb] ||= :post
|
||||||
if data.start_with?("@")
|
if data.start_with?("@")
|
||||||
options[:body] = "File.open(#{data[1..-1].inspect})"
|
options[:body] = "File.open(#{data[1..-1].inspect})"
|
||||||
else
|
else
|
||||||
options[:form] ||= []
|
|
||||||
k, v = data.split("=")
|
k, v = data.split("=")
|
||||||
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v.inspect
|
if v
|
||||||
options[:form] << [k, v]
|
options[:form] ||= []
|
||||||
|
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
|
||||||
|
options[:form] << [k, v]
|
||||||
|
else
|
||||||
|
options[:body] = k
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end # HTTP POST binary data
|
end # HTTP POST binary data
|
||||||
opts.on("--data-raw DATA") do |data|
|
opts.on("--data-raw DATA") do |data|
|
||||||
options[:form] ||= []
|
options[:form] ||= []
|
||||||
k, v = data.split("=")
|
k, v = data.split("=")
|
||||||
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v.inspect
|
if v
|
||||||
options[:form] << [k, v]
|
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
|
||||||
|
options[:form] << [k, v]
|
||||||
|
else
|
||||||
|
options[:body] = k
|
||||||
|
end
|
||||||
end # HTTP POST data, '@' allowed
|
end # HTTP POST data, '@' allowed
|
||||||
opts.on("--data-urlencode DATA") do |data|
|
opts.on("--data-urlencode DATA") do |data|
|
||||||
options[:verb] ||= :post
|
options[:verb] ||= :post
|
||||||
@ -103,6 +123,7 @@ def parse_options(command, options)
|
|||||||
# opts.on("--delegation LEVEL") # GSS-API delegation permission
|
# opts.on("--delegation LEVEL") # GSS-API delegation permission
|
||||||
opts.on("--digest") do
|
opts.on("--digest") do
|
||||||
options[:auth] = :digest_authentication
|
options[:auth] = :digest_authentication
|
||||||
|
options[:auth_method] = :digest_auth
|
||||||
end # Use HTTP Digest Authentication
|
end # Use HTTP Digest Authentication
|
||||||
# opts.on("-q", "--disable") # Disable .curlrc
|
# opts.on("-q", "--disable") # Disable .curlrc
|
||||||
# opts.on("--disable-eprt") # Inhibit using EPRT or LPRT
|
# opts.on("--disable-eprt") # Inhibit using EPRT or LPRT
|
||||||
@ -164,8 +185,8 @@ def parse_options(command, options)
|
|||||||
options[:options][:debug_level] = 1
|
options[:options][:debug_level] = 1
|
||||||
end # Show document info only
|
end # Show document info only
|
||||||
opts.on("-H", "--header HEADER/@FILE") do |data|
|
opts.on("-H", "--header HEADER/@FILE") do |data|
|
||||||
k, v = data.split("/")
|
k, v = data[1..-2].split(/ *: */)
|
||||||
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v.inspect
|
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
|
||||||
|
|
||||||
options[:options][:headers][k] = v
|
options[:options][:headers][k] = v
|
||||||
end # Pass custom header(s) to server
|
end # Pass custom header(s) to server
|
||||||
@ -249,7 +270,10 @@ def parse_options(command, options)
|
|||||||
options[:copy_to] = path
|
options[:copy_to] = path
|
||||||
end # Write to file instead of stdout
|
end # Write to file instead of stdout
|
||||||
opts.on("--pass PHRASE") do |pass|
|
opts.on("--pass PHRASE") do |pass|
|
||||||
options[:auth] ||= :basic_authentication
|
if !options.key?(:auth)
|
||||||
|
options[:auth] = :basic_authentication
|
||||||
|
options[:auth_method] = :basic_auth
|
||||||
|
end
|
||||||
options[:password] = pass
|
options[:password] = pass
|
||||||
end# Pass phrase for the private key
|
end# Pass phrase for the private key
|
||||||
# opts.on("--path-as-is Do not squash .. sequences in URL path
|
# opts.on("--path-as-is Do not squash .. sequences in URL path
|
||||||
@ -414,9 +438,12 @@ def parse_options(command, options)
|
|||||||
options[:urls] << url
|
options[:urls] << url
|
||||||
end # URL to work with
|
end # URL to work with
|
||||||
opts.on("-B", "--use-ascii") # Use ASCII/text transfer
|
opts.on("-B", "--use-ascii") # Use ASCII/text transfer
|
||||||
opts.on("-u", "--user <user:password>") do |user_pass|
|
opts.on("-u <user:password>", "--user <user:password>") do |user_pass|
|
||||||
options[:auth] ||= :basic_authentication
|
if !options.key?(:auth)
|
||||||
user, pass = user_pass.split(":")
|
options[:auth] = :basic_authentication
|
||||||
|
options[:auth_method] = :basic_auth
|
||||||
|
end
|
||||||
|
user, pass = user_pass.sub(/\A"(.*)"\z/, '\\1').split(":")
|
||||||
options[:username] = user
|
options[:username] = user
|
||||||
options[:password] = pass
|
options[:password] = pass
|
||||||
end # Server user and password
|
end # Server user and password
|
||||||
@ -436,7 +463,6 @@ def to_ruby(urls, options)
|
|||||||
template = <<-HTTPX.slice(0..-2)
|
template = <<-HTTPX.slice(0..-2)
|
||||||
require "httpx"
|
require "httpx"
|
||||||
|
|
||||||
http = HTTPX
|
|
||||||
HTTPX
|
HTTPX
|
||||||
|
|
||||||
# load extra deps
|
# load extra deps
|
||||||
@ -444,47 +470,58 @@ http = HTTPX
|
|||||||
template.prepend("require \"#{lib}\"\n")
|
template.prepend("require \"#{lib}\"\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
# load plugins
|
|
||||||
options[:plugins].each do |plugin|
|
|
||||||
template += ".plugin(#{plugin.inspect}"
|
|
||||||
options[:plugin_options][plugin].each do |key, value|
|
|
||||||
template += ", #{key}: #{value.inspect}"
|
|
||||||
end
|
|
||||||
template += ")"
|
|
||||||
end
|
|
||||||
|
|
||||||
# handle auth
|
|
||||||
if (auth = options[:auth])
|
|
||||||
template += ".plugin(#{auth.inspect})." \
|
|
||||||
"#{auth}(#{options[:username].inspect}, " \
|
|
||||||
"#{options[:password].inspect})"
|
|
||||||
end
|
|
||||||
|
|
||||||
# handle general options
|
# handle general options
|
||||||
with_options = options[:options].map do |k, v|
|
with_options = options[:options].map do |k, v|
|
||||||
next if %i[body form json].include?(k)
|
next if %i[body form json].include?(k)
|
||||||
|
|
||||||
"#{k}: #{v.inspect}" unless v.respond_to?(:empty?) && v.empty?
|
"#{k.inspect} => #{v.inspect}" unless v.respond_to?(:empty?) && v.empty?
|
||||||
end.compact
|
end.compact
|
||||||
|
|
||||||
if not with_options.empty?
|
if (http_custom = !options[:plugins].empty? || options[:auth] || !with_options.empty?)
|
||||||
template += ".with(#{with_options.join(', ')})"
|
template += "\nhttp = HTTPX"
|
||||||
|
end
|
||||||
|
|
||||||
|
# load plugins
|
||||||
|
options[:plugins].each do |plugin|
|
||||||
|
template += ".plugin(:#{plugin}"
|
||||||
|
options[:plugin_options][plugin].each do |key, value|
|
||||||
|
template += ", #{key}: #{value.inspect}"
|
||||||
|
end
|
||||||
|
template += ")\n\t"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# handle auth
|
||||||
|
if (auth = options[:auth])
|
||||||
|
template += ".plugin(:#{auth})\n\t" \
|
||||||
|
".#{options.fetch(:auth_method, auth)}(#{options[:username].inspect}, " \
|
||||||
|
"#{options[:password].inspect})\n\t"
|
||||||
|
end
|
||||||
|
|
||||||
|
# handle general options
|
||||||
|
if !with_options.empty?
|
||||||
|
template += ".with(#{with_options.join(', ')})\n\t"
|
||||||
|
end
|
||||||
|
|
||||||
# send request
|
# send request
|
||||||
template += "\nresponse = http"
|
template += "\nresponse = "
|
||||||
|
template += http_custom ? "http" : "HTTPX"
|
||||||
template += ".#{options.fetch(:verb, :get)}("
|
template += ".#{options.fetch(:verb, :get)}("
|
||||||
template += (urls + options[:urls]).map(&:inspect).join(", ")
|
template += (urls + options[:urls]).map do |h|
|
||||||
|
h = h.sub(/\A"(.*)"\z/, '\\1')
|
||||||
|
(h.start_with?("http://") || h.start_with?("https://")) ?
|
||||||
|
h : "http://#{h}"
|
||||||
|
end.map(&:inspect).join(", ")
|
||||||
|
|
||||||
# send body
|
# send body
|
||||||
if options.key?(:body)
|
if options.key?(:body)
|
||||||
template += ", body: #{options[:body].inspect}"
|
template += ", body: #{options[:body]}"
|
||||||
end
|
end
|
||||||
if options.key?(:form)
|
if options.key?(:form)
|
||||||
template += ", form: {"
|
template += ", form: {"
|
||||||
template += options[:form].map do |k, v|
|
template += options[:form].map do |k, v|
|
||||||
"#{k}: #{v}"
|
"#{k.inspect} => #{v.inspect}"
|
||||||
end.join(", ")
|
end.join(", ")
|
||||||
template += "}"
|
template += "}"
|
||||||
end
|
end
|
||||||
@ -509,7 +546,7 @@ def to_httpx
|
|||||||
}
|
}
|
||||||
begin
|
begin
|
||||||
options = {}
|
options = {}
|
||||||
urls = parse_options(command.slice(5..-1).split(/ +/), options)
|
urls = parse_options(command.slice(5..-1).scan(/"[^"]+"|'[^']+'|\S+/), options)
|
||||||
result = to_ruby(urls, options)
|
result = to_ruby(urls, options)
|
||||||
rescue OptionParser::InvalidOption => error
|
rescue OptionParser::InvalidOption => error
|
||||||
result = error.message
|
result = error.message
|
||||||
@ -517,21 +554,47 @@ def to_httpx
|
|||||||
`output.classList.add("error")`
|
`output.classList.add("error")`
|
||||||
end
|
end
|
||||||
|
|
||||||
`console.log(#{result})`
|
|
||||||
%x{
|
%x{
|
||||||
output.value = #{result};
|
output.innerHTML = #{result};
|
||||||
output.rows = #{result.lines.size};
|
|
||||||
output.style.display = "block";
|
output.style.display = "block";
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
%x{
|
%x{
|
||||||
var input = document.getElementById('curl-command-input');
|
var input = document.getElementById('curl-command-input');
|
||||||
|
input.addEventListener('input', on_txt_change, false);
|
||||||
input.addEventListener('change', on_txt_change, false);
|
input.addEventListener('change', on_txt_change, false);
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
to_httpx
|
to_httpx
|
||||||
|
|
||||||
|
EXAMPLES = {
|
||||||
|
"simple" => "curl echoip.com",
|
||||||
|
"basicauth" => %Q{curl https://api.example.com/surprise -u banana:coconuts -d "sample data"},
|
||||||
|
"json" => %Q{curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer b7d03a6947b217efb6f3ec3bd3504582" -d '{"type":"A","name":"www","data":"162.10.66.0","priority":null,"port":null,"weight":null}' "https://api.digitalocean.com/v2/domains/example.com/records"},
|
||||||
|
"complexjson" => %Q{curl -u "demo:" -X POST -H "Content-Type: application/json" -d '{"array": [1,2,3], "object": {"foo": "bar", "nested": {"baz": true}}}' https://example.com/},
|
||||||
|
"formdata" => %Q{
|
||||||
|
curl -X POST https://api.easypost.com/v2/shipments \
|
||||||
|
-u API_KEY: \
|
||||||
|
-d 'shipment[to_address][id]=adr_HrBKVA85' \
|
||||||
|
-d 'shipment[from_address][id]=adr_VtuTOj7o' \
|
||||||
|
-d 'shipment[parcel][id]=prcl_WDv2VzHp' \
|
||||||
|
-d 'shipment[is_return]=true' \
|
||||||
|
-d 'shipment[customs_info][id]=cstinfo_bl5sE20Y'}
|
||||||
|
}
|
||||||
|
|
||||||
|
setexample = lambda do |ex|
|
||||||
|
%x{
|
||||||
|
var input = document.getElementById('curl-command-input');
|
||||||
|
input.value = #{EXAMPLES[ex]};
|
||||||
|
var event = new Event("input");
|
||||||
|
input.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
`window.setexample = setexample`
|
||||||
|
|
||||||
# if $0 == __FILE__
|
# if $0 == __FILE__
|
||||||
# command = ARGV.first
|
# command = ARGV.first
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user