You can check out https://github.com/ducdetronquito/requestz/
#HTTP Get troubles (Newbie Alert)
1 messages · Page 1 of 1 (latest)
yeah but how do I install it
gyro doesn't work for me
or I haven't gotten it to work for me
Lmao 0.10.2
Zig has in master atm a http client
a basic one, but one
also in master we have the zig package manager working for packages that are updated to use it
where can I find the documentation for this?
Documentation
harder to say
too new atm
Read the source, there should be some tests you can use as examples
Or I think someone had a repo with an example
give me a minute
Alright, I appreciate you taking your time on thsi
Also disclaimer: zig http lib has less than month lol
do u mean that its less than a month old?
Yep
You use an allocator implementation
Never been coding low-level languages so never had to manage my own memory like this
and no intellisense isn't helping
this is even a bit more than most languages
Do you use vscode?
yup
install the ziglang zig plugin
I have but idk how to activate it or sum
ctrl + shift + p (Pallete command) And install zls
Tho I have to say, it works when using master
zls is always expecting you to use the latests version
indeed
i'll just uninstall all my current externsions
for zig*
yea
I think I did it
this looks correct?
oh wait I think my code actualyl work
Alright, got it working
imma close this thread, thanks.
hi
hello
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
var http_client = std.http.Client{.allocator = allocator};
var uri = try std.Uri.parse("https://ziglang.org/download/index.json");
var request = try http_client.request(uri, .{}, .{});
defer request.deinit();
var zig_json = try request.reader().readAllAlloc(allocator, std.math.maxInt(usize));
defer allocator.free(zig_json);
try std.io.getStdOut().writer().writeAll(zig_json);
}
oh they updated zig by example
It's the general one
This has a more extensive (yet not complete) example of making a request
i really don't understand this .{}{} stuff
why
its like, y'all making symbols of boobs
mess up my brain
x33
An empty anonymous struct, which when passed as a parameter, it becomes (coerces) into the type the argument is asking, since there is no field to set, it's empty
is there somewhere I can get a through tutorial on this stuff such as defer, .{} stuff
reading the langref and the source😄
can u link it?
That's why I used defer
- Get the gpa
- Get the allocator
- Create the Http Client
- Parse the URI that we are gonna connect
- we create the request
- We make that at the end of the scope (in this case, at the end of the function) we remove all resources that the request allocated
- We read all the data we are being sent and allocate it in the heap of the computer
- We ask it to be freed once the scope ends (in this case, when the function ends)
- We print all
but why do we need "defer" infront? what does that change
Nothing, it's a good practice
You could rewrite it so we free the resources at the end of the function
but then you have to remember that you allocated those in the first place
So if you allocate and instantly defer the deallocation of the resources, is easier to remember and to read what the intent is
And I forgot to deinit the http_client lmao
deinit is the name of the function that removes the resources that were allocated from the struct
however you want to call it
ah okay
it's not a concept, but a common name for that specific procedure
you init structs
deinit them
you create structs
you destroy them
Those are common names
that might be why its never printing the "json"
uh-oh
changed Uri and now its giving me the whole html
It will return you the headers, the response and not much more
this should return a http code right?
Spotify.com returns not_found
or shouuld
oh right, and try with {any} instead of {s}
error: access of union field 'Pointer' while field 'Enum' is active
bro what is it talking abt
that aint even my code
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var allocator = gpa.allocator();
var http_client = std.http.Client{.allocator = allocator};
defer http_client.deinit();
var uri = try std.Uri.parse("https://spotify.com/");
var request = try http_client.request(uri, .{}, .{});
defer request.deinit();
try std.io.getStdOut().writer().print("{any}\n", .{request.response.headers.status});
var zig_json = try request.reader().readAllAlloc(allocator, std.math.maxInt(usize));
defer allocator.free(zig_json);
try std.io.getStdOut().writer().writeAll(zig_json);
try std.io.getStdOut().writer().print("{any}\n", .{request.response.headers.status});
}
// Allocate Memory
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
var client: std.http.Client = .{ .allocator = allocator};
defer client.deinit();
var req = try client.request(uri, .{}, .{});
defer req.deinit();
var res = req.response.headers.status;
std.debug.print("{any}", .{res});
// Release Memory
defer allocator.free(res);
}```
how you make your code colored?
I use the rust syntax highlighting
no idea what that is
You are freeing req.response.headers.status
which is not allocated
oh
```rs
well, idk what to free since I am not allocating anything
pub fn main() !void {
// Allocate Memory
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
var client: std.http.Client = .{ .allocator = allocator};
defer client.deinit();
var req = try client.request(uri, .{}, .{});
defer req.deinit();
var res = req.response.headers.status;
std.debug.print("{any}", .{res});
// Release Memory
defer allocator.free(res);
}```
thats cool
then don't free anything
but then why do I need to allocate memory?
The deinits are the only things needed
The client and the request are allocating
that's why the client asked for a memory allocator
for it to be able to allocate the request and such things
so should I free that or does it free itself with the .deinit();?
It frees itself with deinit in this case
const std = @import("std");
const uri = std.Uri.parse("http://spotify.com/") catch unreachable;
pub fn main() !void {
// Allocate Memory
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
var client: std.http.Client = .{ .allocator = allocator};
defer client.deinit();
var req = try client.request(uri, .{}, .{});
defer req.deinit();
var res = req.response.headers.status;
std.debug.print("{any}", .{res});
// Don't Release Memory
}
this works
returns http.Status(682)
because you haven't read the response yet
I ain't wanna read it
var res = req.readAll(usize);
this should work
but it doesn't
eeh
So you need some array, allocated by an allocator or provided by you, to read all the things
var zig_json = try request.reader().readAllAlloc(allocator, std.math.maxInt(usize)); This is reading the response and all that jazz, and putting it on the heap automatically
if I wanted to do the same with readAll
I used this
const std = @import("std");
const uri = std.Uri.parse("http://spotify.com/") catch unreachable;
pub fn main() !void {
// Allocate Memory
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
var client: std.http.Client = .{ .allocator = allocator};
defer client.deinit();
var req = try client.request(uri, .{}, .{});
defer req.deinit();
var res = try req.reader().readAllAlloc(allocator, std.math.maxInt(usize));
std.debug.print("{any}", .{res});
// Don't Release Memory
defer allocator.free(res);
}
well it looks like this now
unfortunently it is giving me some weird stuff now
its an array of number
its not binary
nor hex
it gotta be byts
bytes
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var allocator = gpa.allocator();
var http_client = std.http.Client{.allocator = allocator};
defer http_client.deinit();
var uri = try std.Uri.parse("https://spotify.com/");
var request = try http_client.request(uri, .{}, .{});
defer request.deinit();
try std.io.getStdOut().writer().print("{any}\n", .{request.response.headers.status});
var buffer : [256 * 1024]u8 = undefined; // 256 kb of stack memory
const result = try request.readAll(&buffer);
try std.io.getStdOut().writer().writeAll(buffer[0..result]);
try std.io.getStdOut().writer().print("\n{any}\n", .{request.response.headers.status});
}
ah yes. I gotta use std.io.getStdOut().writer
don't use any
use {s}
std.format has more info on what you can do with those strings
u told me to use any!
With the enum!
s -> print the string
any -> try anything to print this
- -> print the pointer
d -> Print the number
and some more
I see
well I guess thats everything I needed to know
for now
allocator.free(res);
this still correct?
not tryna bloat my memory with shi
I mean, depends
For this? Absolutly
For this: no
here I gotta free the buffer too?
Nop
Stack memory is memory given to you by the OS that the compiler kinda manages
So when the function dies, that stack is "dead"
if I wanna free multiple stuff at the same time
allocator.free(.{1,2,3,4,5,6,7});
would that owkr?
work*?
nopp
why
First: .{1,2,3,4,5,6} is memory that the allocator did not allocate
each allocator has ownership of some memory
So an allocator from a gpa could not free memory from std.heap.page_allocator
yeah but if I like, had mutiple requests at the same time
in this case, it's allocated by the OS before the program started
Each request would have it's own free
okay great
you got any good idea how to learn zig? like any youtube series or something, (else than reading the master)
Uhm, I learned like this.
But if you like learning by coding
give me a sec
ooh, I'll try that out
The test give you hints and teach you about how more or less the language goes
and you fill the gaps
nop, but I know a lot of people that did
well I guess I gotta try it out that way then
I just went the old: Do stuff and fail a lot while reading the language reference
After a week of doing that for like 2-3 hours a day, I got the hang of the language
for std it took me longer
like a month
Okay, I appreciate the help and all the effort you put in to giving me all this examples and that today, Imma close this thread now and try learning more zig tomorrow.
No problem mate
😘
I will point out that the language reference will tell you about defer, but it basically just means "Run this statement at the end of the current scope", rather than running it immediately.
This is useful because it allows you to allocate some memory, or open a file, or whathaveyou, and then immediately write the code that'll clean it up, rather than putting it at the end of the function for example:
{
const req = getRequest();
defer req.deinit();
// ...
} // 'req.deinit()' is run here
Defers statements can be given an almost-arbitrary statement to run, or even an entire block of code.
It happens to be that the main thing it's useful for is cleaning up stuff up, but it needn't be.
Also for multi step code
that helps alot, way easier to understand now ig, thanks. How do I close this thread? lol
anyone know how I could possibly change the headers of the get request?
@pliant flint could you help me with this
const headers: std.http.Client.Request.Headers = struct {
version: std.http.Version = .@"HTTP/1.1",
method: std.http.Method = .GET,
};
I got this far until it started going downwards