ducaale / xh Goto Github PK
View Code? Open in Web Editor NEWFriendly and fast tool for sending HTTP requests
License: MIT License
Friendly and fast tool for sending HTTP requests
License: MIT License
Would a PR for .netrc
support be accepted? If so I'll take a stab at it this weekend :)
This could be useful if we decide to have an online playground like jqplay.
We would like to remove the HTTPie clone
part in our tagline or reword it. I propose that we use something similar to the one used inside src/cli.rs
.
Friendly and fast tool for sending HTTP requests
These are the places that would need updating after we agree on what tagline to use:
Cargo.toml
and generate.sh
.When doing ht -h it displays the help instead of doing a HEAD request.
I don't know if it's supported by httpie
, but I think it's a valid use case. Basically when requesting with JSON body, one do it like this:
ht -j -v put https://httpbin.org/put SingleLine=my_string
PUT /put HTTP/1.1
accept: application/json, */*
accept-encoding: gzip, deflate
connection: keep-alive
content-length: 26
content-type: application/json
host: httpbin.org
{
"SingleLine": "my_string"
}
HTTP/2.0 200 OK
access-control-allow-credentials: true
access-control-allow-origin: *
content-length: 474
content-type: application/json
date: Tue, 09 Feb 2021 06:53:46 GMT
server: gunicorn/19.9.0
{
"args": {},
"data": "{\"SingleLine\":\"my_string\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json, */*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "26",
"Content-Type": "application/json",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-6022317a-<removed>"
},
"json": {
"SingleLine": "my_string"
},
"origin": "<removed>",
"url": "https://httpbin.org/put"
}
That worked flawlessly, and I really like the way JSON body was constructed by using separated key-value pairs, it's much easy to write, and easier to type without typo.
But when one of the values contains multiple lines, ht
is not happy:
ht -j -v put https://httpbin.org/put SingleLine=my_string MultiLine=my\nstring
error: Invalid value for '<REQUEST_ITEM>...': error: "MultiLine=my\nstring" is not a valid value
This happens with ht 0.5.0
which is the latest version. I know for httpie
you can pipe raw JSON data into it so any form of data is supported, but simple key-value construction is just so much better. Will ht
support this?
The document suggest an auth
argument, but I'm not sure what they are.
HTTPie allows omitting HTTP methods in which case it will default to GET
if the body is empty or to POST
otherwise.
http :8080/users # will be translated to `http get :8080/users`
http :8080/users name=ali # will be translated to `http post :8080/users name=ali`
This should be possible when clap-rs/clap#2122 gets addressed.
This is an httpbin.org clone in Rust https://github.com/svartalf/actix-httpbin
Hello,
➜ ~ ht get https://google.com
HTTP/2.0 400 Bad Request
content-length: 1555
content-type: text/html; charset=UTF-8
date: Sun, 07 Feb 2021 01:19:14 GMT
referrer-policy: no-referrer
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Body, source: hyper::Error(Body, Error { kind: Proto(PROTOCOL_ERROR) }) }', src/printer.rs:208:79
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
➜ ~ ht get http://google.com
Error: reqwest::Error { kind: Redirect, url: Url { scheme: "http", host: Some(Domain("www.google.com")), port: None, path: "/", query: None, fragment: None }, source: TooManyRedirects }
Environment
MacOS - 10.15
I have always preferred httpie
but as I have to often run same command on remote servers/docker for debugging. Sometimes I also pass these commands to colleagues, who might have liking for different tool (curl being most popular choice). It happens the other way too when I get curl commands.
I'm sure this would resonant with people who access multiple systems throughout the day.
It would be a great addition if this tool could have an option to print equivalent curl command and exit without making request. Even greater if it could do the reverse too.
And thanks for rewriting httpie in rust.
We should disable the coloring if NO_COLOR
is set. We might also want to control it via the --pretty
flag but that might be a bit tricky since that flag only takes into account stdout output while progress indicators use stderr for their output.
An interesting thing to note is that progress indicator colors do not suffer from issue #98.
Clap-rs by convention uses -h for short documentation and --help for the detailed form. Unfortunately, the -h flag has now been taken by --header which means there is no way for users to access the condensed form of xh
docs.
I was made aware [1] the name Yahc might be confused with a rust community member who goes by the name Yaahc. Therefore I am planning to rename this project using one of the following:
-rs
at the end to avoid a name clash.It would be great to add a note to the readme to explain why this project exists and why someone might want to choose it over HTTPie. This could also include any points where xh deliberately differs from HTTPie in behaviour/syntax.
Even if the answer is "because I felt like making it" (which is a perfectly valid reason!), I still think it would be valuable to have it written down.
HTTPie has an option to force TLS version. I think it would be useful if xh also has this.
see also: HTTPie documentation
I have a plethora of great statically linked binary installs in Linux (Ubuntu). These include ripgrep
, exa
, bat
, fd
etc. None shines as well as chezmoi
when it comes to the one-line installer.
I recommend to implement a one-line binary installer to follow that of chezmoi
. See this documentation: https://github.com/twpayne/chezmoi/blob/master/docs/INSTALL.md#one-line-binary-install
In effect, what it does, is to download the latest statically linked binary for your operating system and architecture into ./bin
This means I can put myself in whatever dir I want and just call the installer and it will be installed into the bin path of my choosing. Be that ~/bin
or .local/bin
or whatever I prefer.
Hey, I think it'd be neat if the user could choose between using rustls or OpenSSL. For instance, I do sometimes have the requirement to use either one or the other and if xh supported that it'd be pretty good. I'm not sure whether it'd be a compile-time switch or a runtime one as linking to OpenSSL at all times would decrease the nice portability of xh which I do value.
Perhaps allow the user to add OpenSSL support during compile time? Then distro packagers could choose to ship a xh supporting both versions while you still keep building the static builds with only rustls.
I imagine building this would enable a flag --native-tls
which would then internally switch TLS calls to the linked OpenSSL.
Use cases:
What do you think?
This is a broad, open-ended question. When I'm using a tool like ht
with an API that requires authentication and several headers, I find myself struggling to manage that state. My best answer is I set environment variables that I use in the URL for the authentication, frequently go back in the shell history to edit URLs etc. If there is a cookie needed it's even more complicated. Same goes for setting non-standard headers.
GUI tools like Insomnia allow managing this in projects which reduces this pain, but requires using a GUI for a task that's (in my experience) a better fit for the terminal.
So here is my question. Is there a reasonable way to implement some kind support for stateful sessions in ht, that's perhaps applied and mutated automatically when found in the current dir? (a bit like a browser). For example:
# .ht.session
base_url: "https://my-test-api.com/api
headers:
Content-Type: "application/json"
X-My-Specific-Header: "That value"
auth:
token: "Bearer d2h5IHdvdWxkIHlvdSB0YWtlIHRoZSB0aW1lIHRvIGRlY29kZSB0aGlz"
and then used like:
$ ht get /v2/user
Using .ht.session
... dump user json ...
The above a very raw demonstration that hopefully communicates the idea - not the concrete proposal itself.
There is of course a fine balance between explicitness and ease of use. Hiding too much information can lead to surprising behavior. But I still feel there could be a reasonable middle ground. Any thoughts?
Dear @ducaale, could you be so kind to tell what is the xh
equivalent of the following curl
command to upload a file?
$ curl.exe -F [email protected] https://transfer.sh/
This should help us avoid encounters with non-deterministic test failure during releases. See how it is done in ripgrep
It seem that ht does not provide content-length header in http POST. It will result in errors. Examples are listed below.
❯ ht post pb.mgt.moe -f [email protected] --verbose
POST / HTTP/1.1
accept: */*
accept-encoding: gzip, deflate
connection: keep-alive
content-type: multipart/form-data; boundary=88ddf3abad0728f1-290fb9c86111357f-23e2e46e8a5ed38e-0582e206d0c93f3d
host: pb.mgt.moe
+--------------------------------------------+
| NOTE: multipart data not shown in terminal |
+--------------------------------------------+
HTTP/1.1 411 Length Required
connection: keep-alive
content-length: 35
content-type: text/plain; charset=utf-8
date: Sun, 07 Feb 2021 01:46:53 GMT
keep-alive: timeout=4
proxy-connection: keep-alive
server: Caddy
A content-length header is required⏎
Same function with curl
curl:
❯ cat ./test.cxx | curl -F c=@- https://pb.mgt.moe -v
* Uses proxy env variable https_proxy == 'http://127.0.0.1:1080'
* Trying 127.0.0.1:1080...
* Connected to 127.0.0.1 (127.0.0.1) port 1080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to pb.mgt.moe:443
> CONNECT pb.mgt.moe:443 HTTP/1.1
> Host: pb.mgt.moe:443
> User-Agent: curl/7.75.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=pb.mgt.moe
* start date: Dec 31 05:40:41 2020 GMT
* expire date: Mar 31 05:40:41 2021 GMT
* subjectAltName: host "pb.mgt.moe" matched cert's "pb.mgt.moe"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55b9e951e640)
> POST / HTTP/2
> Host: pb.mgt.moe
> user-agent: curl/7.75.0
> accept: */*
> content-length: 248
> content-type: multipart/form-data; boundary=------------------------a3d95940aa84134e
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200
< content-type: text/plain; charset=utf-8
< date: Sun, 07 Feb 2021 01:48:33 GMT
< server: Caddy
< content-length: 221
<
date: 2021-02-07 01:48:33.179267152 UTC
digest: a0efb408dd0568dafacbb17f6cdef5551b70647a3fbeda995e00fb61a818751d
short: 7bl3
size: 98
url: http://pb.mgt.moe/7bl3
status: existed
uuid: 202dc5a8-26a1-438a-815c-d322c4907507
* Connection #0 to host 127.0.0.1 left intact
I love this tool! thanks for working on this!
every time I see a release I am happy but then its super hard to figure out what actually changed.
do you consider starting a changelog?
$ xh
error: The following required arguments were not provided:
<[METHOD] URL>
USAGE:
xh.exe <[METHOD] URL> --verify <VERIFY>
For more information try --help
curl
gives the expected response, whilst ht
does not.
$ curl -i http://chaz6.com
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sat, 06 Feb 2021 12:42:53 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://chaz6.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
$ ht get http://chaz6.com
HTTP/2.0 400 Bad Request
content-length: 150
content-type: text/html
date: Sat, 06 Feb 2021 12:41:40 GMT
server: nginx
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Hi,
I'm passing a query parameter of the form geometry=POINT(1 2)
to a request :
ht post ".../api/...doStuff?exporttype=legacy&geometry=POINT(1 2)" <<< "[]"
please note the request is within double quotes
Using ht
version 3.5.0
, my app receives POINT(1
as the value of parameter geometry
A newline is inserted every 8192 characters of output. It may land in the middle of a json value, causing the output to be invalid as json.
Regardless, this is super stuff. Kudos!!!
Hey, cool tool. :)
I noticed that downloading is pretty slow as compared to wget
. For instance, on downloading a random large file, using ht -d
I get 7-13MB/s on repeated tests while using wget
I get a good 60MB/s (my full connection speed). Any idea?
Sorry I can't be more specific but literally all I do is a multi-run test of a 2-5GB-sized file between wget
and ht -d
.
This would allow anyone with a Unix-like machine to install xh
effortlessly
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/ducaale/xh/master/install.sh | sh
See the https://github.com/ajeetdsouza/zoxide/blob/main/install.sh
$ xh httpbin.org/json -d
$ xh httpbin.org/json -d
$ ls
json.json
json-1.json
$ ls
json.json
json.json-1
When supplying a JSON body to a request it might be a good idea to set the the HTTP Accept
header (to application/json
) so that well behaved web-servers will respond with errors in JSON instead of HTML.
Alternately there could be a method to manually set the Accept
header like the -H
option to curl
.
The only useful use of --default-scheme
is --default-scheme=https
(http
is the default, other schemes don't work). Maybe it should be replaced by a --https
flag?
We could keep --default-scheme
as a deprecated hidden flag.
I have looked at how bat release artifact is structured (ripgrep should have a similar structure)
$ wget https://github.com/sharkdp/bat/releases/download/v0.17.1/bat-v0.17.1-x86_64-apple-darwin.tar.gz
$ tar xvzf bat-v0.17.1-x86_64-apple-darwin.tar.gz
$ tree bat-v0.17.1-x86_64-apple-darwin
bat-v0.17.1-x86_64-apple-darwin
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── autocomplete
│ ├── bat.fish
│ └── bat.zsh
├── bat
└── bat.1
The main difference they have with xh
is:
README.md
, LICENSE.md
, autocompletion, and a manpage fileApart from updating .github\workflows\CI.yaml
, we would need to update places where xh
is published i.e Homebrew, Scoop, etc.
Ups?!
% ht -V
ht 0.3.5
% RUST_BACKTRACE=full ht get https://google.de
HTTP/2.0 400 Bad Request
content-length: 1555
content-type: text/html; charset=UTF-8
date: Sat, 06 Feb 2021 01:51:40 GMT
referrer-policy: no-referrer
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Body, source: hyper::Error(Body, Error { kind: Proto(PROTOCOL_ERROR) }) }', src/printer.rs:208:79
stack backtrace:
0: 0x10cc13104 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha0848bb2602b5d05
1: 0x10cc31b20 - core::fmt::write::h9f3ccac2ef682b93
2: 0x10cc0cc86 - std::io::Write::write_fmt::h0a47673aab280496
3: 0x10cc14ee9 - std::panicking::default_hook::{{closure}}::h850c6aaf5e80c2f5
4: 0x10cc14bad - std::panicking::default_hook::h037801299da6e1c6
5: 0x10cc1556b - std::panicking::rust_panic_with_hook::h76436d4cf7a368ac
6: 0x10cc15095 - std::panicking::begin_panic_handler::{{closure}}::h516c76d70abf04f6
7: 0x10cc13578 - std::sys_common::backtrace::__rust_end_short_backtrace::h653290b4f930faed
8: 0x10cc14ffa - _rust_begin_unwind
9: 0x10cc44d5f - core::panicking::panic_fmt::hde9134dd19c9a74f
10: 0x10cc44c65 - core::result::unwrap_failed::hcef4aa8b48b8f381
11: 0x10c85639e - ht::main::{{closure}}::he3ac16d2a9991dec
12: 0x10c8410cf - std::thread::local::LocalKey<T>::with::he4e6385d82693aed
13: 0x10c868df7 - tokio::runtime::enter::Enter::block_on::ha21fbfb709a85010
14: 0x10c87d6bb - tokio::runtime::thread_pool::ThreadPool::block_on::h85096403de5f2e48
15: 0x10c834583 - tokio::runtime::Runtime::block_on::hcb3032661041b561
16: 0x10c869b94 - ht::main::h1c0bf400bc026e2c
17: 0x10c878dea - std::sys_common::backtrace::__rust_begin_short_backtrace::h23c3e2aace5f6064
18: 0x10c879371 - std::rt::lang_start::{{closure}}::h61625dd6a2f250f3
19: 0x10cc158e4 - std::rt::lang_start_internal::h36ccce6e8a047133
20: 0x10c869c79 - _main
It would be nice to expose a library interface, to enable projects to build on top of xh
along the lines of http-prompt. It would also help with #88.
This could be a pretty big change. We'd have to decide what to expose and commit to not breaking compatibility. Refactoring would become harder the more we expose.
Some concrete steps would be:
main
pub
to pub(crate)
#[non_exhaustive]
to certain public enumsanyhow
It could help to have a consuming project that lives in the same repository (in a workspace).
At first glance, we might not have to expose that much, see how http-prompt calls it. But I haven't looked at other projects, and a richer API might be a lot more convenient.
Breaking the public interface after 1.0 would mean incrementing the major version number. I can think of a few approaches:
xh_core
) that can increment its major version freely, while the xh
package becomes a wrapper around it with more conservative versioning.Hey, I really like this tool and use it quite a bit for debugging. As such, I sometimes need to specifically request a certain version of HTTP from a server. Could you add a mode to force the HTTP version? Curl has --http1.0
, --http1.1
, --http2
, --http3
and I think that makes sense.
Please consider adding those flags.
Just tried running ht https://www.google.com
, and got an error
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Body, source: hyper::Error(Body, Error { kind: Proto(PROTOCOL_ERROR) }) }'
Also tried on another website and got
Custom { kind: InvalidData, error: PeerMisbehavedError("received unadvertised sig scheme RSA_PKCS1_SHA1") }
After recompiling with reqwests's default feature "deafult-tls", both websites worked fine.
Although build.rs
cannot import modules from xh
, it is possible to use the include!()
to paste the content of src/cli.rs
into build.rs
.
See httpie/cli#78
HTTPie lets you negate flags, e.g. --no-check-status
cancels out --check-status
. While argparse
has optional support for that, HTTPie does it by manually processing arguments argparse
didn't recognize (plus a few hardcoded cases).
clap
doesn't support this, but there's an issue for it (clap-rs/clap#815). It also has an escape hatch for looking at unknown arguments, but I don't know exactly how powerful it is, and I'm worried it would degrade the usual error message.
A downside of HTTPie's current approach (and probably of the escape hatch approach for clap
) is that the order of the flags doesn't matter. Normally the last flag counts, so --form --json
works like --json
and --json --form
like --form
, but --no-check-status
always overrides --check-status
, even if it comes first. But that's acceptable, since the typical usage would be to add --no-check-status
after an alias that includes --check-status
, and the opposite wouldn't come up because there's little reason to use --no-check-status
in an alias.
If this is added to clap
it might take a long time before it's usable in xh
. It'd land in version 3.0.0, and then after that we might have to wait for structopt
to support it (or maybe switch to clap_derive
).
=@
and :=@
as seperators in request data.==@
and :@
for reading query string and header values from a file (#288)key@file_name;type=file_type
.--response-charset
and --response-mime
flags. (#184)--raw
flag (#202)HEAD
HTTP method.--all
flag for printing intermediary requests/responses. (#137)--history-print
. (#137)--timeout
flag.--path-as-is
flag--compress
flag.--chunked
flag.-vv
/--meta
flags. (#240)In httpie, redirect outputs are much clearer, and also don't cause the program to return an error status:
$ http google.com
HTTP/1.1 301 Moved Permanently
Cache-Control: public, max-age=2592000
Content-Length: 219
Content-Type: text/html; charset=UTF-8
Date: Sun, 07 Feb 2021 08:12:48 GMT
Expires: Tue, 09 Mar 2021 08:12:48 GMT
Location: http://www.google.com/
Server: gws
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
$ echo $?
0
On ht, on the other hand, this is not the case:
$ ht -v google.com
GET / HTTP/1.1
accept: */*
accept-encoding: gzip, deflate
connection: keep-alive
host: google.com
Error: reqwest::Error { kind: Redirect, url: Url { scheme: "http", host: Some(Domain("www.google.com")), port: None, path: "/", query: None, fragment: None }, source: TooManyRedirects }
$ echo $?
1
Httpie's handling of this case is obviously better in terms of output readability, but IMO also with regards to program success - someone wanting to GET
a resource either wants to succeed on a redirect response or follow the redirect optionally (similar to curl --fail
behavior)
Thanks for this, it's dramatically faster than the original when pretty printing big JSON responses!
When piping to head
or less
I'm seeing a broken pipe-related panic when the pager exits. Seems likely to be related to this? rust-lang/rust#46016
Reproducing it requires a response of sufficient length:
22:02:25 ~ > RUST_BACKTRACE=1 ht get 'http://httpbin.org/stream/150' | head
{"url": "http://httpbin.org/stream/150", "args": {}, "headers": {"Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-601e06c4-02a347b5507c64fe408cf5b6", "Accept-Encoding": "gzip, deflate", "Accept": "*/*"}, "origin": "104.162.100.223", "id": 0}
{"url": "http://httpbin.org/stream/150", "args": {}, "headers": {"Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-601e06c4-02a347b5507c64fe408cf5b6", "Accept-Encoding": "gzip, deflate", "Accept": "*/*"}, "origin": "104.162.100.223", "id": 1}
{"url": "http://httpbin.org/stream/150", "args": {}, "headers": {"Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-601e06c4-02a347b5507c64fe408cf5b6", "Accept-Encoding": "gzip, deflate", "Accept": "*/*"}, "origin": "104.162.100.223", "id": 2}
{"url": "http://httpbin.org/stream/150", "args": {}, "headers": {"Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-601e06c4-02a347b5507c64fe408cf5b6", "Accept-Encoding": "gzip, deflate", "Accept": "*/*"}, "origin": "104.162.100.223", "id": 3}
{"url": "http://httpbin.org/stream/150", "args": {}, "headers": {"Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-601e06c4-02a347b5507c64fe408cf5b6", "Accept-Encoding": "gzip, deflate", "Accept": "*/*"}, "origin": "104.162.100.223", "id": 4}
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:895:9
stack backtrace:
0: rust_begin_unwind
at /build/rustc-71Ymwo/rustc-1.47.0+dfsg1+llvm/library/std/src/panicking.rs:475
1: std::panicking::begin_panic_fmt
at /build/rustc-71Ymwo/rustc-1.47.0+dfsg1+llvm/library/std/src/panicking.rs:429
2: std::io::stdio::print_to
at /build/rustc-71Ymwo/rustc-1.47.0+dfsg1+llvm/library/std/src/io/stdio.rs:895
3: std::io::stdio::_print
at /build/rustc-71Ymwo/rustc-1.47.0+dfsg1+llvm/library/std/src/io/stdio.rs:907
4: ht::buffer::Buffer::write
5: ht::main::{{closure}}
6: std::thread::local::LocalKey<T>::with
7: tokio::runtime::enter::Enter::block_on
8: tokio::runtime::thread_pool::ThreadPool::block_on
9: tokio::runtime::Runtime::block_on
10: ht::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Installed from cargo, rustc 1.47.0
Ubuntu 20.10 / Linux 5.8.0-41-generic
ht
uses async, but it uses it inconsistently and I'm not sure that it needs it.
Is it likely that it will start doing multiple requests at a time in the future? If so, then blocking APIs like std::fs
should be avoided. If not, then maybe reqwest's blocking API would be easier to use.
Consider supporting HTTP/3 (h3). The following projects implement h3 in Rust however Cloudflare's Quiche might be the better option as it doesn't require C projects (Mozilla's Neqo requires NSS) and can be compiled as a static musl binary. It looks like Quinn only implements HTTP.0.9 over QUIC
For example, if someone provides foo\==bar
, it should be parsed as DataField("foo=", "bar")
and not as UrlParam("foo", "bar")
. Our current regex could be modified to support that through negative lookbehind or via some other trick but that comes with some drawbacks:
^(.+?)(?<!(\\))(==|:=|=|@|:)((?s).+)$
on foo\==bar
, it would produce ("foo\=", "=", "bar")
instead of ("foo=", "=", "bar")
.regex
crate we're currently using e.g lookaround.I've been lately playing with https://github.com/Geal/nom to see how easy it is to support nested JSON syntax. Maybe that could help us here?
When downloading this particular file xh
tends to fail.
❯ xh --download --output lid.176.bin https://dl.fbaipublicfiles.com/fasttext/supervised-models/lid.176.bin
HTTP/2.0 200 OK
accept-ranges: bytes
cf-cache-status: DYNAMIC
cf-ray: 647ae6814e4ae80d-LAX
cf-request-id: 09c0ae64d00000e80d05a72000000001
content-length: 131266198
content-type: application/octet-stream
date: Thu, 29 Apr 2021 19:22:40 GMT
etag: "be9a581239b678aafe80d1d4a46d86d8-16"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
last-modified: Fri, 18 Jan 2019 15:01:14 GMT
server: cloudflare
set-cookie: __cfduid=dfd5b87e416587032a11e8c6f286918f91619724160; expires=Sat, 29-May-21 19:22:40 GMT; path=/; domain=.fbaipublicfiles.com; HttpOnly; SameSite=Lax
x-amz-id-2: umZpKluJeIllqq/c6zhTmEKE2/dYK0mJ7QBI6xtRpEMj1sko6eU1W2m970vyu07+/Ih7QglfQPA=
x-amz-request-id: C4P9T3MK474MWB9J
x-amz-server-side-encryption: AES256
x-amz-version-id: i0bvGpDpJiHbCgE2pdfmiT6e8rhcCJdD
Downloading 125.19MB to "lid.176.bin"
Error: request or response body error: error reading a body from connection: broken pipe
Caused by:
0: error reading a body from connection: broken pipe
1: broken pipe
On my macOS laptop it seems most consistently to fail. It also intermittently fails on two Arch Linux machines. Both curl
and httpie
consistently download the file without issue.
Whenever this pull request gets merged, scoop can be added as an installation option in the README.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.