1 /*
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include "ts_lua_util.h"
22
23 static void ts_lua_inject_client_request_client_addr_api(lua_State *L);
24 static void ts_lua_inject_client_request_server_addr_api(lua_State *L);
25
26 static int ts_lua_client_request_header_get(lua_State *L);
27 static int ts_lua_client_request_header_set(lua_State *L);
28 static int ts_lua_client_request_get_headers(lua_State *L);
29 static int ts_lua_client_request_get_url(lua_State *L);
30 static int ts_lua_client_request_get_pristine_url(lua_State *L);
31 static int ts_lua_client_request_get_url_host(lua_State *L);
32 static int ts_lua_client_request_set_url_host(lua_State *L);
33 static int ts_lua_client_request_get_url_port(lua_State *L);
34 static int ts_lua_client_request_set_url_port(lua_State *L);
35 static int ts_lua_client_request_get_url_scheme(lua_State *L);
36 static int ts_lua_client_request_set_url_scheme(lua_State *L);
37
38 static int ts_lua_client_request_get_uri(lua_State *L);
39 static int ts_lua_client_request_set_uri(lua_State *L);
40 static int ts_lua_client_request_set_uri_args(lua_State *L);
41 static int ts_lua_client_request_get_uri_args(lua_State *L);
42 static int ts_lua_client_request_set_uri_params(lua_State *L);
43 static int ts_lua_client_request_get_uri_params(lua_State *L);
44 static int ts_lua_client_request_get_method(lua_State *L);
45 static int ts_lua_client_request_set_method(lua_State *L);
46 static int ts_lua_client_request_get_version(lua_State *L);
47 static int ts_lua_client_request_set_version(lua_State *L);
48
49 static int ts_lua_client_request_get_body_size(lua_State *L);
50 static int ts_lua_client_request_get_header_size(lua_State *L);
51
52 static void ts_lua_inject_client_request_socket_api(lua_State *L);
53 static void ts_lua_inject_client_request_header_api(lua_State *L);
54 static void ts_lua_inject_client_request_headers_api(lua_State *L);
55 static void ts_lua_inject_client_request_url_api(lua_State *L);
56 static void ts_lua_inject_client_request_uri_api(lua_State *L);
57 static void ts_lua_inject_client_request_args_api(lua_State *L);
58 static void ts_lua_inject_client_request_params_api(lua_State *L);
59 static void ts_lua_inject_client_request_method_api(lua_State *L);
60 static void ts_lua_inject_client_request_version_api(lua_State *L);
61 static void ts_lua_inject_client_request_body_size_api(lua_State *L);
62 static void ts_lua_inject_client_request_header_size_api(lua_State *L);
63
64 static int ts_lua_client_request_client_addr_get_ip(lua_State *L);
65 static int ts_lua_client_request_client_addr_get_port(lua_State *L);
66 static int ts_lua_client_request_client_addr_get_addr(lua_State *L);
67 static int ts_lua_client_request_client_addr_get_incoming_port(lua_State *L);
68
69 static void ts_lua_inject_client_request_ssl_reused_api(lua_State *L);
70 static int ts_lua_client_request_get_ssl_reused(lua_State *L);
71 static void ts_lua_inject_client_request_ssl_cipher_api(lua_State *L);
72 static int ts_lua_client_request_get_ssl_cipher(lua_State *L);
73 static void ts_lua_inject_client_request_ssl_protocol_api(lua_State *L);
74 static int ts_lua_client_request_get_ssl_protocol(lua_State *L);
75 static void ts_lua_inject_client_request_ssl_curve_api(lua_State *L);
76 static int ts_lua_client_request_get_ssl_curve(lua_State *L);
77
78 void
ts_lua_inject_client_request_api(lua_State * L)79 ts_lua_inject_client_request_api(lua_State *L)
80 {
81 lua_newtable(L);
82
83 ts_lua_inject_client_request_socket_api(L);
84 ts_lua_inject_client_request_header_api(L);
85 ts_lua_inject_client_request_headers_api(L);
86 ts_lua_inject_client_request_url_api(L);
87 ts_lua_inject_client_request_uri_api(L);
88 ts_lua_inject_client_request_args_api(L);
89 ts_lua_inject_client_request_params_api(L);
90 ts_lua_inject_client_request_method_api(L);
91 ts_lua_inject_client_request_version_api(L);
92 ts_lua_inject_client_request_body_size_api(L);
93 ts_lua_inject_client_request_header_size_api(L);
94 ts_lua_inject_client_request_ssl_reused_api(L);
95 ts_lua_inject_client_request_ssl_cipher_api(L);
96 ts_lua_inject_client_request_ssl_protocol_api(L);
97 ts_lua_inject_client_request_ssl_curve_api(L);
98
99 lua_setfield(L, -2, "client_request");
100 }
101
102 static void
ts_lua_inject_client_request_socket_api(lua_State * L)103 ts_lua_inject_client_request_socket_api(lua_State *L)
104 {
105 ts_lua_inject_client_request_client_addr_api(L);
106 ts_lua_inject_client_request_server_addr_api(L);
107 }
108
109 static void
ts_lua_inject_client_request_client_addr_api(lua_State * L)110 ts_lua_inject_client_request_client_addr_api(lua_State *L)
111 {
112 lua_newtable(L);
113
114 lua_pushcfunction(L, ts_lua_client_request_client_addr_get_ip);
115 lua_setfield(L, -2, "get_ip");
116
117 lua_pushcfunction(L, ts_lua_client_request_client_addr_get_port);
118 lua_setfield(L, -2, "get_port");
119
120 lua_pushcfunction(L, ts_lua_client_request_client_addr_get_addr);
121 lua_setfield(L, -2, "get_addr");
122
123 lua_pushcfunction(L, ts_lua_client_request_client_addr_get_incoming_port);
124 lua_setfield(L, -2, "get_incoming_port");
125
126 lua_setfield(L, -2, "client_addr");
127 }
128
129 static void
ts_lua_inject_client_request_server_addr_api(lua_State * L ATS_UNUSED)130 ts_lua_inject_client_request_server_addr_api(lua_State *L ATS_UNUSED)
131 {
132 return;
133 }
134
135 static void
ts_lua_inject_client_request_header_api(lua_State * L)136 ts_lua_inject_client_request_header_api(lua_State *L)
137 {
138 lua_newtable(L); /* .header */
139
140 lua_createtable(L, 0, 2); /* metatable for .header */
141
142 lua_pushcfunction(L, ts_lua_client_request_header_get);
143 lua_setfield(L, -2, "__index");
144 lua_pushcfunction(L, ts_lua_client_request_header_set);
145 lua_setfield(L, -2, "__newindex");
146
147 lua_setmetatable(L, -2);
148
149 lua_setfield(L, -2, "header");
150 }
151
152 static int
ts_lua_client_request_header_get(lua_State * L)153 ts_lua_client_request_header_get(lua_State *L)
154 {
155 const char *key;
156 const char *val;
157 int val_len;
158 size_t key_len;
159 int count;
160
161 TSMLoc field_loc, next_field_loc;
162 ts_lua_http_ctx *http_ctx;
163
164 GET_HTTP_CONTEXT(http_ctx, L);
165
166 /* we skip the first argument that is the table */
167 key = luaL_checklstring(L, 2, &key_len);
168
169 if (key && key_len) {
170 field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);
171
172 if (field_loc != TS_NULL_MLOC) {
173 count = 0;
174 while (field_loc != TS_NULL_MLOC) {
175 val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len);
176 next_field_loc = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
177 lua_pushlstring(L, val, val_len);
178 count++;
179 // multiple headers with the same name must be semantically the same as one value which is comma separated
180 if (next_field_loc != TS_NULL_MLOC) {
181 lua_pushlstring(L, ",", 1);
182 count++;
183 }
184 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
185 field_loc = next_field_loc;
186 }
187 lua_concat(L, count);
188 } else {
189 lua_pushnil(L);
190 }
191
192 } else {
193 lua_pushnil(L);
194 }
195
196 return 1;
197 }
198
199 static int
ts_lua_client_request_header_set(lua_State * L)200 ts_lua_client_request_header_set(lua_State *L)
201 {
202 const char *key;
203 const char *val;
204 size_t val_len;
205 size_t key_len;
206 int remove;
207 int first;
208
209 TSMLoc field_loc, tmp;
210
211 ts_lua_http_ctx *http_ctx;
212
213 GET_HTTP_CONTEXT(http_ctx, L);
214
215 remove = 0;
216 val = NULL;
217
218 /* we skip the first argument that is the table */
219 key = luaL_checklstring(L, 2, &key_len);
220 if (lua_isnil(L, 3)) {
221 remove = 1;
222 } else {
223 val = luaL_checklstring(L, 3, &val_len);
224 }
225
226 field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);
227
228 if (remove) {
229 while (field_loc != TS_NULL_MLOC) {
230 tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
231 TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
232 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
233 field_loc = tmp;
234 }
235 } else if (field_loc != TS_NULL_MLOC) {
236 first = 1;
237 while (field_loc != TS_NULL_MLOC) {
238 tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
239 if (first) {
240 first = 0;
241 TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len);
242 } else {
243 TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
244 }
245 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
246 field_loc = tmp;
247 }
248 } else if (TSMimeHdrFieldCreateNamed(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len, &field_loc) !=
249 TS_SUCCESS) {
250 TSError("[ts_lua][%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__);
251 return 0;
252
253 } else {
254 TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len);
255 TSMimeHdrFieldAppend(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
256 }
257
258 if (field_loc != TS_NULL_MLOC) {
259 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
260 }
261
262 return 0;
263 }
264
265 static void
ts_lua_inject_client_request_headers_api(lua_State * L)266 ts_lua_inject_client_request_headers_api(lua_State *L)
267 {
268 lua_pushcfunction(L, ts_lua_client_request_get_headers);
269 lua_setfield(L, -2, "get_headers");
270 }
271
272 static int
ts_lua_client_request_get_headers(lua_State * L)273 ts_lua_client_request_get_headers(lua_State *L)
274 {
275 const char *name;
276 const char *value;
277 int name_len;
278 int value_len;
279 TSMLoc field_loc;
280 TSMLoc next_field_loc;
281 const char *tvalue;
282 size_t tvalue_len;
283
284 ts_lua_http_ctx *http_ctx;
285
286 GET_HTTP_CONTEXT(http_ctx, L);
287
288 lua_newtable(L);
289
290 field_loc = TSMimeHdrFieldGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, 0);
291
292 while (field_loc != TS_NULL_MLOC) {
293 name = TSMimeHdrFieldNameGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, &name_len);
294 if (name && name_len) {
295 // retrieve the header name from table
296 lua_pushlstring(L, name, name_len);
297 lua_gettable(L, -2);
298 if (lua_isnil(L, -1)) {
299 // if header name does not exist in the table, insert it
300 lua_pop(L, 1);
301 value =
302 TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len);
303 lua_pushlstring(L, name, name_len);
304 lua_pushlstring(L, value, value_len);
305 lua_rawset(L, -3);
306 } else {
307 // if header name exists in the table, append a command and the new value to the end of the existing value
308 tvalue = lua_tolstring(L, -1, &tvalue_len);
309 lua_pop(L, 1);
310 value =
311 TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len);
312 lua_pushlstring(L, name, name_len);
313 lua_pushlstring(L, tvalue, tvalue_len);
314 lua_pushlstring(L, ",", 1);
315 lua_pushlstring(L, value, value_len);
316 lua_concat(L, 3);
317 lua_rawset(L, -3);
318 }
319 }
320
321 next_field_loc = TSMimeHdrFieldNext(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
322 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
323 field_loc = next_field_loc;
324 }
325
326 return 1;
327 }
328
329 static void
ts_lua_inject_client_request_url_api(lua_State * L)330 ts_lua_inject_client_request_url_api(lua_State *L)
331 {
332 lua_pushcfunction(L, ts_lua_client_request_get_url);
333 lua_setfield(L, -2, "get_url");
334
335 lua_pushcfunction(L, ts_lua_client_request_get_pristine_url);
336 lua_setfield(L, -2, "get_pristine_url");
337
338 lua_pushcfunction(L, ts_lua_client_request_get_url_host);
339 lua_setfield(L, -2, "get_url_host");
340 lua_pushcfunction(L, ts_lua_client_request_set_url_host);
341 lua_setfield(L, -2, "set_url_host");
342
343 lua_pushcfunction(L, ts_lua_client_request_get_url_port);
344 lua_setfield(L, -2, "get_url_port");
345 lua_pushcfunction(L, ts_lua_client_request_set_url_port);
346 lua_setfield(L, -2, "set_url_port");
347
348 lua_pushcfunction(L, ts_lua_client_request_get_url_scheme);
349 lua_setfield(L, -2, "get_url_scheme");
350 lua_pushcfunction(L, ts_lua_client_request_set_url_scheme);
351 lua_setfield(L, -2, "set_url_scheme");
352 }
353
354 static void
ts_lua_inject_client_request_uri_api(lua_State * L)355 ts_lua_inject_client_request_uri_api(lua_State *L)
356 {
357 lua_pushcfunction(L, ts_lua_client_request_set_uri);
358 lua_setfield(L, -2, "set_uri");
359
360 lua_pushcfunction(L, ts_lua_client_request_get_uri);
361 lua_setfield(L, -2, "get_uri");
362 }
363
364 static int
ts_lua_client_request_get_url(lua_State * L)365 ts_lua_client_request_get_url(lua_State *L)
366 {
367 char *url;
368 int url_len;
369
370 ts_lua_http_ctx *http_ctx;
371
372 GET_HTTP_CONTEXT(http_ctx, L);
373
374 url = TSHttpTxnEffectiveUrlStringGet(http_ctx->txnp, &url_len);
375
376 if (url) {
377 lua_pushlstring(L, url, url_len);
378 TSfree(url);
379
380 } else {
381 lua_pushnil(L);
382 }
383
384 return 1;
385 }
386
387 static int
ts_lua_client_request_get_pristine_url(lua_State * L)388 ts_lua_client_request_get_pristine_url(lua_State *L)
389 {
390 char *url;
391 int url_len;
392
393 TSMBuffer bufp;
394 TSMLoc url_loc;
395
396 ts_lua_http_ctx *http_ctx;
397
398 GET_HTTP_CONTEXT(http_ctx, L);
399
400 if (TSHttpTxnPristineUrlGet(http_ctx->txnp, &bufp, &url_loc) != TS_SUCCESS) {
401 return 0;
402 }
403
404 url = TSUrlStringGet(bufp, url_loc, &url_len);
405
406 if (url) {
407 lua_pushlstring(L, url, url_len);
408 TSfree(url);
409
410 } else {
411 lua_pushnil(L);
412 }
413
414 TSHandleMLocRelease(bufp, NULL, url_loc);
415
416 return 1;
417 }
418
419 static int
ts_lua_client_request_get_url_host(lua_State * L)420 ts_lua_client_request_get_url_host(lua_State *L)
421 {
422 const char *host;
423 int len = 0;
424
425 ts_lua_http_ctx *http_ctx;
426
427 GET_HTTP_CONTEXT(http_ctx, L);
428
429 host = TSUrlHostGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len);
430
431 if (len == 0) {
432 char *key = "Host";
433 char *l_key = "host";
434 int key_len = 4;
435
436 TSMLoc field_loc;
437
438 field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);
439 if (field_loc) {
440 host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len);
441 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
442
443 } else {
444 field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, l_key, key_len);
445 if (field_loc) {
446 host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len);
447 TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
448 }
449 }
450 }
451
452 lua_pushlstring(L, host, len);
453
454 return 1;
455 }
456
457 static int
ts_lua_client_request_set_url_host(lua_State * L)458 ts_lua_client_request_set_url_host(lua_State *L)
459 {
460 const char *host;
461 size_t len;
462
463 ts_lua_http_ctx *http_ctx;
464
465 GET_HTTP_CONTEXT(http_ctx, L);
466
467 host = luaL_checklstring(L, 1, &len);
468
469 TSUrlHostSet(http_ctx->client_request_bufp, http_ctx->client_request_url, host, len);
470
471 return 0;
472 }
473
474 static int
ts_lua_client_request_get_url_port(lua_State * L)475 ts_lua_client_request_get_url_port(lua_State *L)
476 {
477 int port;
478
479 ts_lua_http_ctx *http_ctx;
480
481 GET_HTTP_CONTEXT(http_ctx, L);
482
483 port = TSUrlPortGet(http_ctx->client_request_bufp, http_ctx->client_request_url);
484
485 lua_pushnumber(L, port);
486
487 return 1;
488 }
489
490 static int
ts_lua_client_request_set_url_port(lua_State * L)491 ts_lua_client_request_set_url_port(lua_State *L)
492 {
493 int port;
494
495 ts_lua_http_ctx *http_ctx;
496
497 GET_HTTP_CONTEXT(http_ctx, L);
498
499 // NOLINTNEXTLINE
500 port = luaL_checkint(L, 1);
501
502 TSUrlPortSet(http_ctx->client_request_bufp, http_ctx->client_request_url, port);
503
504 return 0;
505 }
506
507 static int
ts_lua_client_request_get_url_scheme(lua_State * L)508 ts_lua_client_request_get_url_scheme(lua_State *L)
509 {
510 const char *scheme;
511 int len;
512
513 ts_lua_http_ctx *http_ctx;
514
515 GET_HTTP_CONTEXT(http_ctx, L);
516
517 scheme = TSUrlSchemeGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len);
518
519 lua_pushlstring(L, scheme, len);
520
521 return 1;
522 }
523
524 static int
ts_lua_client_request_set_url_scheme(lua_State * L)525 ts_lua_client_request_set_url_scheme(lua_State *L)
526 {
527 const char *scheme;
528 size_t len;
529
530 ts_lua_http_ctx *http_ctx;
531
532 GET_HTTP_CONTEXT(http_ctx, L);
533
534 scheme = luaL_checklstring(L, 1, &len);
535
536 TSUrlSchemeSet(http_ctx->client_request_bufp, http_ctx->client_request_url, scheme, len);
537
538 return 0;
539 }
540
541 static int
ts_lua_client_request_get_uri(lua_State * L)542 ts_lua_client_request_get_uri(lua_State *L)
543 {
544 const char *path;
545 int path_len;
546
547 ts_lua_http_ctx *http_ctx;
548
549 GET_HTTP_CONTEXT(http_ctx, L);
550
551 path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &path_len);
552
553 lua_pushlstring(L, "/", 1);
554 lua_pushlstring(L, path, path_len >= TS_LUA_MAX_URL_LENGTH - 1 ? TS_LUA_MAX_URL_LENGTH - 2 : path_len);
555 lua_concat(L, 2);
556
557 return 1;
558 }
559
560 static int
ts_lua_client_request_set_uri(lua_State * L)561 ts_lua_client_request_set_uri(lua_State *L)
562 {
563 const char *path;
564 size_t path_len;
565
566 ts_lua_http_ctx *http_ctx;
567
568 GET_HTTP_CONTEXT(http_ctx, L);
569
570 path = luaL_checklstring(L, 1, &path_len);
571
572 if (*path == '/') {
573 path++;
574 path_len--;
575 }
576
577 TSUrlPathSet(http_ctx->client_request_bufp, http_ctx->client_request_url, path, path_len);
578
579 return 0;
580 }
581
582 static void
ts_lua_inject_client_request_args_api(lua_State * L)583 ts_lua_inject_client_request_args_api(lua_State *L)
584 {
585 lua_pushcfunction(L, ts_lua_client_request_set_uri_args);
586 lua_setfield(L, -2, "set_uri_args");
587
588 lua_pushcfunction(L, ts_lua_client_request_get_uri_args);
589 lua_setfield(L, -2, "get_uri_args");
590 }
591
592 static int
ts_lua_client_request_get_uri_args(lua_State * L)593 ts_lua_client_request_get_uri_args(lua_State *L)
594 {
595 const char *param;
596 int param_len;
597
598 ts_lua_http_ctx *http_ctx;
599
600 GET_HTTP_CONTEXT(http_ctx, L);
601
602 param = TSUrlHttpQueryGet(http_ctx->client_request_bufp, http_ctx->client_request_url, ¶m_len);
603
604 if (param && param_len > 0) {
605 lua_pushlstring(L, param, param_len);
606 } else {
607 lua_pushnil(L);
608 }
609
610 return 1;
611 }
612
613 static int
ts_lua_client_request_set_uri_args(lua_State * L)614 ts_lua_client_request_set_uri_args(lua_State *L)
615 {
616 const char *param;
617 size_t param_len;
618
619 ts_lua_http_ctx *http_ctx;
620
621 GET_HTTP_CONTEXT(http_ctx, L);
622
623 param = luaL_checklstring(L, 1, ¶m_len);
624 TSUrlHttpQuerySet(http_ctx->client_request_bufp, http_ctx->client_request_url, param, param_len);
625
626 return 0;
627 }
628
629 static void
ts_lua_inject_client_request_params_api(lua_State * L)630 ts_lua_inject_client_request_params_api(lua_State *L)
631 {
632 lua_pushcfunction(L, ts_lua_client_request_set_uri_params);
633 lua_setfield(L, -2, "set_uri_params");
634
635 lua_pushcfunction(L, ts_lua_client_request_get_uri_params);
636 lua_setfield(L, -2, "get_uri_params");
637 }
638
639 static int
ts_lua_client_request_get_uri_params(lua_State * L)640 ts_lua_client_request_get_uri_params(lua_State *L)
641 {
642 const char *param;
643 int param_len;
644
645 ts_lua_http_ctx *http_ctx;
646
647 GET_HTTP_CONTEXT(http_ctx, L);
648
649 param = TSUrlHttpParamsGet(http_ctx->client_request_bufp, http_ctx->client_request_url, ¶m_len);
650
651 if (param && param_len > 0) {
652 lua_pushlstring(L, param, param_len);
653 } else {
654 lua_pushnil(L);
655 }
656
657 return 1;
658 }
659
660 static int
ts_lua_client_request_set_uri_params(lua_State * L)661 ts_lua_client_request_set_uri_params(lua_State *L)
662 {
663 const char *param;
664 size_t param_len;
665
666 ts_lua_http_ctx *http_ctx;
667
668 GET_HTTP_CONTEXT(http_ctx, L);
669
670 param = luaL_checklstring(L, 1, ¶m_len);
671 TSUrlHttpParamsSet(http_ctx->client_request_bufp, http_ctx->client_request_url, param, param_len);
672
673 return 0;
674 }
675
676 static int
ts_lua_client_request_client_addr_get_ip(lua_State * L)677 ts_lua_client_request_client_addr_get_ip(lua_State *L)
678 {
679 struct sockaddr const *client_ip;
680 char cip[128];
681 ts_lua_http_ctx *http_ctx;
682
683 GET_HTTP_CONTEXT(http_ctx, L);
684
685 client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);
686
687 if (client_ip == NULL) {
688 lua_pushnil(L);
689
690 } else {
691 if (client_ip->sa_family == AF_INET) {
692 inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip));
693 } else {
694 inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip));
695 }
696
697 lua_pushstring(L, cip);
698 }
699
700 return 1;
701 }
702
703 static int
ts_lua_client_request_client_addr_get_port(lua_State * L)704 ts_lua_client_request_client_addr_get_port(lua_State *L)
705 {
706 struct sockaddr const *client_ip;
707 ts_lua_http_ctx *http_ctx;
708 int port;
709
710 GET_HTTP_CONTEXT(http_ctx, L);
711
712 client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);
713
714 if (client_ip == NULL) {
715 lua_pushnil(L);
716
717 } else {
718 if (client_ip->sa_family == AF_INET) {
719 port = ((struct sockaddr_in *)client_ip)->sin_port;
720 } else {
721 port = ((struct sockaddr_in6 *)client_ip)->sin6_port;
722 }
723
724 lua_pushnumber(L, port);
725 }
726
727 return 1;
728 }
729
730 static int
ts_lua_client_request_client_addr_get_incoming_port(lua_State * L)731 ts_lua_client_request_client_addr_get_incoming_port(lua_State *L)
732 {
733 struct sockaddr const *incoming_addr;
734 ts_lua_http_ctx *http_ctx;
735 int port;
736
737 GET_HTTP_CONTEXT(http_ctx, L);
738
739 incoming_addr = TSHttpTxnIncomingAddrGet(http_ctx->txnp);
740
741 if (incoming_addr == NULL) {
742 lua_pushnil(L);
743
744 } else {
745 if (incoming_addr->sa_family == AF_INET) {
746 port = ((struct sockaddr_in *)incoming_addr)->sin_port;
747 } else {
748 port = ((struct sockaddr_in6 *)incoming_addr)->sin6_port;
749 }
750
751 lua_pushnumber(L, ntohs(port));
752 }
753
754 return 1;
755 }
756
757 static int
ts_lua_client_request_client_addr_get_addr(lua_State * L)758 ts_lua_client_request_client_addr_get_addr(lua_State *L)
759 {
760 struct sockaddr const *client_ip;
761 ts_lua_http_ctx *http_ctx;
762 int port;
763 int family;
764 char cip[128];
765
766 GET_HTTP_CONTEXT(http_ctx, L);
767
768 client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);
769
770 if (client_ip == NULL) {
771 lua_pushnil(L);
772 lua_pushnil(L);
773 lua_pushnil(L);
774
775 } else {
776 if (client_ip->sa_family == AF_INET) {
777 port = ntohs(((struct sockaddr_in *)client_ip)->sin_port);
778 inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip));
779 family = AF_INET;
780 } else {
781 port = ntohs(((struct sockaddr_in6 *)client_ip)->sin6_port);
782 inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip));
783 family = AF_INET6;
784 }
785
786 lua_pushstring(L, cip);
787 lua_pushnumber(L, port);
788 lua_pushnumber(L, family);
789 }
790
791 return 3;
792 }
793
794 static void
ts_lua_inject_client_request_method_api(lua_State * L)795 ts_lua_inject_client_request_method_api(lua_State *L)
796 {
797 lua_pushcfunction(L, ts_lua_client_request_get_method);
798 lua_setfield(L, -2, "get_method");
799
800 lua_pushcfunction(L, ts_lua_client_request_set_method);
801 lua_setfield(L, -2, "set_method");
802 }
803
804 static int
ts_lua_client_request_get_method(lua_State * L)805 ts_lua_client_request_get_method(lua_State *L)
806 {
807 const char *method;
808 int method_len;
809
810 ts_lua_http_ctx *http_ctx;
811
812 GET_HTTP_CONTEXT(http_ctx, L);
813
814 method = TSHttpHdrMethodGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, &method_len);
815
816 if (method && method_len) {
817 lua_pushlstring(L, method, method_len);
818 } else {
819 lua_pushnil(L);
820 }
821
822 return 1;
823 }
824
825 static int
ts_lua_client_request_set_method(lua_State * L)826 ts_lua_client_request_set_method(lua_State *L)
827 {
828 const char *method;
829 size_t method_len;
830
831 ts_lua_http_ctx *http_ctx;
832
833 GET_HTTP_CONTEXT(http_ctx, L);
834
835 method = luaL_checklstring(L, 1, &method_len);
836
837 if (method) {
838 TSHttpHdrMethodSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, method, method_len);
839 }
840
841 return 0;
842 }
843
844 static void
ts_lua_inject_client_request_body_size_api(lua_State * L)845 ts_lua_inject_client_request_body_size_api(lua_State *L)
846 {
847 lua_pushcfunction(L, ts_lua_client_request_get_body_size);
848 lua_setfield(L, -2, "get_body_size");
849 }
850
851 static int
ts_lua_client_request_get_body_size(lua_State * L)852 ts_lua_client_request_get_body_size(lua_State *L)
853 {
854 int64_t body_size;
855 ts_lua_http_ctx *http_ctx;
856
857 GET_HTTP_CONTEXT(http_ctx, L);
858
859 body_size = TSHttpTxnClientReqBodyBytesGet(http_ctx->txnp);
860 lua_pushnumber(L, body_size);
861
862 return 1;
863 }
864
865 static void
ts_lua_inject_client_request_version_api(lua_State * L)866 ts_lua_inject_client_request_version_api(lua_State *L)
867 {
868 lua_pushcfunction(L, ts_lua_client_request_get_version);
869 lua_setfield(L, -2, "get_version");
870
871 lua_pushcfunction(L, ts_lua_client_request_set_version);
872 lua_setfield(L, -2, "set_version");
873 }
874
875 static int
ts_lua_client_request_get_version(lua_State * L)876 ts_lua_client_request_get_version(lua_State *L)
877 {
878 int version;
879 char buf[32];
880 int n;
881
882 ts_lua_http_ctx *http_ctx;
883
884 GET_HTTP_CONTEXT(http_ctx, L);
885
886 version = TSHttpHdrVersionGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp);
887
888 n = snprintf(buf, sizeof(buf), "%d.%d", TS_HTTP_MAJOR(version), TS_HTTP_MINOR(version));
889 if (n >= (int)sizeof(buf)) {
890 lua_pushlstring(L, buf, sizeof(buf) - 1);
891 } else if (n > 0) {
892 lua_pushlstring(L, buf, n);
893 }
894
895 return 1;
896 }
897
898 static int
ts_lua_client_request_set_version(lua_State * L)899 ts_lua_client_request_set_version(lua_State *L)
900 {
901 const char *version;
902 size_t len;
903 unsigned int major, minor;
904
905 ts_lua_http_ctx *http_ctx;
906
907 GET_HTTP_CONTEXT(http_ctx, L);
908
909 version = luaL_checklstring(L, 1, &len);
910
911 if (sscanf(version, "%2u.%2u", &major, &minor) != 2) {
912 return luaL_error(L, "failed to set version. Format must be X.Y");
913 }
914
915 TSHttpHdrVersionSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, TS_HTTP_VERSION(major, minor));
916
917 return 0;
918 }
919
920 static void
ts_lua_inject_client_request_header_size_api(lua_State * L)921 ts_lua_inject_client_request_header_size_api(lua_State *L)
922 {
923 lua_pushcfunction(L, ts_lua_client_request_get_header_size);
924 lua_setfield(L, -2, "get_header_size");
925 }
926
927 static int
ts_lua_client_request_get_header_size(lua_State * L)928 ts_lua_client_request_get_header_size(lua_State *L)
929 {
930 int header_size;
931 ts_lua_http_ctx *http_ctx;
932
933 GET_HTTP_CONTEXT(http_ctx, L);
934
935 header_size = TSHttpTxnClientReqHdrBytesGet(http_ctx->txnp);
936 lua_pushnumber(L, header_size);
937
938 return 1;
939 }
940
941 static void
ts_lua_inject_client_request_ssl_reused_api(lua_State * L)942 ts_lua_inject_client_request_ssl_reused_api(lua_State *L)
943 {
944 lua_pushcfunction(L, ts_lua_client_request_get_ssl_reused);
945 lua_setfield(L, -2, "get_ssl_reused");
946 }
947
948 static int
ts_lua_client_request_get_ssl_reused(lua_State * L)949 ts_lua_client_request_get_ssl_reused(lua_State *L)
950 {
951 int ssl_reused = 0;
952 ts_lua_http_ctx *http_ctx;
953 TSHttpSsn ssnp;
954 TSVConn client_conn;
955
956 GET_HTTP_CONTEXT(http_ctx, L);
957 ssnp = TSHttpTxnSsnGet(http_ctx->txnp);
958 client_conn = TSHttpSsnClientVConnGet(ssnp);
959
960 if (TSVConnIsSsl(client_conn)) {
961 ssl_reused = TSVConnIsSslReused(client_conn);
962 }
963
964 lua_pushnumber(L, ssl_reused);
965
966 return 1;
967 }
968
969 static void
ts_lua_inject_client_request_ssl_cipher_api(lua_State * L)970 ts_lua_inject_client_request_ssl_cipher_api(lua_State *L)
971 {
972 lua_pushcfunction(L, ts_lua_client_request_get_ssl_cipher);
973 lua_setfield(L, -2, "get_ssl_cipher");
974 }
975
976 static int
ts_lua_client_request_get_ssl_cipher(lua_State * L)977 ts_lua_client_request_get_ssl_cipher(lua_State *L)
978 {
979 const char *ssl_cipher = "-";
980 ts_lua_http_ctx *http_ctx;
981 TSHttpSsn ssnp;
982 TSVConn client_conn;
983
984 GET_HTTP_CONTEXT(http_ctx, L);
985
986 ssnp = TSHttpTxnSsnGet(http_ctx->txnp);
987 client_conn = TSHttpSsnClientVConnGet(ssnp);
988
989 if (TSVConnIsSsl(client_conn)) {
990 ssl_cipher = TSVConnSslCipherGet(client_conn);
991 }
992
993 lua_pushstring(L, ssl_cipher);
994
995 return 1;
996 }
997
998 static void
ts_lua_inject_client_request_ssl_protocol_api(lua_State * L)999 ts_lua_inject_client_request_ssl_protocol_api(lua_State *L)
1000 {
1001 lua_pushcfunction(L, ts_lua_client_request_get_ssl_protocol);
1002 lua_setfield(L, -2, "get_ssl_protocol");
1003 }
1004
1005 static int
ts_lua_client_request_get_ssl_protocol(lua_State * L)1006 ts_lua_client_request_get_ssl_protocol(lua_State *L)
1007 {
1008 const char *ssl_protocol = "-";
1009 ts_lua_http_ctx *http_ctx;
1010 TSHttpSsn ssnp;
1011 TSVConn client_conn;
1012
1013 GET_HTTP_CONTEXT(http_ctx, L);
1014
1015 ssnp = TSHttpTxnSsnGet(http_ctx->txnp);
1016 client_conn = TSHttpSsnClientVConnGet(ssnp);
1017
1018 if (TSVConnIsSsl(client_conn)) {
1019 ssl_protocol = TSVConnSslProtocolGet(client_conn);
1020 }
1021
1022 lua_pushstring(L, ssl_protocol);
1023
1024 return 1;
1025 }
1026
1027 static void
ts_lua_inject_client_request_ssl_curve_api(lua_State * L)1028 ts_lua_inject_client_request_ssl_curve_api(lua_State *L)
1029 {
1030 lua_pushcfunction(L, ts_lua_client_request_get_ssl_curve);
1031 lua_setfield(L, -2, "get_ssl_curve");
1032 }
1033
1034 static int
ts_lua_client_request_get_ssl_curve(lua_State * L)1035 ts_lua_client_request_get_ssl_curve(lua_State *L)
1036 {
1037 const char *ssl_curve = "-";
1038 ts_lua_http_ctx *http_ctx;
1039 TSHttpSsn ssnp;
1040 TSVConn client_conn;
1041
1042 GET_HTTP_CONTEXT(http_ctx, L);
1043
1044 ssnp = TSHttpTxnSsnGet(http_ctx->txnp);
1045 client_conn = TSHttpSsnClientVConnGet(ssnp);
1046
1047 if (TSVConnIsSsl(client_conn)) {
1048 ssl_curve = TSVConnSslCurveGet(client_conn);
1049 }
1050
1051 lua_pushstring(L, ssl_curve);
1052
1053 return 1;
1054 }
1055