@@ -3249,7 +3249,8 @@ void list_services(FILE *out)
32493249
32503250/* appctx context used by the "show sess" command */
32513251/* flags used for show_sess_ctx.flags */
3252- #define CLI_SHOWSESS_F_SUSP 0x00000001 /* show only suspicious streams */
3252+ #define CLI_SHOWSESS_F_SUSP 0x00000001 /* show only suspicious streams */
3253+ #define CLI_SHOWSESS_F_DUMP_URI 0x00000002 /* Dump TXN's uri if available in dump */
32533254
32543255struct show_sess_ctx {
32553256 struct bref bref ; /* back-reference from the session being dumped */
@@ -3264,11 +3265,13 @@ struct show_sess_ctx {
32643265
32653266/* This function appends a complete dump of a stream state onto the buffer,
32663267 * possibly anonymizing using the specified anon_key. The caller is responsible
3267- * for ensuring that enough room remains in the buffer to dump a complete
3268- * stream at once. Each new output line will be prefixed with <pfx> if non-null,
3269- * which is used to preserve indenting.
3268+ * for ensuring that enough room remains in the buffer to dump a complete stream
3269+ * at once. Each new output line will be prefixed with <pfx> if non-null, which
3270+ * is used to preserve indenting. The context <ctx>, if non-null, will be used
3271+ * to customize the dump.
32703272 */
3271- void strm_dump_to_buffer (struct buffer * buf , const struct stream * strm , const char * pfx , uint32_t anon_key )
3273+ static void __strm_dump_to_buffer (struct buffer * buf , const struct show_sess_ctx * ctx ,
3274+ const struct stream * strm , const char * pfx , uint32_t anon_key )
32723275{
32733276 struct stconn * scf , * scb ;
32743277 struct tm tm ;
@@ -3411,12 +3414,16 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
34113414 " age=%s)\n" ,
34123415 human_time (ns_to_sec (now_ns ) - ns_to_sec (strm -> logs .request_ts ), 1 ));
34133416
3414- if (strm -> txn )
3417+ if (strm -> txn ) {
34153418 chunk_appendf (buf ,
3416- "%s txn=%p flags=0x%x meth=%d status=%d req.st=%s rsp.st=%s req.f=0x%02x rsp.f=0x%02x\n " , pfx ,
3419+ "%s txn=%p flags=0x%x meth=%d status=%d req.st=%s rsp.st=%s req.f=0x%02x rsp.f=0x%02x" , pfx ,
34173420 strm -> txn , strm -> txn -> flags , strm -> txn -> meth , strm -> txn -> status ,
34183421 h1_msg_state_str (strm -> txn -> req .msg_state ), h1_msg_state_str (strm -> txn -> rsp .msg_state ),
34193422 strm -> txn -> req .flags , strm -> txn -> rsp .flags );
3423+ if (ctx && (ctx -> flags & CLI_SHOWSESS_F_DUMP_URI ) && strm -> txn -> uri )
3424+ chunk_appendf (buf , " uri=\"%s\"" , HA_ANON_STR (anon_key , strm -> txn -> uri ));
3425+ chunk_memcat (buf , "\n" , 1 );
3426+ }
34203427
34213428 scf = strm -> scf ;
34223429 chunk_appendf (buf , "%s scf=%p flags=0x%08x ioto=%s state=%s endp=%s,%p,0x%08x sub=%d" , pfx ,
@@ -3623,6 +3630,14 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
36233630 }
36243631}
36253632
3633+ /* Context-less function to append a complet dump of a stream state onto the
3634+ * buffer. It relies on __strm_dump_to_buffer.
3635+ */
3636+ void strm_dump_to_buffer (struct buffer * buf , const struct stream * strm , const char * pfx , uint32_t anon_key )
3637+ {
3638+ __strm_dump_to_buffer (buf , NULL , strm , pfx , anon_key );
3639+ }
3640+
36263641/* This function dumps a complete stream state onto the stream connector's
36273642 * read buffer. The stream has to be set in strm. It returns 0 if the output
36283643 * buffer is full and it needs to be called again, otherwise non-zero. It is
@@ -3649,7 +3664,7 @@ static int stats_dump_full_strm_to_buffer(struct appctx *appctx, struct stream *
36493664 __fallthrough ;
36503665
36513666 case 1 :
3652- strm_dump_to_buffer (& trash , strm , "" , appctx -> cli_anon_key );
3667+ __strm_dump_to_buffer (& trash , ctx , strm , "" , appctx -> cli_anon_key );
36533668 if (applet_putchk (appctx , & trash ) == -1 )
36543669 goto full ;
36553670
@@ -3667,6 +3682,7 @@ static int stats_dump_full_strm_to_buffer(struct appctx *appctx, struct stream *
36673682static int cli_parse_show_sess (char * * args , char * payload , struct appctx * appctx , void * private )
36683683{
36693684 struct show_sess_ctx * ctx = applet_reserve_svcctx (appctx , sizeof (* ctx ));
3685+ int cur_arg = 2 ;
36703686
36713687 if (!cli_has_level (appctx , ACCESS_LVL_OPER ))
36723688 return 1 ;
@@ -3678,28 +3694,47 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx
36783694 ctx -> pos = 0 ;
36793695 ctx -> thr = 0 ;
36803696
3681- if (* args [2 ] && strcmp (args [2 ], "older" ) == 0 ) {
3697+ if (* args [cur_arg ] && strcmp (args [cur_arg ], "older" ) == 0 ) {
36823698 unsigned timeout ;
36833699 const char * res ;
36843700
3685- if (!* args [3 ])
3701+ if (!* args [cur_arg + 1 ])
36863702 return cli_err (appctx , "Expects a minimum age (in seconds by default).\n" );
36873703
3688- res = parse_time_err (args [3 ], & timeout , TIME_UNIT_S );
3704+ res = parse_time_err (args [cur_arg + 1 ], & timeout , TIME_UNIT_S );
36893705 if (res != 0 )
36903706 return cli_err (appctx , "Invalid age.\n" );
36913707
36923708 ctx -> min_age = timeout ;
36933709 ctx -> target = (void * )-1 ; /* show all matching entries */
3710+ cur_arg += 2 ;
36943711 }
3695- else if (* args [2 ] && strcmp (args [2 ], "susp" ) == 0 ) {
3712+ else if (* args [cur_arg ] && strcmp (args [cur_arg ], "susp" ) == 0 ) {
36963713 ctx -> flags |= CLI_SHOWSESS_F_SUSP ;
36973714 ctx -> target = (void * )-1 ; /* show all matching entries */
3715+ cur_arg ++ ;
36983716 }
3699- else if (* args [2 ] && strcmp (args [2 ], "all" ) == 0 )
3717+ else if (* args [cur_arg ] && strcmp (args [cur_arg ], "all" ) == 0 ) {
37003718 ctx -> target = (void * )-1 ;
3701- else if (* args [2 ])
3702- ctx -> target = (void * )strtoul (args [2 ], NULL , 0 );
3719+ cur_arg ++ ;
3720+ }
3721+ else if (* args [cur_arg ]) {
3722+ ctx -> target = (void * )strtoul (args [cur_arg ], NULL , 0 );
3723+ if (ctx -> target )
3724+ cur_arg ++ ;
3725+ }
3726+
3727+ /* show-sess options parsing */
3728+ while (* args [cur_arg ]) {
3729+ if (* args [cur_arg ] && strcmp (args [cur_arg ], "show-uri" ) == 0 ) {
3730+ ctx -> flags |= CLI_SHOWSESS_F_DUMP_URI ;
3731+ }
3732+ else {
3733+ chunk_printf (& trash , "Unsupported option '%s'.\n" , args [cur_arg ]);
3734+ return cli_err (appctx , trash .area );
3735+ }
3736+ cur_arg ++ ;
3737+ }
37033738
37043739 /* The back-ref must be reset, it will be detected and set by
37053740 * the dump code upon first invocation.
@@ -3897,6 +3932,9 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
38973932 if (task_in_rq (curr_strm -> task ))
38983933 chunk_appendf (& trash , " run(nice=%d)" , curr_strm -> task -> nice );
38993934
3935+ if ((ctx -> flags & CLI_SHOWSESS_F_DUMP_URI ) && curr_strm -> txn && curr_strm -> txn -> uri )
3936+ chunk_appendf (& trash , " uri=\"%s\"" , HA_ANON_CLI (curr_strm -> txn -> uri ));
3937+
39003938 chunk_appendf (& trash , "\n" );
39013939
39023940 if (applet_putchk (appctx , & trash ) == -1 ) {
0 commit comments