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, &param_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, &param_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, &param_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, &param_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