aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Ciro Spaciari <ciro.spaciari@gmail.com> 2023-01-26 23:36:53 -0300
committerGravatar GitHub <noreply@github.com> 2023-01-26 18:36:53 -0800
commit6d0660613548869feb97a299f3aee7b718025802 (patch)
tree99caea489eb130a4ee9e4f0cfb3eccbbfd4ed1d5 /src/bun.js
parent44c6ce11c4cdf160caf445da64f52019ed810073 (diff)
downloadbun-6d0660613548869feb97a299f3aee7b718025802.tar.gz
bun-6d0660613548869feb97a299f3aee7b718025802.tar.zst
bun-6d0660613548869feb97a299f3aee7b718025802.zip
Implement all pending resolve methods in DNS (#1903)
* initial steps to create generic resolve * add soa * add naptr * add naptr * add mx and fix naptr * add resolve caa * fix Caa test * fix toJS from caa * add resolveNs * add resolvePtr * fix resolvePtr test * add resolveCname * add resolve rrtype options (still missing ANY) * fix Naptr * fix drainPendingCares
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/api/bun/dns_resolver.zig759
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp27
-rw-r--r--src/bun.js/node-dns.exports.js371
-rw-r--r--src/bun.js/webcore/encoding.zig14
4 files changed, 914 insertions, 257 deletions
diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig
index 92577d556..08202a09e 100644
--- a/src/bun.js/api/bun/dns_resolver.zig
+++ b/src/bun.js/api/bun/dns_resolver.zig
@@ -614,104 +614,104 @@ pub const GetAddrInfo = struct {
};
};
-pub const ResolveSrvInfoRequest = struct {
- const log = Output.scoped(.ResolveSrvInfoRequest, false);
-
- resolver_for_caching: ?*DNSResolver = null,
- hash: u64 = 0,
- cache: ResolveSrvInfoRequest.CacheConfig = ResolveSrvInfoRequest.CacheConfig{},
- head: SrvLookup,
- tail: *SrvLookup = undefined,
- task: bun.ThreadPool.Task = undefined,
-
- pub fn init(
- cache: DNSResolver.SrvCacheHit,
- resolver: ?*DNSResolver,
- name: []const u8,
- globalThis: *JSC.JSGlobalObject,
- comptime cache_field: []const u8,
- ) !*ResolveSrvInfoRequest {
- var request = try globalThis.allocator().create(ResolveSrvInfoRequest);
- var hasher = std.hash.Wyhash.init(0);
- hasher.update(name);
- const hash = hasher.final();
- var poll_ref = JSC.PollRef.init();
- poll_ref.ref(globalThis.bunVM());
- request.* = .{
- .resolver_for_caching = resolver,
- .hash = hash,
- .head = .{
- .poll_ref = poll_ref,
- .globalThis = globalThis,
- .promise = JSC.JSPromise.Strong.init(globalThis),
- .allocated = false,
- },
- };
- request.tail = &request.head;
- if (cache == .new) {
- request.resolver_for_caching = resolver;
- request.cache = ResolveSrvInfoRequest.CacheConfig{
- .pending_cache = true,
- .entry_cache = false,
- .pos_in_pending = @truncate(u5, @field(resolver.?, cache_field).indexOf(cache.new).?),
- .name_len = @truncate(u9, name.len),
- };
- cache.new.lookup = request;
- }
- return request;
- }
-
- pub const Task = bun.JSC.WorkTask(ResolveSrvInfoRequest, false);
-
- pub const CacheConfig = packed struct(u16) {
- pending_cache: bool = false,
- entry_cache: bool = false,
- pos_in_pending: u5 = 0,
- name_len: u9 = 0,
- };
-
- pub const PendingCacheKey = struct {
- hash: u64,
- len: u16,
- lookup: *ResolveSrvInfoRequest = undefined,
-
- pub fn append(this: *PendingCacheKey, srv_lookup: *SrvLookup) void {
- var tail = this.lookup.tail;
- tail.next = srv_lookup;
- this.lookup.tail = srv_lookup;
- }
-
- pub fn init(name: []const u8) PendingCacheKey {
+pub fn ResolveInfoRequest(comptime cares_type: type, comptime type_name: []const u8) type {
+ return struct {
+ const request_type = @This();
+
+ const log = Output.scoped(@This(), false);
+
+ resolver_for_caching: ?*DNSResolver = null,
+ hash: u64 = 0,
+ cache: @This().CacheConfig = @This().CacheConfig{},
+ head: CAresLookup(cares_type, type_name),
+ tail: *CAresLookup(cares_type, type_name) = undefined,
+
+ pub fn init(
+ cache: DNSResolver.LookupCacheHit(@This()),
+ resolver: ?*DNSResolver,
+ name_str: *const JSC.ZigString.Slice,
+ globalThis: *JSC.JSGlobalObject,
+ comptime cache_field: []const u8,
+ ) !*@This() {
+ const name = name_str.slice();
+ var request = try globalThis.allocator().create(@This());
var hasher = std.hash.Wyhash.init(0);
hasher.update(name);
const hash = hasher.final();
- return PendingCacheKey{
+ var poll_ref = JSC.PollRef.init();
+ poll_ref.ref(globalThis.bunVM());
+ request.* = .{
+ .resolver_for_caching = resolver,
.hash = hash,
- .len = @truncate(u16, name.len),
- .lookup = undefined,
+ .head = .{ .poll_ref = poll_ref, .globalThis = globalThis, .promise = JSC.JSPromise.Strong.init(globalThis), .allocated = false, .name = name_str },
};
+ request.tail = &request.head;
+ if (cache == .new) {
+ request.resolver_for_caching = resolver;
+ request.cache = @This().CacheConfig{
+ .pending_cache = true,
+ .entry_cache = false,
+ .pos_in_pending = @truncate(u5, @field(resolver.?, cache_field).indexOf(cache.new).?),
+ .name_len = @truncate(u9, name.len),
+ };
+ cache.new.lookup = request;
+ }
+ return request;
}
- };
- pub fn onCaresComplete(this: *ResolveSrvInfoRequest, err_: ?c_ares.Error, timeout: i32, result: ?*c_ares.struct_ares_srv_reply) void {
- if (this.resolver_for_caching) |resolver| {
- if (this.cache.pending_cache) {
- resolver.drainPendingSrvCares(
- this.cache.pos_in_pending,
- err_,
- timeout,
- result,
- );
- return;
+ pub const CacheConfig = packed struct(u16) {
+ pending_cache: bool = false,
+ entry_cache: bool = false,
+ pos_in_pending: u5 = 0,
+ name_len: u9 = 0,
+ };
+
+ pub const PendingCacheKey = struct {
+ hash: u64,
+ len: u16,
+ lookup: *request_type = undefined,
+
+ pub fn append(this: *PendingCacheKey, cares_lookup: *CAresLookup(cares_type, type_name)) void {
+ var tail = this.lookup.tail;
+ tail.next = cares_lookup;
+ this.lookup.tail = cares_lookup;
}
- }
- var head = this.head;
- bun.default_allocator.destroy(this);
+ pub fn init(name: []const u8) PendingCacheKey {
+ var hasher = std.hash.Wyhash.init(0);
+ hasher.update(name);
+ const hash = hasher.final();
+ return PendingCacheKey{
+ .hash = hash,
+ .len = @truncate(u16, name.len),
+ .lookup = undefined,
+ };
+ }
+ };
- head.processResolveSrv(err_, timeout, result);
- }
-};
+ pub fn onCaresComplete(this: *@This(), err_: ?c_ares.Error, timeout: i32, result: ?*cares_type) void {
+ if (this.resolver_for_caching) |resolver| {
+ if (this.cache.pending_cache) {
+ resolver.drainPendingCares(
+ this.cache.pos_in_pending,
+ err_,
+ timeout,
+ @This(),
+ cares_type,
+ type_name,
+ result,
+ );
+ return;
+ }
+ }
+
+ var head = this.head;
+ bun.default_allocator.destroy(this);
+
+ head.processResolve(err_, timeout, result);
+ }
+ };
+}
pub const GetAddrInfoRequest = struct {
const log = Output.scoped(.GetAddrInfoRequest, false);
@@ -934,79 +934,78 @@ pub const GetAddrInfoRequest = struct {
}
};
-pub const SrvLookup = struct {
- const log = Output.scoped(.SrvLookup, true);
-
- globalThis: *JSC.JSGlobalObject = undefined,
- promise: JSC.JSPromise.Strong,
- poll_ref: JSC.PollRef,
- allocated: bool = false,
- next: ?*SrvLookup = null,
+pub fn CAresLookup(comptime cares_type: type, comptime type_name: []const u8) type {
+ return struct {
+ const log = Output.scoped(@This(), true);
+
+ globalThis: *JSC.JSGlobalObject = undefined,
+ promise: JSC.JSPromise.Strong,
+ poll_ref: JSC.PollRef,
+ allocated: bool = false,
+ next: ?*@This() = null,
+ name: *const JSC.ZigString.Slice,
+
+ pub fn init(globalThis: *JSC.JSGlobalObject, allocator: std.mem.Allocator, name: *const JSC.ZigString.Slice) !*@This() {
+ var this = try allocator.create(@This());
+ var poll_ref = JSC.PollRef.init();
+ poll_ref.ref(globalThis.bunVM());
+ this.* = .{ .globalThis = globalThis, .promise = JSC.JSPromise.Strong.init(globalThis), .poll_ref = poll_ref, .allocated = true, .name = name };
+ return this;
+ }
- pub fn init(globalThis: *JSC.JSGlobalObject, allocator: std.mem.Allocator) !*SrvLookup {
- var this = try allocator.create(SrvLookup);
- var poll_ref = JSC.PollRef.init();
- poll_ref.ref(globalThis.bunVM());
- this.* = .{
- .globalThis = globalThis,
- .promise = JSC.JSPromise.Strong.init(globalThis),
- .poll_ref = poll_ref,
- .allocated = true,
- };
- return this;
- }
+ pub fn processResolve(this: *@This(), err_: ?c_ares.Error, _: i32, result: ?*cares_type) void {
+ if (err_) |err| {
+ var promise = this.promise;
+ var globalThis = this.globalThis;
+ const error_value = globalThis.createErrorInstance("{s} lookup failed: {s}", .{ type_name, err.label() });
+ error_value.put(
+ globalThis,
+ JSC.ZigString.static("code"),
+ JSC.ZigString.init(err.code()).toValueGC(globalThis),
+ );
- pub fn processResolveSrv(this: *SrvLookup, err_: ?c_ares.Error, _: i32, result: ?*c_ares.struct_ares_srv_reply) void {
- if (err_) |err| {
- var promise = this.promise;
- var globalThis = this.globalThis;
- const error_value = globalThis.createErrorInstance("SRV lookup failed: {s}", .{err.label()});
- error_value.put(
- globalThis,
- JSC.ZigString.static("code"),
- JSC.ZigString.init(err.code()).toValueGC(globalThis),
- );
+ promise.reject(globalThis, error_value);
+ this.deinit();
+ return;
+ }
+ if (result == null) {
+ var promise = this.promise;
+ var globalThis = this.globalThis;
+ const error_value = globalThis.createErrorInstance("{s} lookup failed: {s}", .{ type_name, "No results" });
+ error_value.put(
+ globalThis,
+ JSC.ZigString.static("code"),
+ JSC.ZigString.init("EUNREACHABLE").toValueGC(globalThis),
+ );
- promise.reject(globalThis, error_value);
- this.deinit();
+ promise.reject(globalThis, error_value);
+ this.deinit();
+ return;
+ }
+ var node = result.?;
+ const array = node.toJSReponse(this.globalThis.allocator(), this.globalThis, type_name);
+ this.onComplete(array);
return;
}
- if (result == null or result.?.next == null) {
+ pub fn onComplete(this: *@This(), result: JSC.JSValue) void {
var promise = this.promise;
var globalThis = this.globalThis;
- const error_value = globalThis.createErrorInstance("SRV lookup failed: {s}", .{"No results"});
- error_value.put(
- globalThis,
- JSC.ZigString.static("code"),
- JSC.ZigString.init("EUNREACHABLE").toValueGC(globalThis),
- );
-
- promise.reject(globalThis, error_value);
+ this.promise = .{};
+ promise.resolve(globalThis, result);
this.deinit();
- return;
}
- var node = result.?;
- const array = node.toJSArray(this.globalThis.allocator(), this.globalThis);
- this.onComplete(array);
- return;
- }
- pub fn onComplete(this: *SrvLookup, result: JSC.JSValue) void {
- var promise = this.promise;
- var globalThis = this.globalThis;
- this.promise = .{};
- promise.resolve(globalThis, result);
- this.deinit();
- }
+ pub fn deinit(this: *@This()) void {
+ this.poll_ref.unrefOnNextTick(this.globalThis.bunVM());
+ this.name.deinit();
- pub fn deinit(this: *SrvLookup) void {
- this.poll_ref.unrefOnNextTick(this.globalThis.bunVM());
+ if (this.allocated)
+ this.globalThis.allocator().destroy(this);
+ }
+ };
+}
- if (this.allocated)
- this.globalThis.allocator().destroy(this);
- }
-};
pub const DNSLookup = struct {
const log = Output.scoped(.DNSLookup, true);
@@ -1141,15 +1140,30 @@ pub const DNSResolver = struct {
polls: std.AutoArrayHashMap(i32, ?*JSC.FilePoll) = undefined,
pending_host_cache_cares: PendingCache = PendingCache.init(),
- pending_srv_cache_cares: SrvPendingCache = SrvPendingCache.init(),
pending_host_cache_native: PendingCache = PendingCache.init(),
- // entry_host_cache: std.BoundedArray(128)
+ pending_srv_cache_cares: SrvPendingCache = SrvPendingCache.init(),
+ pending_soa_cache_cares: SoaPendingCache = SoaPendingCache.init(),
+ pending_txt_cache_cares: TxtPendingCache = TxtPendingCache.init(),
+ pending_naptr_cache_cares: NaptrPendingCache = NaptrPendingCache.init(),
+ pending_mx_cache_cares: MxPendingCache = MxPendingCache.init(),
+ pending_caa_cache_cares: CaaPendingCache = CaaPendingCache.init(),
+ pending_ns_cache_cares: NSPendingCache = NSPendingCache.init(),
+ pending_ptr_cache_cares: PtrPendingCache = PtrPendingCache.init(),
+ pending_cname_cache_cares: CnamePendingCache = CnamePendingCache.init(),
const PendingCache = bun.HiveArray(GetAddrInfoRequest.PendingCacheKey, 32);
- const SrvPendingCache = bun.HiveArray(ResolveSrvInfoRequest.PendingCacheKey, 32);
-
- fn getKey(this: *DNSResolver, index: u8, comptime cache_name: []const u8) GetAddrInfoRequest.PendingCacheKey {
- var cache: *PendingCache = &@field(this, cache_name);
+ const SrvPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_srv_reply, "srv").PendingCacheKey, 32);
+ const SoaPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_soa_reply, "soa").PendingCacheKey, 32);
+ const TxtPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_txt_reply, "txt").PendingCacheKey, 32);
+ const NaptrPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_naptr_reply, "naptr").PendingCacheKey, 32);
+ const MxPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_mx_reply, "mx").PendingCacheKey, 32);
+ const CaaPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_caa_reply, "caa").PendingCacheKey, 32);
+ const NSPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_hostent, "ns").PendingCacheKey, 32);
+ const PtrPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_hostent, "ptr").PendingCacheKey, 32);
+ const CnamePendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_hostent, "cname").PendingCacheKey, 32);
+
+ fn getKey(this: *DNSResolver, index: u8, comptime cache_name: []const u8, comptime request_type: type) request_type.PendingCacheKey {
+ var cache = &@field(this, cache_name);
std.debug.assert(!cache.available.isSet(index));
const entry = cache.buffer[index];
cache.buffer[index] = undefined;
@@ -1160,37 +1174,27 @@ pub const DNSResolver = struct {
return entry;
}
- fn getSrvKey(this: *DNSResolver, index: u8, comptime cache_name: []const u8) ResolveSrvInfoRequest.PendingCacheKey {
- var cache: *SrvPendingCache = &@field(this, cache_name);
- std.debug.assert(!cache.available.isSet(index));
- const entry = cache.buffer[index];
- cache.buffer[index] = undefined;
- var available = cache.available;
- available.set(index);
- cache.available = available;
-
- return entry;
- }
+ pub fn drainPendingCares(this: *DNSResolver, index: u8, err: ?c_ares.Error, timeout: i32, comptime request_type: type, comptime cares_type: type, comptime lookup_name: []const u8, result: ?*cares_type) void {
+ const cache_name = comptime std.fmt.comptimePrint("pending_{s}_cache_cares", .{lookup_name});
- pub fn drainPendingSrvCares(this: *DNSResolver, index: u8, err: ?c_ares.Error, timeout: i32, result: ?*c_ares.struct_ares_srv_reply) void {
- const key = this.getSrvKey(index, "pending_srv_cache_cares");
+ const key = this.getKey(index, cache_name, request_type);
var addr = result orelse {
- var pending: ?*SrvLookup = key.lookup.head.next;
- key.lookup.head.processResolveSrv(err, timeout, null);
+ var pending: ?*CAresLookup(cares_type, lookup_name) = key.lookup.head.next;
+ key.lookup.head.processResolve(err, timeout, null);
bun.default_allocator.destroy(key.lookup);
while (pending) |value| {
pending = value.next;
- value.processResolveSrv(err, timeout, null);
+ value.processResolve(err, timeout, null);
}
return;
};
- var pending: ?*SrvLookup = key.lookup.head.next;
+ var pending: ?*CAresLookup(cares_type, lookup_name) = key.lookup.head.next;
var prev_global = key.lookup.head.globalThis;
- var array = addr.toJSArray(this.vm.allocator, prev_global);
+ var array = addr.toJSReponse(this.vm.allocator, prev_global, lookup_name);
defer addr.deinit();
array.ensureStillAlive();
key.lookup.head.onComplete(array);
@@ -1201,7 +1205,7 @@ pub const DNSResolver = struct {
while (pending) |value| {
var new_global = value.globalThis;
if (prev_global != new_global) {
- array = addr.toJSArray(this.vm.allocator, new_global);
+ array = addr.toJSReponse(this.vm.allocator, new_global, lookup_name);
prev_global = new_global;
}
pending = value.next;
@@ -1215,7 +1219,7 @@ pub const DNSResolver = struct {
}
pub fn drainPendingHostCares(this: *DNSResolver, index: u8, err: ?c_ares.Error, timeout: i32, result: ?*c_ares.AddrInfo) void {
- const key = this.getKey(index, "pending_host_cache_cares");
+ const key = this.getKey(index, "pending_host_cache_cares", GetAddrInfoRequest);
var addr = result orelse {
var pending: ?*DNSLookup = key.lookup.head.next;
@@ -1257,7 +1261,7 @@ pub const DNSResolver = struct {
}
pub fn drainPendingHostNative(this: *DNSResolver, index: u8, globalObject: *JSC.JSGlobalObject, err: i32, result: GetAddrInfo.Result.Any) void {
- const key = this.getKey(index, "pending_host_cache_native");
+ const key = this.getKey(index, "pending_host_cache_native", GetAddrInfoRequest);
var array = result.toJS(globalObject) orelse {
var pending: ?*DNSLookup = key.lookup.head.next;
@@ -1305,18 +1309,22 @@ pub const DNSResolver = struct {
new: *GetAddrInfoRequest.PendingCacheKey,
disabled: void,
};
- pub const SrvCacheHit = union(enum) {
- inflight: *ResolveSrvInfoRequest.PendingCacheKey,
- new: *ResolveSrvInfoRequest.PendingCacheKey,
- disabled: void,
- };
- pub fn getOrPutIntoSrvPendingCache(
+ pub fn LookupCacheHit(comptime request_type: type) type {
+ return union(enum) {
+ inflight: *request_type.PendingCacheKey,
+ new: *request_type.PendingCacheKey,
+ disabled: void,
+ };
+ }
+
+ pub fn getOrPutIntoResolvePendingCache(
this: *DNSResolver,
- key: ResolveSrvInfoRequest.PendingCacheKey,
- comptime field: std.meta.FieldEnum(DNSResolver),
- ) SrvCacheHit {
- var cache: *SrvPendingCache = &@field(this, @tagName(field));
+ comptime request_type: type,
+ key: request_type.PendingCacheKey,
+ comptime field: []const u8,
+ ) LookupCacheHit(request_type) {
+ var cache = &@field(this, field);
var inflight_iter = cache.available.iterator(
.{
.kind = .unset,
@@ -1324,7 +1332,7 @@ pub const DNSResolver = struct {
);
while (inflight_iter.next()) |index| {
- var entry: *ResolveSrvInfoRequest.PendingCacheKey = &cache.buffer[index];
+ var entry: *request_type.PendingCacheKey = &cache.buffer[index];
if (entry.hash == key.hash and entry.len == key.len) {
return .{ .inflight = entry };
}
@@ -1504,7 +1512,6 @@ pub const DNSResolver = struct {
return .zero;
};
};
- _ = record_type;
const name_value = arguments.ptr[0];
@@ -1522,9 +1529,44 @@ pub const DNSResolver = struct {
return .zero;
}
- // const name = name_str.toSliceZ(globalThis).cloneZ(bun.default_allocator) catch unreachable;
- // TODO:
- return JSC.JSValue.jsUndefined();
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+ //TODO: ANY CASE
+ switch (record_type) {
+ RecordType.A => {
+ defer name.deinit();
+ const options = GetAddrInfo.Options{ .family = GetAddrInfo.Family.inet };
+ return resolver.doLookup(name.slice(), 0, options, globalThis);
+ },
+ RecordType.AAAA => {
+ defer name.deinit();
+ const options = GetAddrInfo.Options{ .family = GetAddrInfo.Family.inet6 };
+ return resolver.doLookup(name.slice(), 0, options, globalThis);
+ },
+ RecordType.CNAME => {
+ return resolver.doResolveCAres(c_ares.struct_hostent, "cname", &name, globalThis);
+ },
+ RecordType.MX => {
+ return resolver.doResolveCAres(c_ares.struct_ares_mx_reply, "mx", &name, globalThis);
+ },
+ RecordType.NS => {
+ return resolver.doResolveCAres(c_ares.struct_hostent, "ns", &name, globalThis);
+ },
+ RecordType.PTR => {
+ return resolver.doResolveCAres(c_ares.struct_hostent, "ptr", &name, globalThis);
+ },
+ RecordType.SOA => {
+ return resolver.doResolveCAres(c_ares.struct_ares_soa_reply, "soa", &name, globalThis);
+ },
+ RecordType.SRV => {
+ return resolver.doResolveCAres(c_ares.struct_ares_srv_reply, "srv", &name, globalThis);
+ },
+ RecordType.TXT => {
+ return resolver.doResolveCAres(c_ares.struct_ares_txt_reply, "txt", &name, globalThis);
+ },
+ }
}
// pub fn reverse(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
// const arguments = callframe.arguments(3);
@@ -1622,14 +1664,264 @@ pub const DNSResolver = struct {
}
const name = name_str.toSlice(globalThis, bun.default_allocator);
- defer name.deinit();
+
var vm = globalThis.bunVM();
var resolver = vm.rareData().globalDNSResolver(vm);
- return resolver.doResolveSrv(name.slice(), globalThis);
+ return resolver.doResolveCAres(c_ares.struct_ares_srv_reply, "srv", &name, globalThis);
}
- pub fn doResolveSrv(this: *DNSResolver, name: []const u8, globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ pub fn resolveSoa(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveSoa", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveSoa", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveSoa", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_ares_soa_reply, "soa", &name, globalThis);
+ }
+
+ pub fn resolveCaa(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveCaa", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveCaa", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveCaa", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_ares_caa_reply, "caa", &name, globalThis);
+ }
+
+ pub fn resolveNs(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveNs", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveNs", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveNs", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_hostent, "ns", &name, globalThis);
+ }
+
+ pub fn resolvePtr(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolvePtr", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolvePtr", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolvePtr", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_hostent, "ptr", &name, globalThis);
+ }
+
+ pub fn resolveCname(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveCname", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveCname", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveCname", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_hostent, "cname", &name, globalThis);
+ }
+
+ pub fn resolveMx(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveMx", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveMx", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveMx", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_ares_mx_reply, "mx", &name, globalThis);
+ }
+
+ pub fn resolveNaptr(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveNaptr", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveNaptr", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveNaptr", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_ares_naptr_reply, "naptr", &name, globalThis);
+ }
+
+ pub fn resolveTxt(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ if (arguments.len < 1) {
+ globalThis.throwNotEnoughArguments("resolveTxt", 2, arguments.len);
+ return .zero;
+ }
+
+ const name_value = arguments.ptr[0];
+
+ if (name_value.isEmptyOrUndefinedOrNull() or !name_value.isString()) {
+ globalThis.throwInvalidArgumentType("resolveTxt", "hostname", "string");
+ return .zero;
+ }
+
+ const name_str = name_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+
+ if (name_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("resolveTxt", "hostname", "non-empty string");
+ return .zero;
+ }
+
+ const name = name_str.toSlice(globalThis, bun.default_allocator);
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+
+ return resolver.doResolveCAres(c_ares.struct_ares_txt_reply, "txt", &name, globalThis);
+ }
+
+ pub fn doResolveCAres(this: *DNSResolver, comptime cares_type: type, comptime type_name: []const u8, name_str: *const JSC.ZigString.Slice, globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ var name = name_str.slice();
+
var channel: *c_ares.Channel = switch (this.getChannel()) {
.result => |res| res,
.err => |err| {
@@ -1644,29 +1936,34 @@ pub const DNSResolver = struct {
},
};
- const key = ResolveSrvInfoRequest.PendingCacheKey.init(name);
+ const cache_name = comptime std.fmt.comptimePrint("pending_{s}_cache_cares", .{type_name});
+
+ const key = ResolveInfoRequest(cares_type, type_name).PendingCacheKey.init(name);
- var cache = this.getOrPutIntoSrvPendingCache(key, .pending_srv_cache_cares);
+ var cache = this.getOrPutIntoResolvePendingCache(ResolveInfoRequest(cares_type, type_name), key, cache_name);
if (cache == .inflight) {
- var srv_lookup = SrvLookup.init(globalThis, globalThis.allocator()) catch unreachable;
- cache.inflight.append(srv_lookup);
- return srv_lookup.promise.value();
+ // CAresLookup will have the name ownership
+ var cares_lookup = CAresLookup(cares_type, type_name).init(globalThis, globalThis.allocator(), name_str) catch unreachable;
+ cache.inflight.append(cares_lookup);
+ return cares_lookup.promise.value();
}
- var request = ResolveSrvInfoRequest.init(
+ var request = ResolveInfoRequest(cares_type, type_name).init(
cache,
this,
- name,
+ name_str, // CAresLookup will have the ownership
globalThis,
- "pending_srv_cache_cares",
+ cache_name,
) catch unreachable;
const promise = request.tail.promise.value();
- channel.resolveSrv(
+ channel.resolve(
name,
- ResolveSrvInfoRequest,
+ type_name,
+ ResolveInfoRequest(cares_type, type_name),
request,
- ResolveSrvInfoRequest.onCaresComplete,
+ cares_type,
+ ResolveInfoRequest(cares_type, type_name).onCaresComplete,
);
return promise;
@@ -1722,17 +2019,71 @@ pub const DNSResolver = struct {
comptime {
@export(
+ resolve,
+ .{
+ .name = "Bun__DNSResolver__resolve",
+ },
+ );
+ @export(
lookup,
.{
.name = "Bun__DNSResolver__lookup",
},
);
@export(
+ resolveTxt,
+ .{
+ .name = "Bun__DNSResolver__resolveTxt",
+ },
+ );
+ @export(
+ resolveSoa,
+ .{
+ .name = "Bun__DNSResolver__resolveSoa",
+ },
+ );
+ @export(
+ resolveMx,
+ .{
+ .name = "Bun__DNSResolver__resolveMx",
+ },
+ );
+ @export(
+ resolveNaptr,
+ .{
+ .name = "Bun__DNSResolver__resolveNaptr",
+ },
+ );
+ @export(
resolveSrv,
.{
.name = "Bun__DNSResolver__resolveSrv",
},
);
+ @export(
+ resolveCaa,
+ .{
+ .name = "Bun__DNSResolver__resolveCaa",
+ },
+ );
+ @export(
+ resolveNs,
+ .{
+ .name = "Bun__DNSResolver__resolveNs",
+ },
+ );
+ @export(
+ resolvePtr,
+ .{
+ .name = "Bun__DNSResolver__resolvePtr",
+ },
+ );
+ @export(
+ resolveCname,
+ .{
+ .name = "Bun__DNSResolver__resolveCname",
+ },
+ );
}
// pub fn lookupService(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
// const arguments = callframe.arguments(3);
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 58497cad4..fb429340f 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -2172,7 +2172,16 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotask, (JSGlobalObject * globalObj
}
extern "C" EncodedJSValue Bun__DNSResolver__lookup(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolve(JSGlobalObject*, JSC::CallFrame*);
extern "C" EncodedJSValue Bun__DNSResolver__resolveSrv(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveTxt(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveSoa(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveNaptr(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveMx(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveCaa(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveNs(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolvePtr(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__resolveCname(JSGlobalObject*, JSC::CallFrame*);
JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotaskVariadic, (JSGlobalObject * globalObject, CallFrame* callframe))
{
@@ -3325,8 +3334,26 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count, JSC::VM& vm
JSC::JSObject* dnsObject = JSC::constructEmptyObject(this);
dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "lookup"_s), 2, Bun__DNSResolver__lookup, ImplementationVisibility::Public, NoIntrinsic,
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolve"_s), 2, Bun__DNSResolver__resolve, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveSrv"_s), 2, Bun__DNSResolver__resolveSrv, ImplementationVisibility::Public, NoIntrinsic,
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveTxt"_s), 2, Bun__DNSResolver__resolveTxt, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveSoa"_s), 2, Bun__DNSResolver__resolveSoa, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveNaptr"_s), 2, Bun__DNSResolver__resolveNaptr, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveMx"_s), 2, Bun__DNSResolver__resolveMx, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveCaa"_s), 2, Bun__DNSResolver__resolveCaa, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveNs"_s), 2, Bun__DNSResolver__resolveNs, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolvePtr"_s), 2, Bun__DNSResolver__resolvePtr, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "resolveCname"_s), 2, Bun__DNSResolver__resolveCname, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
object->putDirect(vm, PropertyName(identifier), dnsObject, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
}
diff --git a/src/bun.js/node-dns.exports.js b/src/bun.js/node-dns.exports.js
index 864edfdbb..0bcc915cd 100644
--- a/src/bun.js/node-dns.exports.js
+++ b/src/bun.js/node-dns.exports.js
@@ -40,6 +40,128 @@ function resolveSrv(hostname, callback) {
);
}
+
+function resolveTxt(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveTxt(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolveSoa(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveSoa(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolveNaptr(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveNaptr(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolveMx(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveMx(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+
+}
+
+function resolveCaa(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveCaa(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolveNs(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveNs(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolvePtr(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolvePtr(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
+function resolveCname(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveCname(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
function lookupService(address, port, callback) {
if (typeof callback != "function") {
throw new TypeError("callback must be a function");
@@ -49,9 +171,9 @@ function lookupService(address, port, callback) {
}
var InternalResolver = class Resolver {
- constructor(options) {}
+ constructor(options) { }
- cancel() {}
+ cancel() { }
getServers() {
return [];
@@ -66,13 +188,22 @@ var InternalResolver = class Resolver {
throw new TypeError("callback must be a function");
}
- dns.lookup(hostname).then(
- (addresses) => {
- callback(
- null,
- hostname,
- addresses.map(({ address }) => address),
- );
+ dns.resolve(hostname).then(
+ (results) => {
+ switch (rrtype?.toLowerCase()) {
+ case 'a':
+ case 'aaaa':
+ callback(
+ null,
+ hostname,
+ results.map(({ address }) => address),
+ );
+ break;
+ default:
+ callback(null, results);
+ break;
+ }
+
},
(error) => {
callback(error);
@@ -129,27 +260,79 @@ var InternalResolver = class Resolver {
}
resolveCname(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveCname(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
resolveMx(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveMx(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+
}
resolveNaptr(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveNaptr(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
resolveNs(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveNs(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
resolvePtr(hostname, callback) {
- callback(null, []);
- }
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
- resolveSoa(hostname, callback) {
- callback(null, []);
+ dns.resolvePtr(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
resolveSrv(hostname, callback) {
@@ -168,20 +351,88 @@ var InternalResolver = class Resolver {
}
resolveCaa(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveCaa(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
resolveTxt(hostname, callback) {
- callback(null, []);
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveTxt(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+ }
+ resolveSoa(hostname, callback) {
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolveSoa(hostname, callback).then(
+ (results) => {
+ callback(null, results);
+ },
+ (error) => {
+ callback(error);
+ },
+ );
}
reverse(ip, callback) {
callback(null, []);
}
- setServers(servers) {}
+ setServers(servers) { }
};
+function resolve(hostname, rrtype, callback) {
+ if (typeof rrtype == "function") {
+ callback = rrtype;
+ }
+
+ if (typeof callback != "function") {
+ throw new TypeError("callback must be a function");
+ }
+
+ dns.resolve(hostname).then(
+ (results) => {
+ switch (rrtype?.toLowerCase()) {
+ case 'a':
+ case 'aaaa':
+ callback(
+ null,
+ hostname,
+ results.map(({ address }) => address),
+ );
+ break;
+ default:
+ callback(null, results);
+ break;
+ }
+
+ },
+ (error) => {
+ callback(error);
+ },
+ );
+}
+
function Resolver(options) {
return new InternalResolver(options);
}
@@ -205,8 +456,8 @@ export var {
resolveTxt,
} = InternalResolver.prototype;
-function setDefaultResultOrder() {}
-function setServers() {}
+function setDefaultResultOrder() { }
+function setServers() { }
const promisifyLookup = (res) => {
res.sort((a, b) => a.family - b.family);
@@ -214,6 +465,21 @@ const promisifyLookup = (res) => {
return { address, family };
};
+const promisifyResolve = (rrtype) => {
+ switch (rrtype?.toLowerCase()) {
+ case 'a':
+ case 'aaaa':
+ return (res) => {
+
+ res.sort((a, b) => a.family - b.family);
+ const [{ address, family }] = res;
+ return { address, family };
+ };
+ default:
+ return (res) => res;
+ }
+}
+
// promisified versions
export const promises = {
lookup(domain, options) {
@@ -225,7 +491,7 @@ export const promises = {
},
resolve(hostname, rrtype) {
- return dns.lookup(hostname);
+ return dns.resolve(hostname, rrtype).then(promisifyResolve);
},
resolve4(hostname, options) {
@@ -239,18 +505,43 @@ export const promises = {
resolveSrv(hostname) {
return dns.resolveSrv(hostname);
},
+ resolveTxt(hostname) {
+ return dns.resolveTxt(hostname);
+ },
+ resolveSoa(hostname) {
+ return dns.resolveSoa(hostname);
+ },
+ resolveNaptr(hostname) {
+ return dns.resolveNaptr(hostname);
+ },
+
+ resolveMx(hostname) {
+ return dns.resolveMx(hostname);
+ },
+ resolveCaa(hostname) {
+ return dns.resolveCaa(hostname);
+ },
+ resolveNs(hostname) {
+ return dns.resolveNs(hostname);
+ },
+ resolvePtr(hostname) {
+ return dns.resolvePtr(hostname);
+ },
+ resolveCname(hostname) {
+ return dns.resolveCname(hostname);
+ },
Resolver: class Resolver {
- constructor(options) {}
+ constructor(options) { }
- cancel() {}
+ cancel() { }
getServers() {
return [];
}
resolve(hostname, rrtype) {
- return dns.lookup(hostname);
+ return dns.resolve(hostname, rrtype).then(promisifyResolve);
}
resolve4(hostname, options) {
@@ -266,27 +557,27 @@ export const promises = {
}
resolveCname(hostname) {
- return Promise.resolve([]);
+ return dns.resolveCname(hostname);
}
resolveMx(hostname) {
- return Promise.resolve([]);
+ return dns.resolveMx(hostname);
}
resolveNaptr(hostname) {
- return Promise.resolve([]);
+ return dns.resolveNaptr(hostname);
}
resolveNs(hostname) {
- return Promise.resolve([]);
+ return dns.resolveNs(hostname);
}
resolvePtr(hostname) {
- return Promise.resolve([]);
+ return dns.resolvePtr(hostname);
}
resolveSoa(hostname) {
- return Promise.resolve([]);
+ return dns.resolveSoa(hostname);
}
resolveSrv(hostname) {
@@ -294,30 +585,22 @@ export const promises = {
}
resolveCaa(hostname) {
- return Promise.resolve([]);
+ return dns.resolveCaa(hostname);
}
resolveTxt(hostname) {
- return Promise.resolve([]);
+ return dns.resolveTxt(hostname);
}
reverse(ip) {
return Promise.resolve([]);
}
- setServers(servers) {}
+ setServers(servers) { }
},
};
for (const key of [
"resolveAny",
- "resolveCname",
- "resolveCaa",
- "resolveMx",
- "resolveNaptr",
- "resolveNs",
- "resolvePtr",
- "resolveSoa",
- "resolveTxt",
"reverse",
]) {
promises[key] = () => Promise.resolve(undefined);
@@ -369,12 +652,12 @@ const exports = {
resolveCname,
resolveCaa,
resolveMx,
- resolveNaptr,
resolveNs,
resolvePtr,
resolveSoa,
resolveSrv,
resolveTxt,
+ resolveNaptr,
promises,
[Symbol.for("CommonJS")]: 0,
};
diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig
index 4f30aadae..4dc5d0bd0 100644
--- a/src/bun.js/webcore/encoding.zig
+++ b/src/bun.js/webcore/encoding.zig
@@ -860,14 +860,12 @@ pub const Encoder = struct {
switch (comptime encoding) {
JSC.Node.Encoding.buffer => {
-
const written = @min(len, to_len);
@memcpy(to, input, written);
return @intCast(i64, written);
},
.latin1, .ascii => {
-
const written = @min(len, to_len);
@memcpy(to, input, written);
@@ -899,7 +897,6 @@ pub const Encoder = struct {
var written = strings.copyLatin1IntoUTF16([]align(1) u16, output, []const u8, buf).written;
return written * 2;
-
}
},
@@ -908,7 +905,6 @@ pub const Encoder = struct {
},
JSC.Node.Encoding.base64url => {
-
var slice = strings.trim(input[0..len], "\r\n\t " ++ [_]u8{std.ascii.control_code.vt});
if (slice.len == 0)
return 0;
@@ -948,7 +944,7 @@ pub const Encoder = struct {
},
JSC.Node.Encoding.hex => {
- return len / 2;
+ return len / 2;
},
JSC.Node.Encoding.base64, JSC.Node.Encoding.base64url => {
@@ -972,12 +968,12 @@ pub const Encoder = struct {
},
// string is already encoded, just need to copy the data
JSC.Node.Encoding.ucs2, JSC.Node.Encoding.utf16le => {
- var bytes_input_len = len * 2;
- var written = @min(bytes_input_len, to_len);
+ const bytes_input_len = len * 2;
+ const written = @min(bytes_input_len, to_len);
if (written < 2) return 0;
- var fixed_len = (written/2) * 2;
- var input_u8 = @ptrCast([*] const u8, input);
+ const fixed_len = (written / 2) * 2;
+ const input_u8 = @ptrCast([*]const u8, input);
strings.copyU16IntoU8(to[0..written], []const u8, input_u8[0..fixed_len]);
return @intCast(i64, written);
},