@@ -117,9 +117,66 @@ local function dns_lookup(records, dns_resolver, host, query_type, filter_type,
117
117
for rec in each_matching_record (packet , host , filter_type ) do
118
118
local t = rec :type ()
119
119
if t == cqueues_dns_record .AAAA then
120
- table.insert ( records , { family = cs . AF_INET6 , host = rec :addr () } )
120
+ records : add_v6 ( rec :addr ())
121
121
elseif t == cqueues_dns_record .A then
122
- table.insert (records , { family = cs .AF_INET , host = rec :addr () })
122
+ records :add_v4 (rec :addr ())
123
+ end
124
+ end
125
+ end
126
+
127
+ local records_methods = {}
128
+ local records_mt = {
129
+ __name = " http.client.records" ;
130
+ __index = records_methods ;
131
+ }
132
+
133
+ local function new_records ()
134
+ return setmetatable ({
135
+ n = 0 ;
136
+ nil -- preallocate space for one
137
+ }, records_mt )
138
+ end
139
+
140
+ function records_mt :__len ()
141
+ return self .n
142
+ end
143
+
144
+ function records_methods :add_v4 (addr )
145
+ local n = self .n + 1
146
+ self [n ] = {
147
+ family = cs .AF_INET ;
148
+ addr = addr ;
149
+ }
150
+ self .n = n
151
+ end
152
+
153
+ function records_methods :add_v6 (addr )
154
+ local n = self .n + 1
155
+ self [n ] = {
156
+ family = cs .AF_INET6 ;
157
+ addr = addr ;
158
+ }
159
+ self .n = n
160
+ end
161
+
162
+ function records_methods :add_unix (path )
163
+ local n = self .n + 1
164
+ self [n ] = {
165
+ family = cs .AF_UNIX ;
166
+ path = path ;
167
+ }
168
+ self .n = n
169
+ end
170
+
171
+ function records_methods :remove_family (family )
172
+ if family == nil then
173
+ family = AF_UNSPEC
174
+ end
175
+
176
+ for i = self .n , 1 , - 1 do
177
+ if self [i ].family == family then
178
+ table.remove (self , i )
179
+ self .n = self .n - 1
123
180
end
124
181
end
125
182
end
@@ -142,15 +199,19 @@ local function connect(options, timeout)
142
199
local deadline = timeout and monotime ()+ timeout
143
200
144
201
local host = options .host
145
- local records
202
+
203
+ local records = new_records ()
204
+
146
205
if path then
147
- records = { { family = family , path = path } }
206
+ records : add_unix ( path )
148
207
elseif http_util .is_ip (host ) then
149
- family = host :find (" :" , 1 , true ) and cs .AF_INET6 or cs .AF_INET
150
- records = { { family = family , host = host } }
208
+ if host :find (" :" , 1 , true ) then
209
+ records :add_v6 (host )
210
+ else
211
+ records :add_v4 (host )
212
+ end
151
213
else
152
214
local dns_resolver = options .dns_resolver or cqueues_dns .getpool ()
153
- records = {}
154
215
if family == cs .AF_UNSPEC then
155
216
dns_lookup (records , dns_resolver , host , cqueues_dns_record .AAAA , nil , timeout )
156
217
dns_lookup (records , dns_resolver , host , cqueues_dns_record .A , nil , deadline and deadline - monotime ())
@@ -194,11 +255,10 @@ local function connect(options, timeout)
194
255
195
256
local lasterr , lasterrno = " The name does not resolve for the supplied parameters"
196
257
local i = 1
197
- local n = # records
198
- while i <= n do
258
+ while i <= records .n do
199
259
local rec = records [i ]
200
260
connect_params .family = rec .family ;
201
- connect_params .host = rec .host ;
261
+ connect_params .host = rec .addr ;
202
262
connect_params .path = rec .path ;
203
263
local s
204
264
s , lasterr , lasterrno = ca .fileresult (cs .connect (connect_params ))
@@ -221,15 +281,7 @@ local function connect(options, timeout)
221
281
if lasterrno == ce .EAFNOSUPPORT then
222
282
-- If an address family is not supported then entirely remove that
223
283
-- family from candidate records
224
- local af = connect_params .family
225
- for j = n , i + 1 , - 1 do
226
- if records [j ].family == af then
227
- table.remove (records , j )
228
- n = n - 1
229
- end
230
- end
231
- table.remove (records , i )
232
- n = n - 1
284
+ records :remove_family (connect_params .family )
233
285
else
234
286
i = i + 1
235
287
end
0 commit comments