Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a zig package manager support #6

Closed
softprops opened this issue Feb 26, 2024 · 18 comments
Closed

Add a zig package manager support #6

softprops opened this issue Feb 26, 2024 · 18 comments

Comments

@softprops
Copy link

As of zig 0.11, the current stable version, zig supports a native package manager.

This library having that native package manager support for that would really go a long ways because many real world services don’t support tls v3 yet

@melonedo
Copy link
Owner

Do you might opening a PR? I do not see many resources on package managers...

@Cloudef
Copy link
Contributor

Cloudef commented Feb 26, 2024

#4 I already added it. Though keep in mind the compressor api in std changed and this project has to be updated to work with latest nightly zig. Also prob have to change the interface to match this ziglang/zig#18955

@melonedo
Copy link
Owner

#4 I already added it. Though keep in mind the compressor api in std changed and this project has to be updated to work with latest nightly zig. Also prob have to change the interface to match this ziglang/zig#18955

So I can take this commit as fixed. Also, bf85ec5 synchronizes with zig master.

@softprops
Copy link
Author

softprops commented Feb 27, 2024

Ah, I was looking for something like a build.zig.zon file in this repo or something in the readme that provided installation instructions.

keep in mind the compressor api in std changed and this project has to be updated to work with latest nightly zig

My hope would be for some library that would be compatible with the current stable version 0.11. The build.zig.zon version also helps with documenting which min version the library expects so that my down stream clients aren't forced to depend on nightly zig releases.

@melonedo melonedo reopened this Feb 28, 2024
@melonedo
Copy link
Owner

melonedo commented Feb 28, 2024

Do you have examples to follow? Based on what i observed, build.zig.zon is only need for a project that has dependencies. Since zig-tls12 has no dependency except zig itself, #4 (comment) should be enough.

Also, you can open a new issue about 0.11 support so that these two issues are separately tracked.

@Cloudef
Copy link
Contributor

Cloudef commented Feb 28, 2024

build.zig.zon does not encode zig version information at all, you might be confusing with zigmod which is not the official package manager. build.zig.zon only contains the following information

  • project name
  • project version
  • dependencies
  • paths the hash is calculated from (not in 0.11)

#4 (comment) Could be added to the readme though. The changes in this PR can be applied to separate branch for version that supports 0.11, though do note the std.Build API has changed a lot so you need to do some changes there as well. hexops/mach#1135 (comment) is good reference for that.

Though I'd recommend waiting for 0.12 which should come around soon(ish).

@softprops
Copy link
Author

Hi folks, I'd clear up some confusion

@melonedo

you can open a new issue about 0.11 support so that these two issues are separately tracked.

That's what I meant in the first sentence of this gh issue

As of zig 0.11...

I was meaning this to be that 0.11 issue

@Cloudef

build.zig.zon does not encode zig version information at all, you might be confusing with zigmod which is not the official package manager. build.zig.zon only contains the following information

I made this assumption based on reading docs on zig.build.zon which does include a minimum_zig_version field. I presumed this is part of the official package manager that came with in 0.11. I'm aware that is a declaration not yet enforced but it does serve as a structured way to communicate that a library supports the latest stable version of only a given nightly version of zig.

I just tested adding minimum_zig_version to a library of my own which targets the current stable 0.11 version it seems to work.

recommend waiting for 0.12 which should come around soon(ish).

👍 I'm okay with that. The 0.12 milestone recently had set a target date for march 6

Screenshot 2024-02-28 at 9 37 52 AM

That's the first release I'm seeing that's committing to a date so hopefully afterward we can expect to see some regular cadence of releases 🤞

@Cloudef
Copy link
Contributor

Cloudef commented Feb 28, 2024

Oh i wasnt aware of that zon key, nice to know!

@softprops
Copy link
Author

no worries I wasn't aware 0.12 was coming out so soon. that's super exciting

@softprops
Copy link
Author

Looks like a due date was removed from the 0.12 milestone :/ since there isn't a a defined cadence for the zig project yet that means there's no eta on when to expect that release to arrive

@melonedo
Copy link
Owner

I've backported zig-tls12 to 0.11. @softprops could you help me check and test https://github.com/melonedo/zig-tls12/tree/zig-0.11?

@softprops
Copy link
Author

Unfortunately that didn't seem to work for me. I got an TlsInitializationFailed error. Here's what I tried

$zig version  
0.11.0

In a build.zig.zon, add I added your lib

.{
    .name = "devtogo",
    .version = "0.1.0",
    .dependencies = .{
        .http = .{
            .url = "https://github.com/melonedo/zig-tls12/archive/refs/heads/zig-0.11.tar.gz",
            .hash = "1220182f2188716f14d6756a0ae43c69949eebe858f188d21ac8396d0abceff18c78",
        },
    },
}

in a build.zig file wire it in to and exe

const http = b.dependency("http", .{
    .target = target,
    .optimize = optimize,
});
...
exe.addModule("http", http.module("zig-tls12"));

in a main.zig file, make a request to the dev.to rest api

const std = @import("std");
const HttpClient = @import("http"); 

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    var client = HttpClient{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse("https://dev.to/api/articles/me");

    var headers = std.http.Headers{ .allocator = allocator };
    defer headers.deinit();
    try headers.append("Accept", "application/vnd.forem.api-v1+json");
    try headers.append("api-key", std.os.getenv("DEV_TO_APIKEY").?);

    var req = try client.request(.GET, uri, headers, .{});
    defer req.deinit();

    try req.start();
    try req.wait();
    const body = try req.reader().readAllAlloc(allocator, 16 * 1024 * 1024);
    defer allocator.free(body);

    std.debug.print("{s}: {s}\n", .{ uri, body });
}

give it a spin

$DEV_TO_APIKEY=xxx zig build run
error: TlsInitializationFailed
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/tls.zig:200:9: 0x1008e9c03 in toError (devtogo)
        return switch (alert) {
        ^
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/tls/Client.zig:255:17: 0x100848e57 in init__anon_10632 (devtogo)
                try desc.toError();
                ^
/Users/doug/.cache/zig/p/1220182f2188716f14d6756a0ae43c69949eebe858f188d21ac8396d0abceff18c78/src/HttpClient.zig:914:103: 0x10073ef6b in connectUnproxied (devtogo)
            conn.data.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch return error.TlsInitializationFailed;
                                                                                                      ^
/Users/doug/.cache/zig/p/1220182f2188716f14d6756a0ae43c69949eebe858f188d21ac8396d0abceff18c78/src/HttpClient.zig:949:9: 0x10070affb in connect (devtogo)
        return client.connectUnproxied(host, port, protocol);
        ^
/Users/doug/.cache/zig/p/1220182f2188716f14d6756a0ae43c69949eebe858f188d21ac8396d0abceff18c78/src/HttpClient.zig:1014:44: 0x100703bc3 in request (devtogo)
    const conn = options.connection orelse try client.connect(host, port, protocol);
                                           ^
/Users/doug/code/github/devtogo/src/main.zig:19:15: 0x100702c4b in main (devtogo)
    var req = try client.request(.GET, uri, headers, .{});
              ^
run devtogo: error: the following command exited with error code 1:
/Users/doug/code/github/devtogo/zig-out/bin/devtogo 
Build Summary: 3/5 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run devtogo failure
error: the following build command failed with exit code 1:
/Users/doug/code/github/devtogo/zig-cache/o/97b1fbb649247342b060a551f2f882ef/build /opt/homebrew/Cellar/zig/0.11.0/bin/zig /Users/doug/code/github/devtogo /Users/doug/code/github/devtogo/zig-cache /Users/doug/.cache/zig run

When I try the same request with curl I get an expected response, note curl uses tls 1.2 in the output below

$curl -v --proto '=https' --tlsv1.2 -H "api_key:xxx" -H 'Accept:application/vnd.forem.api-v1+json' https://dev.to/api/articles/me
*   Trying 151.101.194.217:443...
* Connected to dev.to (151.101.194.217) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 👈 curl  is using tls 1.2
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=dev.to
*  start date: Mar  6 21:57:00 2024 GMT
*  expire date: Apr  7 21:56:59 2025 GMT
*  subjectAltName: host "dev.to" matched cert's "dev.to"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign Atlas R3 DV TLS CA 2024 Q1
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://dev.to/api/articles/me
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: dev.to]
* [HTTP/2] [1] [:path: /api/articles/me]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [api_key: xxx]
* [HTTP/2] [1] [accept: application/vnd.forem.api-v1+json]
> GET /api/articles/me HTTP/2
> Host: dev.to
> User-Agent: curl/8.4.0
> api_key:xxx
> Accept:application/vnd.forem.api-v1+json
> 
< HTTP/2 200 
... rest of response

However, if I try with the https://bing.com example from your repo I do get a response

What's interesting with the bing.com example is that curl seems to choose actually choose tls 1.3

 curl -v --proto '=https' --tlsv1.2  https://bing.com
*   Trying 13.107.21.200:443...
* Connected to bing.com (13.107.21.200) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384  👈 curl  is using tls 1.3
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=www.bing.com
*  start date: Jan 21 13:42:33 2024 GMT
*  expire date: Jun 27 23:59:59 2024 GMT
*  subjectAltName: host "bing.com" matched cert's "bing.com"
*  issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure TLS Issuing CA 02
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://bing.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: bing.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
> GET / HTTP/2
> Host: bing.com
> User-Agent: curl/8.4.0
> 
< HTTP/2 301 
.. rest of response

I double checked at the std lib std.http.Client also works with with your bing example, likely because it supports tls 1.3

@melonedo
Copy link
Owner

Oops I did not actually use TlsClient at all, it is fixed now.

@softprops
Copy link
Author

I tried once more this time with the hash 12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797 after deleting my zig-* cache dirs

.dependencies = .{
        .http = .{
            .url = "https://github.com/melonedo/zig-tls12/archive/refs/heads/zig-0.11.tar.gz",
            .hash = "12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797",
        },
    },

I'll get a long pause and then TlsInitializationFailed again. something doesn't seem quite right as the error is coming from std/crypto/tls/Client and not the replacement which might. mean something is slightly flawed in the way zig downloads these artifacts. the hash updated by I feel like I'm linking against the previous version of the sources

DEV_TO_APIKEY=xxxx zig build run
error: TlsInitializationFailed
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/tls.zig:200:9: 0x102db9c1f in toError (devtogo)
        return switch (alert) {
        ^
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/tls/Client.zig:255:17: 0x102d18e73 in init__anon_10598 (devtogo)
                try desc.toError();
                ^
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/http/Client.zig:912:103: 0x102c0ef6b in connectUnproxied (devtogo)
            conn.data.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch return error.TlsInitializationFailed;
                                                                                                      ^
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/http/Client.zig:947:9: 0x102bdaffb in connect (devtogo)
        return client.connectUnproxied(host, port, protocol);
        ^
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/http/Client.zig:1012:44: 0x102bd3bc3 in request (devtogo)
    const conn = options.connection orelse try client.connect(host, port, protocol);
                                           ^
/Users/doug/code/github/devtogo/src/main.zig:19:15: 0x102bd2c4b in main (devtogo)
    var req = try client.request(.GET, uri, headers, .{});
              ^
run devtogo: error: the following command exited with error code 1:
/Users/doug/code/github/devtogo/zig-out/bin/devtogo 
Build Summary: 3/5 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run devtogo failure
error: the following build command failed with exit code 1:
/Users/doug/code/github/devtogo/zig-cache/o/c4e3cd487e42d683850213cd336d6808/build /opt/homebrew/Cellar/zig/0.11.0/bin/zig /Users/doug/code/github/devtogo /Users/doug/code/github/devtogo/zig-cache /Users/doug/.cache/zig run

@melonedo
Copy link
Owner

melonedo commented Mar 11, 2024 via email

@softprops
Copy link
Author

I'm sorry, my bad there. I had updated my example code to use the std http client when I was checking what was happening with the bing example.

After switching back to your client I get a different error

this one looks like a compile time error

error: expected type '*crypto.Certificate.Bundle', found '*crypto.Bundle'

DEV_TO_APIKEY=xxx zig build run
zig build-exe devtogo Debug native: error: the following command failed with 1 compilation errors:
/opt/homebrew/Cellar/zig/0.11.0/bin/zig build-exe /Users/doug/code/github/devtogo/src/main.zig --cache-dir /Users/doug/code/github/devtogo/zig-cache --global-cache-dir /Users/doug/.cache/zig --name devtogo --mod http::/Users/doug/.cache/zig/p/12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797/src/HttpClient.zig --deps http --listen=- 
Build Summary: 0/5 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run devtogo transitive failure
   ├─ zig build-exe devtogo Debug native 1 errors
   └─ install transitive failure
      └─ install devtogo transitive failure
         └─ zig build-exe devtogo Debug native (reused)
/Users/doug/.cache/zig/p/12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797/src/crypto/Bundle.zig:62:36: error: expected type '*crypto.Certificate.Bundle', found '*crypto.Bundle'
        .macos => return rescanMac(cb, gpa),
                                   ^~
/Users/doug/.cache/zig/p/12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797/src/crypto/Bundle.zig:62:36: note: pointer type child 'crypto.Bundle' cannot cast into pointer type child 'crypto.Certificate.Bundle'
/Users/doug/.cache/zig/p/12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797/src/crypto/Bundle.zig:1:1: note: struct declared here
//! A set of certificates. Typically pre-installed on every operating system,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/Certificate/Bundle.zig:1:1: note: struct declared here
//! A set of certificates. Typically pre-installed on every operating system,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/zig/0.11.0/lib/zig/std/crypto/Certificate/Bundle.zig:59:19: note: parameter type declared here
pub fn rescan(cb: *Bundle, gpa: Allocator) RescanError!void {
                  ^~~~~~~
referenced by:
    request: /Users/doug/.cache/zig/p/12207ddff4694ce69db81cb9fa6073e22293e0302f079544234f8c34adfe49960797/src/HttpClient.zig:1009:29
    main: src/main.zig:19:25
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
    ```

@melonedo
Copy link
Owner

melonedo commented Mar 11, 2024

Bundle/macos.zig is not included in my setting, I adjusted for this in my latest commit (eb3f389).

@softprops
Copy link
Author

that worked!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants