56 Commits

Author SHA1 Message Date
Andrew Kelley
1e2aab2f97 std: combine BufferedWriter into Writer 2025-07-01 16:35:29 -07:00
Andrew Kelley
3c98e2c826 std: combine BufferedReader into Reader 2025-07-01 16:35:29 -07:00
Andrew Kelley
2ed47f1ed8 std: update AtomicFile to new API 2025-07-01 16:35:29 -07:00
Andrew Kelley
ba684a18ca std: upgrade more API to use File.Reader 2025-07-01 16:35:29 -07:00
Andrew Kelley
2f5574ac08 std: finish renaming RwError to StreamError 2025-07-01 16:35:29 -07:00
Andrew Kelley
74c56376ee std: update http.WebSocket to new API 2025-07-01 16:35:29 -07:00
Andrew Kelley
af4bb996f0 std.http.Client: fix redirects 2025-07-01 16:35:29 -07:00
Andrew Kelley
d0b8392852 std.http fixes 2025-07-01 16:35:28 -07:00
Andrew Kelley
af7721d20f std.http.BodyWriter: fix end of transfer-encoding chunked
Looks like chunked transfers are supposed to always end with a length
zero chunk. This bug exists on master branch as well.
2025-07-01 16:35:28 -07:00
Andrew Kelley
97c7d6e5b3 std.http: fix parseTrailers (transfer-encoding: chunked)
It needs to detect \r\n as end of stream rather than trying to check the
next byte.
2025-07-01 16:35:28 -07:00
Andrew Kelley
2abbcb6d2a std.http: fix chunked transfer flushing and end-of-stream handling 2025-07-01 16:35:28 -07:00
Andrew Kelley
847afd0a47 std.http: fix chunked header offset calculation 2025-07-01 16:35:28 -07:00
Andrew Kelley
4716c00366 std.http.Server: don't try to discard nonexistent body 2025-07-01 16:35:28 -07:00
Andrew Kelley
9ed20386bb std.http.Reader: simplify states 2025-07-01 16:35:28 -07:00
Andrew Kelley
bb7af21d6f std.crypto.tls.Client: update to new reader/writer API 2025-07-01 16:35:28 -07:00
Andrew Kelley
c7040171fb std.http: mostly finish the rewrite 2025-07-01 16:35:28 -07:00
Andrew Kelley
d8cea03245 std.http: more update 2025-07-01 16:35:28 -07:00
Andrew Kelley
ab3a947bef get build runner compiling again 2025-07-01 16:35:28 -07:00
Andrew Kelley
81b0d14e2b std.http: rewrite
WIP
2025-07-01 16:35:28 -07:00
Andrew Kelley
b9fd0eeca6 add std.http.WebSocket 2024-08-07 00:48:32 -07:00
mlugg
eae9aa800e
std: avoid references that trigger compile errors
Note that the `_ = Address` statements in tests previously were a nop,
and now actually check that the type is valid. However, on WASI, the
type is *not* valid.
2024-07-04 21:01:42 +01:00
Andrew Kelley
653d4158cd std.http.Server: expose arbitrary HTTP headers
Ultimate flexibility, just be sure to destroy the correct amount of
information when looking at them.
2024-02-23 02:58:02 -07:00
Andrew Kelley
d7ac8c8e65 wasi: don't try to test http
wasi does not support networking
2024-02-23 02:37:11 -07:00
Andrew Kelley
b4b9f6aa4a std.http.Server: reimplement chunked uploading
* Uncouple std.http.ChunkParser from protocol.zig
* Fix receiveHead not passing leftover buffer through the header parser.
* Fix content-length read streaming

This implementation handles the final chunk length correctly rather than
"hoping" that the buffer already contains \r\n.
2024-02-23 02:37:11 -07:00
Andrew Kelley
6395ba852a std.http.Server: rework the API entirely
Mainly, this removes the poorly named `wait`, `send`, `finish`
functions, which all operated on the same "Response" object, which was
actually being used as the request.

Now, it looks like this:
1. std.net.Server.accept() gives you a std.net.Server.Connection
2. std.http.Server.init() with the connection
3. Server.receiveHead() gives you a Request
4. Request.reader() gives you a body reader
5. Request.respond() is a one-shot, or Request.respondStreaming() creates
   a Response
6. Response.writer() gives you a body writer
7. Response.end() finishes the response; Response.endChunked() allows
   passing response trailers.

In other words, the type system now guides the API user down the correct
path.

receiveHead allows extra bytes to be read into the read buffer, and then
will reuse those bytes for the body or the next request upon connection
reuse.

respond(), the one-shot function, will send the entire response in one
syscall.

Streaming response bodies no longer wastefully wraps every call to write
with a chunk header and trailer; instead it only sends the HTTP chunk
wrapper when flushing. This means the user can still control when it
happens but it also does not add unnecessary chunks.

Empirically, in my example project that uses this API, the usage code is
significantly less noisy, it has less error handling while handling
errors more correctly, it's more obvious what is happening, and it is
syscall-optimal.

Additionally:
* Uncouple std.http.HeadParser from protocol.zig
* Delete std.Server.Connection; use std.net.Server.Connection instead.
  - The API user supplies the read buffer when initializing the
    http.Server, and it is used for the HTTP head as well as a buffer
    for reading the body into.
* Replace and document the State enum. No longer is there both "start"
  and "first".
2024-02-23 02:37:11 -07:00
Andrew Kelley
511acc167f std.http: remove format() method of Method
I don't like this mechanism in general, and it is unused by the standard
library.
2024-02-23 02:37:11 -07:00
Andrew Kelley
3d61890d24 std: convert http trailers test to unit test
making it no longer dead code. it is currently failing.
2024-02-23 02:37:11 -07:00
Andrew Kelley
4d401e6159 std.http: remove Headers API
I originally removed these in 402f967ed5339fa3d828b7fe1d57cdb5bf38dbf2.
I allowed them to be added back in #15299 because they were smuggled in
alongside a bug fix, however, I wasn't kidding when I said that I wanted
to take the design of std.http in a different direction than using this
data structure.

Instead, some headers are provided via explicit field names populated
while parsing the HTTP request/response, and some are provided via
new fields that support passing extra, arbitrary headers.

This resulted in simplification of logic in many places, as well as
elimination of the possibility of failure in many places. There is
less deinitialization code happening now.

Furthermore, it made it no longer necessary to clone the headers data
structure in order to handle redirects.

http_proxy and https_proxy fields are now pointers since it is common
for them to be unpopulated.

loadDefaultProxies is changed into initDefaultProxies to communicate
that it does not actually load anything from disk or from the network.
The function now is leaky; the API user must pass an already
instantiated arena allocator. Removes the need to deinitialize proxies.

Before, proxies stored arbitrary sets of headers. Now they only store
the authorization value.

Removed the duplicated code between https_proxy and http_proxy. Finally,
parsing failures of the environment variables result in errors being
emitted rather than silently ignoring the proxy.

error.CompressionNotSupported is renamed to
error.CompressionUnsupported, matching the naming convention from all
the other errors in the same set.

Removed documentation comments that were redundant with field and type
names.

Disabling zstd decompression in the server for now; see #18937.

I found some apparently dead code in src/Package/Fetch/git.zig. I want
to check with Ian about this.

I discovered that test/standalone/http.zig is dead code, it is only
being compiled but not being run. Furthermore it hangs at the end if you
run it manually. The previous commits in this branch were written under
the assumption that this test was being run with
`zig build test-standalone`.
2024-02-23 02:37:11 -07:00
Carl Ã…stholm
d7b36503ca Remove some @as coercions from assertions
These are some spurious fixes to help illustrate the improved ergonomics of the `expectEqual` change. It is by no means complete.
2024-01-03 21:20:48 +01:00
Nameless
7dd3099519
std.http: fix crashes found via fuzzing 2023-10-21 20:52:59 -05:00
Nameless
c523b5421b
std.http: make encoding fields non-null, store as enum variant 2023-10-21 20:52:59 -05:00
JustinWayland
c45af2af61
Fix simple doc mistakes. (#17624)
* Add missing period in Stack's description

This looks fine in the source, but looks bad when seen on the documentation website.

* Correct documentation for attachSegfaultHandler()

The description for attachSegfaultHandler() looks pretty bad without indicating that the stuff at the end is code

* Added missing 'the's in Queue.put's documentation

* Fixed several errors in Stack's documentation

`push()` and `pop()` were not styled as code

There was no period after `pop()`, which looks bad on the documentation.

* Fix multiple problems in base64.zig

Both "invalid"s in Base64.decoder were not capitalized.

Missing period in documentation of Base64DecoderWithIgnore.calcSizeUpperBound.

* Fix capitalization typos in bit_set.zig

In DynamicBitSetUnmanaged.deinit's and DynamicBitSet.deinit's documentation, "deinitializes" was uncapitalized.

* Fix typos in fifo.zig's documentation

Added a previously missing period to the end of the first line of LinearFifo.writableSlice's documentation.
Added missing periods to both lines of LinearFifo.pump's documentation.

* Fix typos in fmt.bufPrint's documentation

The starts of both lines were not capitalized.

* Fix minor documentation problems in fs/file.zig

Missing periods in documentation for Permissions.setReadOnly, PermissionsWindows.setReadOnly, MetadataUnix.created, MetadataLinux.created, and MetadataWindows.created.

* Fix a glaring typo in enums.zig

* Correct errors in fs.zig

* Fixed documentation problems in hash_map.zig

The added empty line in verify_context's documentation is needed, otherwise autodoc for some reason assumes that the list hasn't been terminated and continues reading off the rest of the documentation as if it were part of the second list item.

* Added lines between consecutive URLs in http.zig

Makes the documentation conform closer to what was intended.

* Fix wrongfully ended sentence in Uri.zig

* Handle wrongly entered comma in valgrind.zig.

* Add missing periods in wasm.zig's documentation

* Fix odd spacing in event/loop.zig

* Add missing period in http/Headers.zig

* Added missing period in io/limited_reader.zig

This isn't in the documentation due to what I guess is a limitation of autodoc, but it's clearly supposed to be. If it was, it would look pretty bad.

* Correct documentation in math/big/int.zig

* Correct formatting in math/big/rational.zig

* Create an actual link to ZIGNOR's paper.

* Fixed grammatical issues in sort/block.zig

This will not show up in the documentation currently.

* Fix typo in hash_map.zig
2023-10-21 21:24:55 +00:00
Chris Burgess
1c726bcb32
std.http: add identity to content encodings (#16493)
Some servers will respond with the identity encoding, meaning no
encoding, especially when responding to range-get requests. Adding the
identity encoding stops the header parser from failing when it
encounters this.
2023-09-26 17:16:40 -04:00
Nameless
4689d93cb2
std.http: allow for arbitrary http methods 2023-08-30 13:05:45 -05:00
jim price
59322963ce Fix the http.Server test and add it to the set of tests in http.zig 2023-07-23 13:58:34 -07:00
Eric Joldasov
50339f595a all: zig fmt and rename "@XToY" to "@YFromX"
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-19 12:34:42 -07:00
Nameless
71c228fe65
std.http: add simple standalone http tests, add state check for http server 2023-05-06 21:35:15 -05:00
Linus Groh
94e30a756e std: fix a bunch of typos
The majority of these are in comments, some in doc comments which might
affect the generated documentation, and a few in parameter names -
nothing that should be breaking, however.
2023-04-30 18:16:04 -07:00
Meghan
66da64d77c
std.http: fix name of Status field to better match RFC name (#15455)
.header_fields_too_large -> .request_header_fields_too_large
2023-04-26 14:02:55 -04:00
Ryo Ota
06763c4c8c move the HTTP test to lib/std/http/test.zig 2023-04-21 09:51:23 +09:00
Nameless
e65cbff94d
std.http: use 'Field' to describe an individual header 2023-04-17 19:16:06 -05:00
Nameless
134294230a
std.http: add Headers 2023-04-17 19:15:55 -05:00
Nameless
96533b1289
std.http: very basic http client proxy 2023-04-17 19:14:48 -05:00
Nameless
08bdaf3bd6
std.http: add http server
* extract http protocol into protocol.zig, as it is shared between client and server
* coalesce Request and Response back into Client.zig, they don't contain
  any large chunks of code anymore
* http.Server is implemented as basic as possible, a simple example below:

```zig
fn handler(res: *Server.Response) !void {
    while (true) {
        defer res.reset();

        try res.waitForCompleteHead();
        res.headers.transfer_encoding = .{ .content_length = 14 };
        res.headers.connection = res.request.headers.connection;
        try res.sendResponseHead();
        _ = try res.write("Hello, World!\n");

        if (res.connection.closing) break;
    }
}

pub fn main() !void {
    var server = Server.init(std.heap.page_allocator, .{ .reuse_address = true });
    defer server.deinit();

    try server.listen(try net.Address.parseIp("127.0.0.1", 8080));

    while (true) {
        const res = try server.accept(.{ .dynamic = 8192 });

        const thread = try std.Thread.spawn(.{}, handler, .{res});
        thread.detach();
    }
}
```
2023-04-08 09:59:35 -05:00
Nameless
634e715504
std.http: split Client's parts into their own files 2023-03-09 14:55:20 -06:00
Nameless
fd2f906d1e
std.http: handle compressed payloads 2023-03-09 14:54:26 -06:00
Andrew Kelley
a7a933d7ee std.http.Client: support transfer-encoding: chunked
closes #14204

In order to add tests for this I need to implement an HTTP server in the
standard library (#910) so that's probably the next thing I'll do.
2023-01-05 19:57:00 -07:00
Andrew Kelley
450f3bc925 std.http.Class: classify out-of-range codes as server_error
RFC 9110 section 15:
Values outside the range 100..599 are invalid. Implementations often use
three-digit integer values outside of that range (i.e., 600..999) for
internal communication of non-HTTP status (e.g., library errors). A
client that receives a response with an invalid status code SHOULD
process the response as if it had a 5xx (Server Error) status code.
2023-01-05 13:31:26 -07:00
Andrew Kelley
8248fdbbdb std.http.Client: support HTTP redirects
* std.http.Status.Class: add a "nonstandard" enum tag. Instead of
   having `class` return an optional value, it can potentially return
   nonstandard.
 * extract out std.http.Client.Connection from std.http.Client.Request
   - this code abstracts over plain/TLS only
   - this is the type that will potentially be stored in a client's LRU
     connection map
 * introduce two-staged HTTP header parsing
   - API users can rely on a heap-allocated buffer with a maximum limit,
     which defaults to 16 KB, or they can provide a static buffer that
     is borrowed by the Request instance.
   - The entire HTTP header is buffered because there are strings in
     there and they must be accessed later, such as with the case of
     HTTP redirects.
   - When buffering the HTTP header, the parser only looks for the
     \r\n\r\n pattern. Further validation is done later.
   - After the full HTTP header is buffered, it is parsed into
     components such as Content-Length and Location.
 * HTTP redirects are handled, with a maximum redirect count option that
   defaults to 3.
   - Connection: close is always used for now; implementing keep-alive
     connections and an LRU connection pool in std.http.Client is a task
     for another day.

see #2007
2023-01-04 18:37:53 -07:00
Andrew Kelley
5d9429579d std.http.Headers.Parser: parse version and status 2023-01-04 18:37:53 -07:00