Merge branch 'issue-162' into 'master'

Curl to httpx widget

Closes #162

See merge request honeyryderchuck/httpx!193
This commit is contained in:
HoneyryderChuck 2022-02-01 23:24:53 +00:00
commit a46fb03426
15 changed files with 982 additions and 266 deletions

View File

@ -88,6 +88,8 @@ end
group :website do
gem "hanna-nouveau"
# gem "opal", require: "opal"
gem "opal", git: "https://github.com/opal/opal.git", branch: "master", platform: :mri
gem "jekyll", "~> 4.2.0"
gem "jekyll-brotli", "~> 2.2.0", platform: :mri

View File

@ -81,6 +81,9 @@ module Faraday
def response=(response)
super
return if response.is_a?(::HTTPX::ErrorResponse)
response.body.on_data = @response_on_data
end
end
@ -210,6 +213,7 @@ module Faraday
if parallel?(env)
handler = env[:parallel_manager].enqueue(env)
handler.on_response do |response|
response.raise_for_status
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
response_headers.merge!(response.headers)
end

View File

@ -10,12 +10,12 @@ RUBY_ENGINE=`ruby -e 'puts RUBY_ENGINE'`
IPTABLES=iptables-translate
if [[ "$RUBY_ENGINE" = "truffleruby" ]]; then
microdnf install -y iptables iproute which file idn2
microdnf install -y iptables iproute which file idn2 git
elif [[ "$RUBY_PLATFORM" = "java" ]]; then
echo "
deb http://deb.debian.org/debian sid main contrib non-free
deb-src http://deb.debian.org/debian sid main contrib non-free" >> /etc/apt/sources.list
apt-get update && apt-get install -y build-essential iptables iproute2 openssl libssl-dev ca-certificates file idn2
apt-get update && apt-get install -y build-essential iptables iproute2 openssl libssl-dev ca-certificates file idn2 git
update-ca-certificates
elif [[ ${RUBY_VERSION:0:3} = "2.1" ]]; then
apt-get update && apt-get install -y libsodium-dev iptables iproute2 libmagic-dev shared-mime-info

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
set -euo pipefail

View File

@ -1,26 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEBjCCAe4CFEAnX6HC6fq3GnXmLwT3cxqbRvKQMA0GCSqGSIb3DQEBCwUAMEEx
MIIEBjCCAe4CFALAmAAVRbjEpV2RNq+ADoaW/kgZMA0GCSqGSIb3DQEBCwUAMEEx
CzAJBgNVBAYTAlBUMQswCQYDVQQIDAJMWDESMBAGA1UECgwJQnVtYmFrbGF0MREw
DwYDVQQDDAhodHRweC1jYTAgFw0yMTAxMzAxNTIzMDhaGA8zMDAxMDQwMzE1MjMw
OFowPDELMAkGA1UEBhMCUFQxCzAJBgNVBAgMAkxYMRIwEAYDVQQKDAlCdW1iYWts
DwYDVQQDDAhodHRweC1jYTAgFw0yMjAyMDEyMjQ5NDNaGA8zMDAyMDQwNTIyNDk0
M1owPDELMAkGA1UEBhMCUFQxCzAJBgNVBAgMAkxYMRIwEAYDVQQKDAlCdW1iYWts
YXQxDDAKBgNVBAMMA2RvaDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALoPIoQ0hnI6azw1UNJ2V4AxmMf3lBOVS5qHuIVHs5eegB4NPiJ0orxdW7Ghpc2+
rR7IflpiewDfLmw4kA4/WGRr7NujnmtuNQrX9eKOPY2ag2HgMKc4GvsnyOmnd2b2
dxbFX4EZOvrNP2t/yiFJRc+ko57UjenbrFFd9aZoNaHndVqaLJv5vz6moGTb0Xtd
wJbuxEVuUMtFbbqQjqZ78a04eQWw4f/VPCUUJMVBT2C4sy7QMlHX5kEuIYjCbGHP
YKCUiWKs3HB/ZkI+m/tnRu0ZPOUDxMTSARJitfgnhuajQQHtC2KgxzytksdqMiCa
zUrHpoSr/GelqPM9isFKIq8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAT1u+UMi2
eIZkAw9aFkCvTAfkKtIkO21eIKbK/PYo5jmR8umOkOfAh06jgp+WiE4cxFyTLsjI
CpPx83/5R0q5rL21DIbP847BWMjeulec/1qusEoWdeO3j+88f7pYGhCQscBYULXk
V6OMDS0tAP1fW64M9eXJ74B0XH4TCg7zJcrYOOuU+DaUJLixu3m7K7YF1+vfVDJ4
EPdSEpEPwiiREydXiOkw3acNbI93WB0r+LeYNPliEGZG4gY95xWK9qrDwOwcGs1W
+SpjGReIl5WpSXnDL1IxOgWKN5qulxI2eFLPGCjXC+9yx2dM68DKHu84mcLzbtvF
FcZ1qjyp54mdMiG6I9DYNRePqA2H9uiGULZGZs0e874BSsGv9ISBeE67gLbRYSX2
pemIJIgNlI/oIkQQ5PaFfaRCBXKixNEM348FcXqMdNZuYLruaZbKlGfALYKHMbOD
XIii8OaqYYcYGwQ1Jv4rppLnqcsQvvRuokOylLHvVvqVlB8gLUOQMBAiq2NuLEzH
BqM2jYs0Xg/bOkXJWbFylCAfOrwBb+M6UgkH8NvreE1af8Zmc+IUVE+HGcCOw1uZ
vQ6dm/JCLd9+quYqRXtw0+GJD6DmfF4FPojKHZCBAs5QVB8GDSxIC95zFexIYp39
SQldRsTczU/5O5+AhneHqbseSGTqI0UsPwY=
ALVurmb79h+z/Ko+LAvNOUMbnZnWw6DwycXU0xx5/xSzMsqsUwjXC3wPvVGfhVEV
OvtOC5vsNEW/L0nAfy+d1O53f0pbs+yM9JDi0qGhiYSCj62LsYSXh2nuoSCLZLPv
Puj4nsZD75ApzgtawjM5N8Q6r7ssEg+2iOjl7K8TYihGoAlZoqMo9B5ELianfwBR
fmT8KEROufQt10Wh7vZT6FiueQtoQLGgO63oVSilXkVCl8zvYYw/NENTan+Nck1G
evoqS0rIMw5wRdNMqy/dpTIe12bpgtifaN60XspDdcI3kyUvHvQwTcwqihg5apu8
uJdSkHHGvMeFPGf+Uy4xWTUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAStGfDZ5g
n7hJWPql63kFllEdM1ulUYFhhCLtnYPJyUEhV1gvjCQ10gpu9+F3zntnKM6ucgtz
PScaKyWzyDWzQNucWwbFjwEccGSkMIMzNXDbEjGuqLio8tpFYovSmkOqQPKXgAIV
i0/C9MHu13cE3EhIQ0oXfSiy12UVp7JuC7Q0Dg0f8JGu9qol42UqBiQCNZQ76Ssq
ggekzJA3nQhx/Ab111U+iNDLBwravTHeCumXfHLL1Nfz555okZJEGeEVg2byPiHY
/y2mOE3CnSkUc0RnZ3cZAtJpfeesL92rBWCp3qn1Ek7fjnF01p2rfwOCa0UxF8IN
jhBj/FjXjTms+rRk74raHC1zHug174vlzm6y1QfqkA/+1ki2ZwEdujVwsB3IWdYz
F4tS9TDK903B4Ka6b+9LE4w8h+X8645Tx0UMEQVZYpQAK9y5amHJ5p0vbDRXgbjf
aSOoQtpNMoYt315M4wGuE+AW84Oqfugqkz96VhPXcYKhnuVo28tzQ/V+1V2sr3Nd
MywM1xNG/XoUAhVCCsix/YTX5kUfUqnTGK54zEKSv4VXS6l+VffSG6iz46wRgRpC
+NZuQKrszMUNyFrJvaIFHTwnXLarLWB33Skb4fQLMoJkyarQeWvbKO6FBGeAJ8Gl
//YRL5UxIPjw4LywQKBXcFkRUi4Rxg6ydYg=
-----END CERTIFICATE-----
Certificate:
Data:
@ -29,31 +29,31 @@ Certificate:
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=PT, ST=LX, O=Bumbaklat, CN=httpx-ca
Validity
Not Before: Jan 30 15:23:08 2021 GMT
Not After : Jan 30 15:23:08 2022 GMT
Not Before: Feb 1 22:49:43 2022 GMT
Not After : Feb 1 22:49:43 2023 GMT
Subject: C=PT, ST=LX, O=Bumbaklat, OU=nghttp2, CN=nghttp2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c0:76:20:b8:6d:99:78:5c:05:e2:7f:ef:1c:9c:
d8:73:ae:d4:a1:7c:99:e2:f2:59:fd:2b:09:f7:19:
3a:38:6d:ef:80:be:ce:6b:9d:b3:8e:46:be:ac:85:
2c:99:e9:77:a8:de:48:d3:53:61:70:77:00:aa:73:
af:2c:1a:80:69:a5:67:b0:27:ad:a8:3e:1e:f2:d7:
f1:6f:a6:00:ee:bf:9d:77:9a:00:ba:ea:7b:a4:81:
c2:39:04:d6:d1:e2:40:e0:a4:be:b0:71:c0:ef:c2:
52:ef:86:9c:7e:4d:12:77:f2:51:cb:bb:e8:d5:f7:
b5:b7:5d:ab:67:7d:76:8a:78:1e:66:40:53:d7:ec:
cd:cf:6f:11:97:83:2b:d8:ca:d0:24:91:1f:65:3d:
52:d7:e6:73:c6:71:c4:51:2a:02:d6:11:9b:22:fc:
f0:5b:d2:6c:f7:33:7b:43:a2:6a:ac:cb:fb:02:ef:
38:47:a6:ab:4e:f8:81:cd:cf:86:1a:8a:22:f4:eb:
85:be:dc:af:a6:5b:49:4c:d8:f9:64:20:10:fd:3d:
0a:28:47:b2:7f:c1:e9:f0:f7:56:a3:5d:c0:db:57:
73:a7:ad:bd:61:25:b2:4c:4c:c9:dd:aa:d1:fc:80:
71:49:20:a0:a7:55:c6:ff:dc:5d:44:b7:5e:91:ec:
38:77
00:96:f8:d7:89:d0:7e:d6:38:13:fa:8f:be:87:81:
0d:67:24:2c:cd:cc:51:13:7c:57:8e:74:ab:12:7b:
fc:f9:e2:10:d3:b1:50:74:e3:4a:7e:96:a1:ca:0f:
6b:16:2a:51:17:61:fd:81:78:5f:22:8a:39:dc:2e:
79:80:b9:73:a9:c9:24:42:92:be:78:11:4a:ec:2f:
75:f9:81:47:25:bb:f9:2f:cb:43:a6:0e:c8:b1:4c:
c1:25:2c:af:ea:24:79:62:08:c0:34:7e:22:2f:76:
90:75:cb:b7:bd:a3:34:93:51:dd:07:1b:d1:30:bf:
fa:99:56:e6:3b:a7:d3:30:d0:de:df:e7:5b:b7:5f:
80:55:f0:af:b3:0e:64:04:a6:42:6b:e6:e2:58:04:
6e:bb:09:ca:a7:9c:5e:2c:08:f2:1c:8d:c3:61:d3:
7c:22:95:b2:a4:9e:f6:e7:37:85:12:74:f8:dc:5b:
6a:3f:00:2f:23:27:28:52:10:a1:16:24:82:5b:c5:
58:10:00:71:b1:59:71:e1:c8:ca:e9:c6:00:e0:41:
dd:b8:b9:35:33:c9:24:93:d0:b4:ba:00:e6:5b:dc:
a2:6a:cf:38:2f:85:b1:4a:44:db:cb:02:fa:88:4d:
97:bb:01:19:7a:5c:6b:7d:c8:e6:d6:5e:c4:f1:af:
69:f1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
@ -61,91 +61,91 @@ Certificate:
X509v3 Subject Alternative Name:
DNS:nghttp2, DNS:another, DNS:another2
X509v3 Subject Key Identifier:
2E:63:AD:2E:8A:C7:7A:16:B4:52:0E:C6:0A:88:51:74:60:07:6B:34
E1:F6:71:9B:4F:67:AC:8F:0D:C9:7C:20:D6:7F:4F:9D:49:68:07:19
Signature Algorithm: sha256WithRSAEncryption
2a:70:05:46:3f:28:4b:50:60:c6:0a:ac:46:6b:7f:4b:f1:1e:
8b:c3:52:c9:35:1f:3d:ad:23:73:f1:7a:54:5f:de:91:e9:cb:
2b:b4:77:9e:44:56:76:78:0b:ca:5f:c6:00:c8:4f:04:c5:47:
74:83:79:98:38:f1:da:ad:10:b2:4a:7f:2e:78:a6:c3:70:63:
5c:9e:07:e7:ab:b5:f4:44:6a:8d:86:2c:a3:0c:31:3b:89:ce:
c7:ab:82:2e:9f:57:88:31:9f:46:80:0f:86:8f:ef:2f:35:36:
9b:2d:51:61:93:86:da:17:96:94:1b:44:75:9d:52:f2:be:84:
4f:da:11:80:9b:f5:47:a8:ab:cb:c2:ae:bf:e3:71:8b:3b:5a:
37:5d:b9:aa:36:b8:b8:13:b0:6d:77:17:c7:ee:24:9b:3b:f3:
36:14:f3:0f:48:d7:18:e6:40:4d:be:c6:da:ff:4d:18:78:eb:
be:09:47:b9:fe:65:f1:ed:32:2c:dd:be:26:a4:a8:4f:9b:c0:
96:6a:32:d8:4a:9a:45:93:f4:43:44:43:72:be:8d:71:53:f1:
a2:9c:ad:d5:8f:8e:76:6e:84:e1:c7:0e:06:33:a4:bc:19:d5:
b8:ab:f5:58:80:50:d5:87:ca:ac:2a:e6:49:f4:8c:b9:37:7b:
bf:b8:3d:af:db:75:49:75:9b:7e:1a:f0:84:30:b7:06:c1:e0:
a4:1b:be:36:d8:fd:42:fd:0a:ea:a1:b5:7a:e0:dc:f1:01:bd:
73:64:df:c2:3a:7b:8c:3f:f1:17:e0:70:1f:9c:bd:a3:1d:cb:
68:53:d2:ee:50:7b:07:4f:d5:f0:a7:4e:d0:d3:41:8f:d3:70:
a2:c8:32:4b:f4:88:4d:0c:4e:71:a7:a4:bc:7c:45:b9:f4:be:
6c:24:72:76:08:8f:5a:22:7b:c0:83:b4:60:1f:5f:69:ea:6c:
11:a4:a6:f8:c9:21:5e:44:60:7c:51:17:c0:a1:8a:79:a7:2b:
b2:ca:6d:8c:b9:8d:5f:33:8e:9c:f3:68:69:f5:35:9b:e7:2d:
29:bb:69:2f:d5:f5:d7:d7:7b:fd:8b:24:87:a8:e0:06:bb:f7:
b4:5d:06:45:5d:cb:5e:38:24:e1:73:01:c9:5a:bd:bc:19:3b:
ee:fa:8e:25:c5:8e:fc:8d:66:8b:ab:56:ae:4c:60:c1:42:1f:
05:eb:24:87:72:fc:ca:9f:99:93:2b:69:2b:84:36:4d:26:7a:
c4:4c:27:c6:76:ff:47:49:07:c3:f4:75:3b:17:59:dd:4e:3e:
4f:e7:1a:f7:62:2b:f7:c5:49:62:2a:2f:96:7e:c6:78:35:6f:
24:dc:a8:42:46:12:67:dc
bf:3e:47:e4:ea:bd:14:0b:b9:aa:5e:74:c4:7a:7c:af:25:b4:
05:e1:6a:ba:b1:c0:21:fc:b4:82:87:49:d7:28:e1:dd:9c:ae:
c5:6e:72:87:08:bd:df:9f:b2:97:7f:61:0f:24:ea:86:36:a0:
0c:8f:bd:85:37:b8:41:e9:7e:10:86:f3:f3:d1:4b:ea:98:82:
a4:28:fb:3b:b2:7d:d7:a8:27:e6:47:1d:8c:7c:2f:69:ed:ed:
b8:74:ae:57:36:f9:f8:6b:39:77:b2:e4:69:6c:de:e6:13:62:
3a:76:f0:06:a6:b8:7b:55:6c:63:12:18:d6:70:4a:4e:d0:14:
e1:9f:50:7f:a0:6f:0f:2e:79:17:3b:e8:30:d1:1a:a9:7e:37:
45:5a:f2:54:84:9d:57:81:a4:f3:9a:0b:b5:e2:98:d4:e1:9f:
10:ea:f9:01:08:12:02:af:e8:ee:0c:e0:ca:ec:45:ea:b2:64:
16:ab:c8:a4:dd:37:25:d2:65:8f:50:cb:a2:09:59:50:4a:6b:
44:f2:6f:97:fb:ef:20:9a:ad:ec:d6:e2:51:f6:77:b8:80:78:
03:5e:80:6d:64:b3:73:9e:ee:65:ef:15:91:dd:2e:a0:bc:95:
15:26:70:29:77:07:02:47:06:a1:40:37:cc:22:59:30:52:10:
9f:0b:1c:80:29:32:07:49:51:d6:41:f4:8a:f0:05:41:39:8a:
68:de:a1:70:cb:b8:ee:c6:d8:5c:0b:0b:24:fb:68:34:83:19:
b1:d4:74:37:ee:89:af:d5:79:31:3b:d4:25:69:0d:10:fb:17:
34:c0:75:7a:93:1b:f0:06:1e:93:25:a8:eb:80:08:69:6e:15:
51:fb:d4:d0:3e:7d:da:ad:fd:ee:e0:dc:8d:cc:87:c1:6b:94:
aa:7c:dc:33:fd:44:00:c9:ac:e3:75:34:fe:84:03:95:4c:01:
8d:53:2e:0a:87:79:b2:ca:c8:c6:aa:1c:06:99:70:56:76:4d:
88:09:4d:7a:b2:18:0e:af:a3:d1:ef:bf:7f:80:c3:ff:c1:f2:
93:18:5d:69:f6:63:77:bd:38:ed:0c:64:3d:a6:17:46:c6:dc:
6b:ac:44:20:f2:0d:d9:d6:7a:ea:01:be:04:25:30:0d:b4:83:
66:71:50:74:b0:57:ca:60:d4:19:b9:85:ac:7f:9f:a6:d5:9f:
0f:27:9f:88:0f:6e:9f:f9:a3:33:bc:79:f0:25:6e:a1:e6:4e:
0d:69:d0:55:78:0b:bd:f2:00:1d:ac:74:4d:8f:8c:71:5d:1d:
ad:68:10:5f:d2:a3:3a:16:88:7c:5a:04:79:8d:83:70:e8:90:
bf:1f:fd:68:4b:4f:54:09
-----BEGIN CERTIFICATE-----
MIIEYTCCAkmgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJQVDEL
MAkGA1UECAwCTFgxEjAQBgNVBAoMCUJ1bWJha2xhdDERMA8GA1UEAwwIaHR0cHgt
Y2EwHhcNMjEwMTMwMTUyMzA4WhcNMjIwMTMwMTUyMzA4WjBSMQswCQYDVQQGEwJQ
Y2EwHhcNMjIwMjAxMjI0OTQzWhcNMjMwMjAxMjI0OTQzWjBSMQswCQYDVQQGEwJQ
VDELMAkGA1UECAwCTFgxEjAQBgNVBAoMCUJ1bWJha2xhdDEQMA4GA1UECwwHbmdo
dHRwMjEQMA4GA1UEAwwHbmdodHRwMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAMB2ILhtmXhcBeJ/7xyc2HOu1KF8meLyWf0rCfcZOjht74C+zmuds45G
vqyFLJnpd6jeSNNTYXB3AKpzrywagGmlZ7Anrag+HvLX8W+mAO6/nXeaALrqe6SB
wjkE1tHiQOCkvrBxwO/CUu+GnH5NEnfyUcu76NX3tbddq2d9dop4HmZAU9fszc9v
EZeDK9jK0CSRH2U9Utfmc8ZxxFEqAtYRmyL88FvSbPcze0OiaqzL+wLvOEemq074
gc3PhhqKIvTrhb7cr6ZbSUzY+WQgEP09CihHsn/B6fD3VqNdwNtXc6etvWElskxM
yd2q0fyAcUkgoKdVxv/cXUS3XpHsOHcCAwEAAaNTMFEwCQYDVR0TBAIwADAlBgNV
HREEHjAcggduZ2h0dHAyggdhbm90aGVygghhbm90aGVyMjAdBgNVHQ4EFgQULmOt
LorHeha0Ug7GCohRdGAHazQwDQYJKoZIhvcNAQELBQADggIBACpwBUY/KEtQYMYK
rEZrf0vxHovDUsk1Hz2tI3PxelRf3pHpyyu0d55EVnZ4C8pfxgDITwTFR3SDeZg4
8dqtELJKfy54psNwY1yeB+ertfREao2GLKMMMTuJzsergi6fV4gxn0aAD4aP7y81
NpstUWGThtoXlpQbRHWdUvK+hE/aEYCb9Ueoq8vCrr/jcYs7Wjdduao2uLgTsG13
F8fuJJs78zYU8w9I1xjmQE2+xtr/TRh4674JR7n+ZfHtMizdviakqE+bwJZqMthK
mkWT9ENEQ3K+jXFT8aKcrdWPjnZuhOHHDgYzpLwZ1bir9ViAUNWHyqwq5kn0jLk3
e7+4Pa/bdUl1m34a8IQwtwbB4KQbvjbY/UL9CuqhtXrg3PEBvXNk38I6e4w/8Rfg
cB+cvaMdy2hT0u5QewdP1fCnTtDTQY/TcKLIMkv0iE0MTnGnpLx8Rbn0vmwkcnYI
j1oie8CDtGAfX2nqbBGkpvjJIV5EYHxRF8ChinmnK7LKbYy5jV8zjpzzaGn1NZvn
LSm7aS/V9dfXe/2LJIeo4Aa797RdBkVdy144JOFzAclavbwZO+76jiXFjvyNZour
Vq5MYMFCHwXrJIdy/MqfmZMraSuENk0mesRMJ8Z2/0dJB8P0dTsXWd1OPk/nGvdi
K/fFSWIqL5Z+xng1byTcqEJGEmfc
AQoCggEBAJb414nQftY4E/qPvoeBDWckLM3MURN8V450qxJ7/PniENOxUHTjSn6W
ocoPaxYqURdh/YF4XyKKOdwueYC5c6nJJEKSvngRSuwvdfmBRyW7+S/LQ6YOyLFM
wSUsr+okeWIIwDR+Ii92kHXLt72jNJNR3Qcb0TC/+plW5jun0zDQ3t/nW7dfgFXw
r7MOZASmQmvm4lgEbrsJyqecXiwI8hyNw2HTfCKVsqSe9uc3hRJ0+Nxbaj8ALyMn
KFIQoRYkglvFWBAAcbFZceHIyunGAOBB3bi5NTPJJJPQtLoA5lvcomrPOC+FsUpE
28sC+ohNl7sBGXpca33I5tZexPGvafECAwEAAaNTMFEwCQYDVR0TBAIwADAlBgNV
HREEHjAcggduZ2h0dHAyggdhbm90aGVygghhbm90aGVyMjAdBgNVHQ4EFgQU4fZx
m09nrI8NyXwg1n9PnUloBxkwDQYJKoZIhvcNAQELBQADggIBAL8+R+TqvRQLuape
dMR6fK8ltAXharqxwCH8tIKHSdco4d2crsVucocIvd+fspd/YQ8k6oY2oAyPvYU3
uEHpfhCG8/PRS+qYgqQo+zuyfdeoJ+ZHHYx8L2nt7bh0rlc2+fhrOXey5Gls3uYT
Yjp28AamuHtVbGMSGNZwSk7QFOGfUH+gbw8ueRc76DDRGql+N0Va8lSEnVeBpPOa
C7XimNThnxDq+QEIEgKv6O4M4MrsReqyZBaryKTdNyXSZY9Qy6IJWVBKa0Tyb5f7
7yCarezW4lH2d7iAeANegG1ks3Oe7mXvFZHdLqC8lRUmcCl3BwJHBqFAN8wiWTBS
EJ8LHIApMgdJUdZB9IrwBUE5imjeoXDLuO7G2FwLCyT7aDSDGbHUdDfuia/VeTE7
1CVpDRD7FzTAdXqTG/AGHpMlqOuACGluFVH71NA+fdqt/e7g3I3Mh8FrlKp83DP9
RADJrON1NP6EA5VMAY1TLgqHebLKyMaqHAaZcFZ2TYgJTXqyGA6vo9Hvv3+Aw//B
8pMYXWn2Y3e9OO0MZD2mF0bG3GusRCDyDdnWeuoBvgQlMA20g2ZxUHSwV8pg1Bm5
hax/n6bVnw8nn4gPbp/5ozO8efAlbqHmTg1p0FV4C73yAB2sdE2PjHFdHa1oEF/S
ozoWiHxaBHmNg3DokL8f/WhLT1QJ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@ -1,24 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEBjCCAe4CFEAnX6HC6fq3GnXmLwT3cxqbRvKQMA0GCSqGSIb3DQEBCwUAMEEx
MIIEBjCCAe4CFALAmAAVRbjEpV2RNq+ADoaW/kgZMA0GCSqGSIb3DQEBCwUAMEEx
CzAJBgNVBAYTAlBUMQswCQYDVQQIDAJMWDESMBAGA1UECgwJQnVtYmFrbGF0MREw
DwYDVQQDDAhodHRweC1jYTAgFw0yMTAxMzAxNTIzMDhaGA8zMDAxMDQwMzE1MjMw
OFowPDELMAkGA1UEBhMCUFQxCzAJBgNVBAgMAkxYMRIwEAYDVQQKDAlCdW1iYWts
DwYDVQQDDAhodHRweC1jYTAgFw0yMjAyMDEyMjQ5NDNaGA8zMDAyMDQwNTIyNDk0
M1owPDELMAkGA1UEBhMCUFQxCzAJBgNVBAgMAkxYMRIwEAYDVQQKDAlCdW1iYWts
YXQxDDAKBgNVBAMMA2RvaDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALoPIoQ0hnI6azw1UNJ2V4AxmMf3lBOVS5qHuIVHs5eegB4NPiJ0orxdW7Ghpc2+
rR7IflpiewDfLmw4kA4/WGRr7NujnmtuNQrX9eKOPY2ag2HgMKc4GvsnyOmnd2b2
dxbFX4EZOvrNP2t/yiFJRc+ko57UjenbrFFd9aZoNaHndVqaLJv5vz6moGTb0Xtd
wJbuxEVuUMtFbbqQjqZ78a04eQWw4f/VPCUUJMVBT2C4sy7QMlHX5kEuIYjCbGHP
YKCUiWKs3HB/ZkI+m/tnRu0ZPOUDxMTSARJitfgnhuajQQHtC2KgxzytksdqMiCa
zUrHpoSr/GelqPM9isFKIq8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAT1u+UMi2
eIZkAw9aFkCvTAfkKtIkO21eIKbK/PYo5jmR8umOkOfAh06jgp+WiE4cxFyTLsjI
CpPx83/5R0q5rL21DIbP847BWMjeulec/1qusEoWdeO3j+88f7pYGhCQscBYULXk
V6OMDS0tAP1fW64M9eXJ74B0XH4TCg7zJcrYOOuU+DaUJLixu3m7K7YF1+vfVDJ4
EPdSEpEPwiiREydXiOkw3acNbI93WB0r+LeYNPliEGZG4gY95xWK9qrDwOwcGs1W
+SpjGReIl5WpSXnDL1IxOgWKN5qulxI2eFLPGCjXC+9yx2dM68DKHu84mcLzbtvF
FcZ1qjyp54mdMiG6I9DYNRePqA2H9uiGULZGZs0e874BSsGv9ISBeE67gLbRYSX2
pemIJIgNlI/oIkQQ5PaFfaRCBXKixNEM348FcXqMdNZuYLruaZbKlGfALYKHMbOD
XIii8OaqYYcYGwQ1Jv4rppLnqcsQvvRuokOylLHvVvqVlB8gLUOQMBAiq2NuLEzH
BqM2jYs0Xg/bOkXJWbFylCAfOrwBb+M6UgkH8NvreE1af8Zmc+IUVE+HGcCOw1uZ
vQ6dm/JCLd9+quYqRXtw0+GJD6DmfF4FPojKHZCBAs5QVB8GDSxIC95zFexIYp39
SQldRsTczU/5O5+AhneHqbseSGTqI0UsPwY=
ALVurmb79h+z/Ko+LAvNOUMbnZnWw6DwycXU0xx5/xSzMsqsUwjXC3wPvVGfhVEV
OvtOC5vsNEW/L0nAfy+d1O53f0pbs+yM9JDi0qGhiYSCj62LsYSXh2nuoSCLZLPv
Puj4nsZD75ApzgtawjM5N8Q6r7ssEg+2iOjl7K8TYihGoAlZoqMo9B5ELianfwBR
fmT8KEROufQt10Wh7vZT6FiueQtoQLGgO63oVSilXkVCl8zvYYw/NENTan+Nck1G
evoqS0rIMw5wRdNMqy/dpTIe12bpgtifaN60XspDdcI3kyUvHvQwTcwqihg5apu8
uJdSkHHGvMeFPGf+Uy4xWTUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAStGfDZ5g
n7hJWPql63kFllEdM1ulUYFhhCLtnYPJyUEhV1gvjCQ10gpu9+F3zntnKM6ucgtz
PScaKyWzyDWzQNucWwbFjwEccGSkMIMzNXDbEjGuqLio8tpFYovSmkOqQPKXgAIV
i0/C9MHu13cE3EhIQ0oXfSiy12UVp7JuC7Q0Dg0f8JGu9qol42UqBiQCNZQ76Ssq
ggekzJA3nQhx/Ab111U+iNDLBwravTHeCumXfHLL1Nfz555okZJEGeEVg2byPiHY
/y2mOE3CnSkUc0RnZ3cZAtJpfeesL92rBWCp3qn1Ek7fjnF01p2rfwOCa0UxF8IN
jhBj/FjXjTms+rRk74raHC1zHug174vlzm6y1QfqkA/+1ki2ZwEdujVwsB3IWdYz
F4tS9TDK903B4Ka6b+9LE4w8h+X8645Tx0UMEQVZYpQAK9y5amHJ5p0vbDRXgbjf
aSOoQtpNMoYt315M4wGuE+AW84Oqfugqkz96VhPXcYKhnuVo28tzQ/V+1V2sr3Nd
MywM1xNG/XoUAhVCCsix/YTX5kUfUqnTGK54zEKSv4VXS6l+VffSG6iz46wRgRpC
+NZuQKrszMUNyFrJvaIFHTwnXLarLWB33Skb4fQLMoJkyarQeWvbKO6FBGeAJ8Gl
//YRL5UxIPjw4LywQKBXcFkRUi4Rxg6ydYg=
-----END CERTIFICATE-----

View File

@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -5,31 +5,31 @@ Certificate:
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=PT, ST=LX, O=Bumbaklat, CN=httpx-ca
Validity
Not Before: Jan 30 15:23:08 2021 GMT
Not After : Jan 30 15:23:08 2022 GMT
Not Before: Feb 1 22:49:43 2022 GMT
Not After : Feb 1 22:49:43 2023 GMT
Subject: C=PT, ST=LX, O=Bumbaklat, OU=nghttp2, CN=nghttp2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c0:76:20:b8:6d:99:78:5c:05:e2:7f:ef:1c:9c:
d8:73:ae:d4:a1:7c:99:e2:f2:59:fd:2b:09:f7:19:
3a:38:6d:ef:80:be:ce:6b:9d:b3:8e:46:be:ac:85:
2c:99:e9:77:a8:de:48:d3:53:61:70:77:00:aa:73:
af:2c:1a:80:69:a5:67:b0:27:ad:a8:3e:1e:f2:d7:
f1:6f:a6:00:ee:bf:9d:77:9a:00:ba:ea:7b:a4:81:
c2:39:04:d6:d1:e2:40:e0:a4:be:b0:71:c0:ef:c2:
52:ef:86:9c:7e:4d:12:77:f2:51:cb:bb:e8:d5:f7:
b5:b7:5d:ab:67:7d:76:8a:78:1e:66:40:53:d7:ec:
cd:cf:6f:11:97:83:2b:d8:ca:d0:24:91:1f:65:3d:
52:d7:e6:73:c6:71:c4:51:2a:02:d6:11:9b:22:fc:
f0:5b:d2:6c:f7:33:7b:43:a2:6a:ac:cb:fb:02:ef:
38:47:a6:ab:4e:f8:81:cd:cf:86:1a:8a:22:f4:eb:
85:be:dc:af:a6:5b:49:4c:d8:f9:64:20:10:fd:3d:
0a:28:47:b2:7f:c1:e9:f0:f7:56:a3:5d:c0:db:57:
73:a7:ad:bd:61:25:b2:4c:4c:c9:dd:aa:d1:fc:80:
71:49:20:a0:a7:55:c6:ff:dc:5d:44:b7:5e:91:ec:
38:77
00:96:f8:d7:89:d0:7e:d6:38:13:fa:8f:be:87:81:
0d:67:24:2c:cd:cc:51:13:7c:57:8e:74:ab:12:7b:
fc:f9:e2:10:d3:b1:50:74:e3:4a:7e:96:a1:ca:0f:
6b:16:2a:51:17:61:fd:81:78:5f:22:8a:39:dc:2e:
79:80:b9:73:a9:c9:24:42:92:be:78:11:4a:ec:2f:
75:f9:81:47:25:bb:f9:2f:cb:43:a6:0e:c8:b1:4c:
c1:25:2c:af:ea:24:79:62:08:c0:34:7e:22:2f:76:
90:75:cb:b7:bd:a3:34:93:51:dd:07:1b:d1:30:bf:
fa:99:56:e6:3b:a7:d3:30:d0:de:df:e7:5b:b7:5f:
80:55:f0:af:b3:0e:64:04:a6:42:6b:e6:e2:58:04:
6e:bb:09:ca:a7:9c:5e:2c:08:f2:1c:8d:c3:61:d3:
7c:22:95:b2:a4:9e:f6:e7:37:85:12:74:f8:dc:5b:
6a:3f:00:2f:23:27:28:52:10:a1:16:24:82:5b:c5:
58:10:00:71:b1:59:71:e1:c8:ca:e9:c6:00:e0:41:
dd:b8:b9:35:33:c9:24:93:d0:b4:ba:00:e6:5b:dc:
a2:6a:cf:38:2f:85:b1:4a:44:db:cb:02:fa:88:4d:
97:bb:01:19:7a:5c:6b:7d:c8:e6:d6:5e:c4:f1:af:
69:f1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
@ -37,60 +37,60 @@ Certificate:
X509v3 Subject Alternative Name:
DNS:nghttp2, DNS:another, DNS:another2
X509v3 Subject Key Identifier:
2E:63:AD:2E:8A:C7:7A:16:B4:52:0E:C6:0A:88:51:74:60:07:6B:34
E1:F6:71:9B:4F:67:AC:8F:0D:C9:7C:20:D6:7F:4F:9D:49:68:07:19
Signature Algorithm: sha256WithRSAEncryption
2a:70:05:46:3f:28:4b:50:60:c6:0a:ac:46:6b:7f:4b:f1:1e:
8b:c3:52:c9:35:1f:3d:ad:23:73:f1:7a:54:5f:de:91:e9:cb:
2b:b4:77:9e:44:56:76:78:0b:ca:5f:c6:00:c8:4f:04:c5:47:
74:83:79:98:38:f1:da:ad:10:b2:4a:7f:2e:78:a6:c3:70:63:
5c:9e:07:e7:ab:b5:f4:44:6a:8d:86:2c:a3:0c:31:3b:89:ce:
c7:ab:82:2e:9f:57:88:31:9f:46:80:0f:86:8f:ef:2f:35:36:
9b:2d:51:61:93:86:da:17:96:94:1b:44:75:9d:52:f2:be:84:
4f:da:11:80:9b:f5:47:a8:ab:cb:c2:ae:bf:e3:71:8b:3b:5a:
37:5d:b9:aa:36:b8:b8:13:b0:6d:77:17:c7:ee:24:9b:3b:f3:
36:14:f3:0f:48:d7:18:e6:40:4d:be:c6:da:ff:4d:18:78:eb:
be:09:47:b9:fe:65:f1:ed:32:2c:dd:be:26:a4:a8:4f:9b:c0:
96:6a:32:d8:4a:9a:45:93:f4:43:44:43:72:be:8d:71:53:f1:
a2:9c:ad:d5:8f:8e:76:6e:84:e1:c7:0e:06:33:a4:bc:19:d5:
b8:ab:f5:58:80:50:d5:87:ca:ac:2a:e6:49:f4:8c:b9:37:7b:
bf:b8:3d:af:db:75:49:75:9b:7e:1a:f0:84:30:b7:06:c1:e0:
a4:1b:be:36:d8:fd:42:fd:0a:ea:a1:b5:7a:e0:dc:f1:01:bd:
73:64:df:c2:3a:7b:8c:3f:f1:17:e0:70:1f:9c:bd:a3:1d:cb:
68:53:d2:ee:50:7b:07:4f:d5:f0:a7:4e:d0:d3:41:8f:d3:70:
a2:c8:32:4b:f4:88:4d:0c:4e:71:a7:a4:bc:7c:45:b9:f4:be:
6c:24:72:76:08:8f:5a:22:7b:c0:83:b4:60:1f:5f:69:ea:6c:
11:a4:a6:f8:c9:21:5e:44:60:7c:51:17:c0:a1:8a:79:a7:2b:
b2:ca:6d:8c:b9:8d:5f:33:8e:9c:f3:68:69:f5:35:9b:e7:2d:
29:bb:69:2f:d5:f5:d7:d7:7b:fd:8b:24:87:a8:e0:06:bb:f7:
b4:5d:06:45:5d:cb:5e:38:24:e1:73:01:c9:5a:bd:bc:19:3b:
ee:fa:8e:25:c5:8e:fc:8d:66:8b:ab:56:ae:4c:60:c1:42:1f:
05:eb:24:87:72:fc:ca:9f:99:93:2b:69:2b:84:36:4d:26:7a:
c4:4c:27:c6:76:ff:47:49:07:c3:f4:75:3b:17:59:dd:4e:3e:
4f:e7:1a:f7:62:2b:f7:c5:49:62:2a:2f:96:7e:c6:78:35:6f:
24:dc:a8:42:46:12:67:dc
bf:3e:47:e4:ea:bd:14:0b:b9:aa:5e:74:c4:7a:7c:af:25:b4:
05:e1:6a:ba:b1:c0:21:fc:b4:82:87:49:d7:28:e1:dd:9c:ae:
c5:6e:72:87:08:bd:df:9f:b2:97:7f:61:0f:24:ea:86:36:a0:
0c:8f:bd:85:37:b8:41:e9:7e:10:86:f3:f3:d1:4b:ea:98:82:
a4:28:fb:3b:b2:7d:d7:a8:27:e6:47:1d:8c:7c:2f:69:ed:ed:
b8:74:ae:57:36:f9:f8:6b:39:77:b2:e4:69:6c:de:e6:13:62:
3a:76:f0:06:a6:b8:7b:55:6c:63:12:18:d6:70:4a:4e:d0:14:
e1:9f:50:7f:a0:6f:0f:2e:79:17:3b:e8:30:d1:1a:a9:7e:37:
45:5a:f2:54:84:9d:57:81:a4:f3:9a:0b:b5:e2:98:d4:e1:9f:
10:ea:f9:01:08:12:02:af:e8:ee:0c:e0:ca:ec:45:ea:b2:64:
16:ab:c8:a4:dd:37:25:d2:65:8f:50:cb:a2:09:59:50:4a:6b:
44:f2:6f:97:fb:ef:20:9a:ad:ec:d6:e2:51:f6:77:b8:80:78:
03:5e:80:6d:64:b3:73:9e:ee:65:ef:15:91:dd:2e:a0:bc:95:
15:26:70:29:77:07:02:47:06:a1:40:37:cc:22:59:30:52:10:
9f:0b:1c:80:29:32:07:49:51:d6:41:f4:8a:f0:05:41:39:8a:
68:de:a1:70:cb:b8:ee:c6:d8:5c:0b:0b:24:fb:68:34:83:19:
b1:d4:74:37:ee:89:af:d5:79:31:3b:d4:25:69:0d:10:fb:17:
34:c0:75:7a:93:1b:f0:06:1e:93:25:a8:eb:80:08:69:6e:15:
51:fb:d4:d0:3e:7d:da:ad:fd:ee:e0:dc:8d:cc:87:c1:6b:94:
aa:7c:dc:33:fd:44:00:c9:ac:e3:75:34:fe:84:03:95:4c:01:
8d:53:2e:0a:87:79:b2:ca:c8:c6:aa:1c:06:99:70:56:76:4d:
88:09:4d:7a:b2:18:0e:af:a3:d1:ef:bf:7f:80:c3:ff:c1:f2:
93:18:5d:69:f6:63:77:bd:38:ed:0c:64:3d:a6:17:46:c6:dc:
6b:ac:44:20:f2:0d:d9:d6:7a:ea:01:be:04:25:30:0d:b4:83:
66:71:50:74:b0:57:ca:60:d4:19:b9:85:ac:7f:9f:a6:d5:9f:
0f:27:9f:88:0f:6e:9f:f9:a3:33:bc:79:f0:25:6e:a1:e6:4e:
0d:69:d0:55:78:0b:bd:f2:00:1d:ac:74:4d:8f:8c:71:5d:1d:
ad:68:10:5f:d2:a3:3a:16:88:7c:5a:04:79:8d:83:70:e8:90:
bf:1f:fd:68:4b:4f:54:09
-----BEGIN CERTIFICATE-----
MIIEYTCCAkmgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJQVDEL
MAkGA1UECAwCTFgxEjAQBgNVBAoMCUJ1bWJha2xhdDERMA8GA1UEAwwIaHR0cHgt
Y2EwHhcNMjEwMTMwMTUyMzA4WhcNMjIwMTMwMTUyMzA4WjBSMQswCQYDVQQGEwJQ
Y2EwHhcNMjIwMjAxMjI0OTQzWhcNMjMwMjAxMjI0OTQzWjBSMQswCQYDVQQGEwJQ
VDELMAkGA1UECAwCTFgxEjAQBgNVBAoMCUJ1bWJha2xhdDEQMA4GA1UECwwHbmdo
dHRwMjEQMA4GA1UEAwwHbmdodHRwMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAMB2ILhtmXhcBeJ/7xyc2HOu1KF8meLyWf0rCfcZOjht74C+zmuds45G
vqyFLJnpd6jeSNNTYXB3AKpzrywagGmlZ7Anrag+HvLX8W+mAO6/nXeaALrqe6SB
wjkE1tHiQOCkvrBxwO/CUu+GnH5NEnfyUcu76NX3tbddq2d9dop4HmZAU9fszc9v
EZeDK9jK0CSRH2U9Utfmc8ZxxFEqAtYRmyL88FvSbPcze0OiaqzL+wLvOEemq074
gc3PhhqKIvTrhb7cr6ZbSUzY+WQgEP09CihHsn/B6fD3VqNdwNtXc6etvWElskxM
yd2q0fyAcUkgoKdVxv/cXUS3XpHsOHcCAwEAAaNTMFEwCQYDVR0TBAIwADAlBgNV
HREEHjAcggduZ2h0dHAyggdhbm90aGVygghhbm90aGVyMjAdBgNVHQ4EFgQULmOt
LorHeha0Ug7GCohRdGAHazQwDQYJKoZIhvcNAQELBQADggIBACpwBUY/KEtQYMYK
rEZrf0vxHovDUsk1Hz2tI3PxelRf3pHpyyu0d55EVnZ4C8pfxgDITwTFR3SDeZg4
8dqtELJKfy54psNwY1yeB+ertfREao2GLKMMMTuJzsergi6fV4gxn0aAD4aP7y81
NpstUWGThtoXlpQbRHWdUvK+hE/aEYCb9Ueoq8vCrr/jcYs7Wjdduao2uLgTsG13
F8fuJJs78zYU8w9I1xjmQE2+xtr/TRh4674JR7n+ZfHtMizdviakqE+bwJZqMthK
mkWT9ENEQ3K+jXFT8aKcrdWPjnZuhOHHDgYzpLwZ1bir9ViAUNWHyqwq5kn0jLk3
e7+4Pa/bdUl1m34a8IQwtwbB4KQbvjbY/UL9CuqhtXrg3PEBvXNk38I6e4w/8Rfg
cB+cvaMdy2hT0u5QewdP1fCnTtDTQY/TcKLIMkv0iE0MTnGnpLx8Rbn0vmwkcnYI
j1oie8CDtGAfX2nqbBGkpvjJIV5EYHxRF8ChinmnK7LKbYy5jV8zjpzzaGn1NZvn
LSm7aS/V9dfXe/2LJIeo4Aa797RdBkVdy144JOFzAclavbwZO+76jiXFjvyNZour
Vq5MYMFCHwXrJIdy/MqfmZMraSuENk0mesRMJ8Z2/0dJB8P0dTsXWd1OPk/nGvdi
K/fFSWIqL5Z+xng1byTcqEJGEmfc
AQoCggEBAJb414nQftY4E/qPvoeBDWckLM3MURN8V450qxJ7/PniENOxUHTjSn6W
ocoPaxYqURdh/YF4XyKKOdwueYC5c6nJJEKSvngRSuwvdfmBRyW7+S/LQ6YOyLFM
wSUsr+okeWIIwDR+Ii92kHXLt72jNJNR3Qcb0TC/+plW5jun0zDQ3t/nW7dfgFXw
r7MOZASmQmvm4lgEbrsJyqecXiwI8hyNw2HTfCKVsqSe9uc3hRJ0+Nxbaj8ALyMn
KFIQoRYkglvFWBAAcbFZceHIyunGAOBB3bi5NTPJJJPQtLoA5lvcomrPOC+FsUpE
28sC+ohNl7sBGXpca33I5tZexPGvafECAwEAAaNTMFEwCQYDVR0TBAIwADAlBgNV
HREEHjAcggduZ2h0dHAyggdhbm90aGVygghhbm90aGVyMjAdBgNVHQ4EFgQU4fZx
m09nrI8NyXwg1n9PnUloBxkwDQYJKoZIhvcNAQELBQADggIBAL8+R+TqvRQLuape
dMR6fK8ltAXharqxwCH8tIKHSdco4d2crsVucocIvd+fspd/YQ8k6oY2oAyPvYU3
uEHpfhCG8/PRS+qYgqQo+zuyfdeoJ+ZHHYx8L2nt7bh0rlc2+fhrOXey5Gls3uYT
Yjp28AamuHtVbGMSGNZwSk7QFOGfUH+gbw8ueRc76DDRGql+N0Va8lSEnVeBpPOa
C7XimNThnxDq+QEIEgKv6O4M4MrsReqyZBaryKTdNyXSZY9Qy6IJWVBKa0Tyb5f7
7yCarezW4lH2d7iAeANegG1ks3Oe7mXvFZHdLqC8lRUmcCl3BwJHBqFAN8wiWTBS
EJ8LHIApMgdJUdZB9IrwBUE5imjeoXDLuO7G2FwLCyT7aDSDGbHUdDfuia/VeTE7
1CVpDRD7FzTAdXqTG/AGHpMlqOuACGluFVH71NA+fdqt/e7g3I3Mh8FrlKp83DP9
RADJrON1NP6EA5VMAY1TLgqHebLKyMaqHAaZcFZ2TYgJTXqyGA6vo9Hvv3+Aw//B
8pMYXWn2Y3e9OO0MZD2mF0bG3GusRCDyDdnWeuoBvgQlMA20g2ZxUHSwV8pg1Bm5
hax/n6bVnw8nn4gPbp/5ozO8efAlbqHmTg1p0FV4C73yAB2sdE2PjHFdHa1oEF/S
ozoWiHxaBHmNg3DokL8f/WhLT1QJ
-----END CERTIFICATE-----

View File

@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -22,8 +22,10 @@ module SessionWithMockResponse
@mock_responses_counter -= 1
response.status = Thread.current[:httpx_mock_response_status]
response.merge_headers(Thread.current[:httpx_mock_response_headers])
unless response.is_a?(HTTPX::ErrorResponse)
response.status = Thread.current[:httpx_mock_response_status]
response.merge_headers(Thread.current[:httpx_mock_response_headers])
end
super(request, response)
end
end

View File

@ -26,8 +26,7 @@ pagination:
include:
- wiki
exclude:
- Gemfile
- Gemfile.lock
- scripts/curl_to_ruby.js.rb
plugins:
- jekyll-gzip
- jekyll-brotli

View File

@ -1,3 +1,7 @@
.buttons {
display: block;
text-align: center;
}
.btn {
display: inline-block;
padding: 0.75em 1.25em;
@ -17,6 +21,12 @@
svg {
vertical-align: -1px;
}
&.btn-small {
background-color: green;
border-radius: 0.2em;
padding: 0 0.4em;
}
}
.badge {

View File

@ -54,13 +54,57 @@
.code-preview {
margin-bottom: 25px;
font-size: 0.7em;
code {
code, #curl-command {
border-radius: 10px;
padding: 10px;
padding: 0 10px;
font-weight: bold;
background-color: black;
color: white;
text-align: justify;
}
#curl-command:before {
content: ">";
color: white;
}
#curl-command input,
#curl-command textarea,
#curl-command pre {
background: transparent;
border: none;
font-size: 20px;
}
#curl-command input, #curl-command textarea {
padding: 10px;
width: 95%;
}
#curl-command pre {
width: 100%;
background-image: radial-gradient(
rgba(0, 70, 0, 0.75), black 120%
);
padding-top: 10px;
font-family: Inconsolata, monospace;
text-shadow: 0 0 5px #C8C8C8;
color: #87cefa;
&.error {
color: red;
}
&::selection {
background: #0080FF;
text-shadow: none;
}
}
}
.curl-widget {
margin-top: 10px;
text-align: justify;
}
@media screen and (min-width: 1000px) {

View File

@ -21,6 +21,23 @@ layout: default
HTTPX.get("https://news.ycombinator.com")
</code>
</div>
<div class="code-preview">
<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>
<div class="curl-widget">
<label for="curl-command-input">insert curl command here...</label>
<div id="curl-command">
<input id="curl-command-input" type="text" placeholder="curl http://..."/>
<pre id="curl-command-output" style="display:none"></pre>
</div>
</div>
</div>
<a class="btn" href="{{ '/posts/index.html' | prepend: site.baseurl }}">
Blog
</a>
@ -95,3 +112,4 @@ layout: default
<p>A production of <a href="{{ site.authorurl }}">HoneyryderChuck</a> and published under the <a href="{{ site.repourl | append: '/blob/master/LICENSE.txt' }}">Apache 2.0 License</a>.</p>
</div>
</footer>
<script src="{{ '/scripts/curl_to_ruby.js' | prepend: site.baseurl }}"></script>

View File

@ -0,0 +1,637 @@
require "optparse"
require "uri"
require "json"
def parse_options(command, options)
OptionParser.new do |opts|
options[:urls] = []
options[:require] = []
options[:plugins] = []
options[:plugin_options] = Hash.new { |hs, k| hs[k] = {} }
options[:options] = {
ssl: {},
timeout: {},
headers: {},
}
# opts.on("--abstract-unix-socket PATH") do |path|# TODO: Connect via abstract Unix domain socket
# end
# opts.on("--alt-svc FILE") do |path| # TODO: nable alt-svc with this cache file
# end
# opts.on("--anyauth") do # Pick any authentication method
# end
# opts.on("-a", "--append") do # Append to target file when uploading
# end
opts.on("--basic") do # Use HTTP Basic Authentication
options[:auth] = :basic_authentication
options[:auth_method] = :basic_auth
end
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}))"
end
opts.on("--capath DIR") do |path|
options[:options][:ssl][:ca_path] = path
end # CA directory to verify peer against
opts.on("-E", "--cert <certificate[:password]>") do |cert|
(options[:options][:ssl][:certificate] ||= {})[:cert] = "OpenSSL::X509::Certificate.new(File.read(#{cert.inspect}))"
end # Client certificate file and password
# opts.on("--cert-status") # Verify the status of the server certificate
# opts.on("--cert-type TYPE") # Certificate file type (DER/PEM/ENG)
opts.on("--ciphers CIPHERLIST") do |ciphers| # SSL ciphers to use
options[:options][:ssl][:ciphers] = ciphers.inspect
end
opts.on("--compressed") do
options[:plugins] << :compression
end # Request compressed response
# opts.on("--compressed-ssh") # Enable SSH compression
# opts.on("-K, --config FILE") # Read config from a file
opts.on("--connect-timeout SECS") do |timeout|
options[:options][:timeout][:connect_timeout] = Float(timeout)
end # Maximum time allowed for connection
opts.on("--connect-to HOST1:PORT1:HOST2:PORT2") do |ios| # Connect to host
options[:options][:io] = ios.split(":").each_slice(2).map{|*a|a.join(":s")}
end
opts.on("-C", "--continue-at OFFSET") # Resumed transfer offset
opts.on("-b", "--cookie DATAORFILENAME") do |cookie|
options[:options][:headers][:cookie] = cookie
end # Send cookies from string/file
# opts.on("-c", "--cookie-jar FILENAME") # TODO: Write cookies to <filename> after operation
# opts.on("--create-dirs") # Create necessary local directory hierarchy
# 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("-d", "--data DATA") do |data|
data = data.sub(/\A'(.*)'\z/, '\\1')
options[:verb] ||= :post
if data.start_with?("@")
options[:body] = "File.open(#{data[1..-1].inspect})"
else
k, v = data.split("=")
if 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 # HTTP POST data
opts.on("--data-ascii DATA") do |data|
data = data.sub(/\A'(.*)'\z/, '\\1')
options[:verb] ||= :post
if data.start_with?("@")
options[:body] = "File.open(#{data[1..-1].inspect})"
else
k, v = data.split("=")
if 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 # HTTP POST ASCII data
opts.on("--data-binary DATA") do |data|
data = data.sub(/\A'(.*)'\z/, '\\1')
options[:verb] ||= :post
if data.start_with?("@")
options[:body] = "File.open(#{data[1..-1].inspect})"
else
k, v = data.split("=")
if 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 # HTTP POST binary data
opts.on("--data-raw DATA") do |data|
options[:form] ||= []
k, v = data.split("=")
if 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
opts.on("--data-urlencode DATA") do |data|
options[:verb] ||= :post
options[:require] << "cgi"
options[:body] = "CGI.escape(#{data.inspect})"
end # HTTP POST data url encoded
# opts.on("--delegation LEVEL") # GSS-API delegation permission
opts.on("--digest") do
options[:auth] = :digest_authentication
options[:auth_method] = :digest_auth
end # Use HTTP Digest Authentication
# opts.on("-q", "--disable") # Disable .curlrc
# opts.on("--disable-eprt") # Inhibit using EPRT or LPRT
# opts.on("--disable-epsv") # Inhibit using EPSV
# opts.on("--disallow-username-in-url") # Disallow username in url
# opts.on("--dns-interface INTERFACE") # Interface to use for DNS requests
# opts.on("--dns-ipv4-addr ADDRESS") # IPv4 address to use for DNS requests
# opts.on("--dns-ipv6-addr ADDRESS") # IPv6 address to use for DNS requests
# opts.on("--dns-servers ADDRESSES") # DNS server addrs to use
opts.on("--doh-url URL") do |uri|
options[:options][:resolver_options] = { resolver_class: :https, uri: uri }
end # Resolve host names over DOH
# opts.on("-D", "--dump-header FILENAME") # Write the received headers to <filename>
# opts.on("--egd-file FILE") # EGD socket path for random data
opts.on("--expect100-timeout SECONDS") do |secs|
options[:plugins] << :expect
options[:plugin_options][:expect][:expect_timeout] = Float(secs)
end # How long to wait for 100-continue
opts.on("-f", "--fail") # Fail silently (no output at all) on HTTP errors
opts.on("--fail-early") do
options[:raise_for_status] = true
end # Fail on first transfer error, do not continue
# opts.on("--false-start") # Enable TLS False Start
opts.on("-F", "--form NAME=CONTENT") do |data|
data = URI.decode_www_form(data)
data.each do |_, val|
if val[0] = "@"
options[:plugins] << :multipart
val.replace("File.open(#{val.slice(1..-1).inspect})")
end
end
options[:verb] ||= :post
options[:form] ||= []
options[:form] += data
end # Specify multipart MIME data
opts.on("--form-string <NAME=STRING") do |data|
options[:verb] ||= :post
options[:form] ||= []
options[:form] += URI.decode_www_form(data)
end # Specify multipart MIME data
# opts.on("--ftp-account DATA") # Account data string
# opts.on("--ftp-alternative-to-user <command> String to replace USER [name]
# opts.on("--ftp-create-dirs Create the remote dirs if not present
# opts.on("--ftp-method <method> Control CWD usage
# opts.on("--ftp-pasv Use PASV/EPSV instead of PORT
# opts.on("-P, --ftp-port <address> Use PORT instead of PASV
# opts.on("--ftp-pret Send PRET before PASV
# opts.on("--ftp-skip-pasv-ip Skip the IP address for PASV
# opts.on("--ftp-ssl-ccc Send CCC after authenticating
# opts.on("--ftp-ssl-ccc-mode <active/passive> Set CCC mode
# opts.on("--ftp-ssl-control Require SSL/TLS for FTP login, clear for transfer
opts.on("-G", "--get") do
options[:verb] = :get
end # Put the post data in the URL and use GET
# opts.on("-g", "--globoff") # Disable URL sequences and ranges using {} and []
# opts.on("--happy-eyeballs-timeout-ms MILLISECONDS") # TODO: How long to wait in milliseconds for IPv6 before trying IPv4
# opts.on("--haproxy-protocol Send HAProxy PROXY protocol v1 header
opts.on("-I", "--head") do
options[:verb] = :head
options[:options][:debug_level] = 1
end # Show document info only
opts.on("-H", "--header HEADER/@FILE") do |data|
k, v = data[1..-2].split(/ *: */)
v = v.start_with?("@") ? "File.open(#{v[1..-1].inspect})" : v
options[:options][:headers][k.downcase] = v
end # Pass custom header(s) to server
# opts.on("-h, --help This help text
# opts.on("--hostpubmd5 <md5> Acceptable MD5 hash of the host public key
# opts.on("--http0.9 Allow HTTP 0.9 responses
# opts.on("-0, --http1.0 Use HTTP 1.0
opts.on("--http1.1") do
options[:options][:ssl][:alpn_protocols] = %w[http/1.1]
end # Use HTTP 1.1
opts.on("--http2") do
options[:plugins] << :h2c
end # Use HTTP 2
opts.on("--http2-prior-knowledge") do
options[:options][:fallback_protocol] = "h2"
end # Use HTTP 2 without HTTP/1.1 Upgrade
# opts.on("--ignore-content-length") # TODO: Ignore the size of the remote resource
# opts.on("-i", "--include") # TODO: Include protocol response headers in the output
opts.on("-k", "--insecure") do
options[:options][:ssl][:verify_mode] = "OpenSSL::SSL::VERIFY_NONE"
end # Allow insecure server connections when using SSL
# opts.on("--interface NAME") # Use network INTERFACE (or address)
opts.on("-4", "--ipv4") do
options[:options][:ip_families] = "Socket::AF_INET"
end # Resolve names to IPv4 addresses
opts.on("-6", "--ipv6") do
options[:options][:ip_families] = "Socket::AF_INET6"
end # Resolve names to IPv6 addresses
# opts.on("-j", "--junk-session-cookies") # Ignore session cookies read from file
opts.on("--keepalive-time SECONDS", Integer) do |timeout|
options[:options][:timeout][:keepalive_timeout] = timeout
end # Interval time for keepalive probes
opts.on("--key KEY") do |key|
(options[:options][:ssl][:certificate] ||= {})[:key] = OpenSSL::PKey::PKey.new(File.read(key))
end # Private key file name
# opts.on("--key-type TYPE") # Private key file type (DER/PEM/ENG)
# opts.on("--krb <level> Enable Kerberos with security <level>
# opts.on("--libcurl <file> Dump libcurl equivalent code of this command line
# opts.on("--limit-rate <speed> Limit transfer speed to RATE
# opts.on("-l, --list-only List only mode
# opts.on("--local-port <num/range> Force use of RANGE for local port numbers
opts.on("-L", "--location") do
options[:plugins] << :follow_redirects
end # Follow redirects
# opts.on("--location-trusted") # TODO: Like --location, and send auth to other hosts
# opts.on("--login-options <options> Server login options
# opts.on("--mail-auth <address> Originator address of the original email
# opts.on("--mail-from <address> Mail from this address
# opts.on("--mail-rcpt <address> Mail to this address
# opts.on("-M, --manual Display the full manual
opts.on("--max-filesize BYTES") # Maximum file size to download
opts.on("--max-redirs NUM", Integer) do |max|
options[:plugins] << :retries
options[:plugin_options][:retries][:max_retries] = max
end # Maximum number of redirects allowed
# opts.on("-m", "--max-time SECONDS") # TODO: Maximum time allowed for the transfer
# opts.on("--metalink Process given URLs as metalink XML file
opts.on("--negotiate") do
options[:auth] = :ntlm_authentication
end # Use HTTP Negotiate (SPNEGO) authentication
# opts.on("-n, --netrc Must read .netrc for user name and password
# opts.on("--netrc-file <filename> Specify FILE for netrc
# opts.on("--netrc-optional Use either .netrc or URL
# opts.on("-:, --next Make next URL use its separate set of options
opts.on("--no-alpn") do # Disable the ALPN TLS extension
options[:options][:ssl][:alpn_protocols] = []
end
# opts.on("-N, --no-buffer Disable buffering of the output stream
# opts.on("--no-keepalive") # TODO: Disable TCP keepalive on the connection
# opts.on("--no-npn Disable the NPN TLS extension
# opts.on("--no-sessionid") # Disable SSL session-ID reusing
opts.on("--noproxy NOPROXYLIST") # List of hosts which do not use proxy
opts.on("--ntlm") do
options[:plugins] << :ntlm_authentication
end # Use HTTP NTLM authentication
# opts.on("--ntlm-wb") # Use HTTP NTLM authentication with winbind
opts.on("--oauth2-bearer TOKEN") do |token|
options[:options][:headers]["authorization"] = "Bearer #{token}"
end # OAuth 2 Bearer Token
opts.on("-o", "--output FILE") do |path|
options[:copy_to] = path
end # Write to file instead of stdout
opts.on("--pass PHRASE") do |pass|
if !options.key?(:auth)
options[:auth] = :basic_authentication
options[:auth_method] = :basic_auth
end
options[:password] = pass
end# Pass phrase for the private key
# opts.on("--path-as-is Do not squash .. sequences in URL path
# opts.on("--pinnedpubkey <hashes> FILE/HASHES Public key to verify peer against
opts.on("--post301") # Do not switch to GET after following a 301
opts.on("--post302") # Do not switch to GET after following a 302
opts.on("--post303") # Do not switch to GET after following a 303
# opts.on("--preproxy [protocol://]host[:port] Use this proxy first
# opts.on("-#, --progress-bar Display transfer progress as a bar
# opts.on("--proto <protocols> Enable/disable PROTOCOLS
# opts.on("--proto-default <protocol> Use PROTOCOL for any URL missing a scheme
# opts.on("--proto-redir <protocols> Enable/disable PROTOCOLS on redirect
opts.on("-x", "--proxy [protocol://]host[:port]") do |proxy|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:uri] = proxy
end # Use this proxy
# opts.on("--proxy-anyauth Pick any proxy authentication method
opts.on("--proxy-basic") do
options[:plugins] << :proxy
options[:plugin_options][:proxy][:authentication] = :basic
end # Use Basic authentication on the proxy
# opts.on("--proxy-cacert <file> CA certificate to verify peer against for proxy
# opts.on("--proxy-capath <dir> CA directory to verify peer against for proxy
# opts.on("--proxy-cert <cert[:passwd]> Set client certificate for proxy
# opts.on("--proxy-cert-type <type> Client certificate type for HTTPS proxy
# opts.on("--proxy-ciphers <list> SSL ciphers to use for proxy
# opts.on("--proxy-crlfile <file> Set a CRL list for proxy
# opts.on("--proxy-digest Use Digest authentication on the proxy
opts.on("--proxy-header <header/@file>") do |header|
end # Pass custom header(s) to proxy
opts.on("--proxy-insecure") # Do HTTPS proxy connections without verifying the proxy
opts.on("--proxy-key <key>") # Private key for HTTPS proxy
opts.on("--proxy-key-type <type>") # Private key file type for proxy
opts.on("--proxy-negotiate") # Use HTTP Negotiate (SPNEGO) authentication on the proxy
opts.on("--proxy-ntlm") # Use NTLM authentication on the proxy
opts.on("--proxy-pass <phrase>") do |pass|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:password] = pass
end # Pass phrase for the private key for HTTPS proxy
# opts.on("--proxy-pinnedpubkey <hashes> FILE/HASHES public key to verify proxy with
# opts.on("--proxy-service-name <name> SPNEGO proxy service name
# opts.on("--proxy-ssl-allow-beast Allow security flaw for interop for HTTPS proxy
# opts.on("--proxy-tls13-ciphers <ciphersuite list> TLS 1.3 proxy cipher suites
# opts.on("--proxy-tlsauthtype <type> TLS authentication type for HTTPS proxy
# opts.on("--proxy-tlspassword <string> TLS password for HTTPS proxy
# opts.on("--proxy-tlsuser <name> TLS username for HTTPS proxy
# opts.on("--proxy-tlsv1 Use TLSv1 for HTTPS proxy
opts.on("-U", "--proxy-user <user:password>") do |user|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:username] = user
end # Proxy user and password
# opts.on("--proxy1.0 <host[:port]> Use HTTP/1.0 proxy on given port
# opts.on("-p", "--proxytunnel") Operate through an HTTP proxy tunnel (using CONNECT)
# opts.on("--pubkey <key> SSH Public key file name
# opts.on("-Q, --quote Send command(s) to server before transfer
# opts.on("--random-file <file> File for reading random data from
opts.on("-r", "--range RANGE") # Retrieve only the bytes within RANGE
opts.on("--raw") # Do HTTP "raw"; no transfer decoding
opts.on("-e", "--referer URL") do |url|
options[:options][:headers]["referer"] = url
end # Referrer URL
# opts.on("-J", "--remote-header-name Use the header-provided filename
# opts.on("-O, --remote-name Write output to a file named as the remote file
# opts.on("--remote-name-all Use the remote file name for all URLs
# opts.on("-R, --remote-time Set the remote file's time on the local output
opts.on("-X", "--request <command>") do |verb|
options[:verb] = verb.downcase.to_sym
end # Specify request command to use
# opts.on("--request-target Specify the target for this request
opts.on("--resolve <host:port:address[,address]...>") # Resolve the host+port to this address
opts.on("--retry <num>", Integer) do |num|
options[:plugins] << :retries
# options[:options]
end # Retry request if transient problems occur
opts.on("--retry-connrefused") # Retry on connection refused (use with --retry)
opts.on("--retry-delay <seconds>", Integer) do |delay|
options[:plugins] << :retries
options[:plugin_options][:retries][:retry_after] = delay
end # Wait time between retries
# opts.on("--retry-max-time <seconds> Retry only within this period
# opts.on("--sasl-ir Enable initial response in SASL authentication
# opts.on("--service-name <name> SPNEGO service name
# opts.on("-S, --show-error Show error even when -s is used
# opts.on("-s, --silent Silent mode
opts.on("--socks4 <host[:port]>") do |socks_authority|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:uri] = "socks4://#{socks_authority}"
end # SOCKS4 proxy on given host + port
opts.on("--socks4a <host[:port]>") do |socks_authority|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:uri] = "socks4a://#{socks_authority}"
end # SOCKS4a proxy on given host + port
opts.on("--socks5 <host[:port]>") do |socks_authority|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:uri] = "socks5://#{socks_authority}"
end # SOCKS5 proxy on given host + port
opts.on("--socks5-basic") do |pass|
options[:plugins] << :proxy
options[:plugin_options][:proxy][:password] = pass
end # Enable username/password auth for SOCKS5 proxies
# opts.on("--socks5-gssapi Enable GSS-API auth for SOCKS5 proxies
# opts.on("--socks5-gssapi-nec Compatibility with NEC SOCKS5 server
# opts.on("--socks5-gssapi-service <name> SOCKS5 proxy service name for GSS-API
opts.on("--socks5-hostname <host[:port]>") # SOCKS5 proxy, pass host name to proxy
# opts.on("-Y, --speed-limit <speed> Stop transfers slower than this
# opts.on("-y, --speed-time <seconds> Trigger 'speed-limit' abort after this time
# opts.on("--ssl Try SSL/TLS
# opts.on("--ssl-allow-beast Allow security flaw to improve interop
# opts.on("--ssl-no-revoke Disable cert revocation checks (Schannel)
# opts.on("--ssl-reqd Require SSL/TLS
opts.on("-2", "--sslv2") do
options[:options][:ssl][:min_version] = ":SSL2"
end # Use SSLv2
opts.on("-3", "--sslv3") do
options[:options][:ssl][:min_version] = ":SSL3"
end # Use SSLv3
opts.on("--stderr") # Where to redirect stderr
# opts.on("--styled-output Enable styled output for HTTP headers
# opts.on("--suppress-connect-headers Suppress proxy CONNECT response headers
# opts.on("--tcp-fastopen Use TCP Fast Open
# opts.on("--tcp-nodelay Use the TCP_NODELAY option
# opts.on("-t, --telnet-option <opt=val> Set telnet option
# opts.on("--tftp-blksize <value> Set TFTP BLKSIZE option
# opts.on("--tftp-no-options Do not send any TFTP options
# opts.on("-z, --time-cond <time> Transfer based on a time condition
opts.on("--tls-max <VERSION>") do |version|
options[:options][:ssl][:max_version] = version.sub("v", "").sub(".", "_").upcase.to_sym
end # Set maximum allowed TLS version
# opts.on("--tls13-ciphers <list of TLS 1.3 ciphersuites> TLS 1.3 cipher suites to use
# opts.on("--tlsauthtype <type> TLS authentication type
# opts.on("--tlspassword TLS password
# opts.on("--tlsuser <name> TLS user name
opts.on("-1", "--tlsv1") do
options[:options][:ssl][:min_version] = ":TLS1_0"
end # Use TLSv1.0 or greater
opts.on("--tlsv1.0") do
options[:options][:ssl][:min_version] = ":TLS1_0"
end # Use TLSv1.0 or greater
opts.on("--tlsv1.1") do
options[:options][:ssl][:min_version] = ":TLS1_1"
end # Use TLSv1.1 or greater
opts.on("--tlsv1.2") do
options[:options][:ssl][:min_version] = ":TLS1_2"
end # Use TLSv1.2 or greater
opts.on("--tlsv1.3") do
options[:options][:ssl][:min_version] = ":TLS1_3"
end # Use TLSv1.3 or greater
opts.on("--tr-encoding") # Request compressed transfer encoding
# opts.on("--trace <file> Write a debug trace to FILE
# opts.on("--trace-ascii <file> Like --trace, but without hex output
# opts.on("--trace-time Add time stamps to trace/verbose output
opts.on("--unix-socket <path>") do |path|
options[:options][:transport] = :unix
options[:options][:addresses] = [path]
end # Connect through this Unix domain socket
opts.on("-T", "--upload-file <file>") do |path|
options[:verb] = :put
options[:body] = Pathname.open(path)
end # Transfer local FILE to destination
opts.on("--url <url>") do |url|
options[:urls] << url
end # URL to work with
opts.on("-B", "--use-ascii") # Use ASCII/text transfer
opts.on("-u <user:password>", "--user <user:password>") do |user_pass|
if !options.key?(:auth)
options[:auth] = :basic_authentication
options[:auth_method] = :basic_auth
end
user, pass = user_pass.sub(/\A"(.*)"\z/, '\\1').split(":")
options[:username] = user
options[:password] = pass
end # Server user and password
opts.on("-A", "--user-agent <name>") do |uagent|
options[:options][:headers]["user-agent"] = uagent
end # Send User-Agent <name> to server
opts.on("-v", "--verbose") do
options[:options][:debug_level] = 2
end # Make the operation more talkative
# opts.on("-V", "--version") # Show version number and quit
# opts.on("-w", "--write-out <format> Use output FORMAT after completion
# opts.on("--xattr Store metadata in extended file attributes
end.parse(command)
end
def to_ruby(urls, options)
template = <<-HTTPX.slice(0..-2)
require "httpx"
HTTPX
# load extra deps
options[:require].uniq.each do |lib|
template.prepend("require \"#{lib}\"\n")
end
if options[:options][:headers]["content-type"] == "application/json" && options.key?(:body)
begin
options[:json] = JSON.parse(options[:body])
options.delete(:body)
options[:options][:headers].delete("content-type")
rescue JSON::ParserError
end
end
# handle general options
with_options = options[:options].map do |k, v|
next if %i[body form json].include?(k)
unless v.respond_to?(:empty?) && v.empty?
v = case k
when :ssl, :timeout
vstr = "{"
vstr += v.map do |sk, sv|
" #{sk}: #{sv}"
end.join(",")
vstr += " }"
vstr
# when :headers
else
v.inspect
end
"#{k}: #{v}"
end
end.compact
if (http_custom = !options[:plugins].empty? || options[:auth] || !with_options.empty?)
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}"
end
template += ")\n\t"
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
template += "\nresponse = "
template += http_custom ? "http" : "HTTPX"
template += ".#{options.fetch(:verb, :get)}("
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
if options.key?(:body)
template += ", body: #{options[:body]}"
elsif options.key?(:json)
template += ", json: #{options[:json]}"
elsif options.key?(:form)
template += ", form: {"
template += options[:form].map do |k, v|
"#{k.inspect} => #{v.inspect}"
end.join(", ")
template += "}"
end
template += ")\n"
template += "response.raise_for_status\n" if options[:raise_for_status]
template += "puts response.to_s"
template
end
def to_httpx
on_txt_change = lambda do |evt|
command = `#{evt}.target.value`
unless command.start_with?("curl ")
`document.getElementById('curl-command-output').style.display = "none"`
return
end
%x{
var output = document.getElementById('curl-command-output');
output.classList.remove("error");
}
begin
options = {}
urls = parse_options(command.slice(5..-1).scan(/"[^"]+"|'[^']+'|\S+/), options)
result = to_ruby(urls, options)
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument => error
result = error.message
result.sub("invalid", "unsupported")
`output.classList.add("error")`
end
%x{
output.innerHTML = #{result};
output.style.display = "block";
}
end
%x{
var input = document.getElementById('curl-command-input');
input.addEventListener('input', on_txt_change, false);
input.addEventListener('change', on_txt_change, false);
}
end
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__
# command = ARGV.first
# return unless command.start_with?("curl ")
# options = {}
# urls = parse_options(command.slice(5..-1).split(/ +/), options)
# puts to_ruby(urls, options)
# end