@@ -54,6 +54,9 @@ typedef struct {
5454
5555 ngx_http_request_t * request ;
5656
57+ size_t bytes_in ;
58+ size_t bytes_out ;
59+
5760 unsigned action :2 ;
5861 unsigned last :1 ;
5962 unsigned redo :1 ;
@@ -71,6 +74,8 @@ typedef struct {
7174static ngx_http_output_header_filter_pt ngx_http_next_header_filter ;
7275static ngx_http_output_body_filter_pt ngx_http_next_body_filter ;
7376
77+ static ngx_str_t ngx_http_zstd_ratio = ngx_string ("zstd_ratio" );
78+
7479
7580static ngx_int_t ngx_http_zstd_header_filter (ngx_http_request_t * r );
7681static ngx_int_t ngx_http_zstd_body_filter (ngx_http_request_t * r ,
@@ -91,6 +96,9 @@ static char *ngx_http_zstd_init_main_conf(ngx_conf_t *cf, void *conf);
9196static void * ngx_http_zstd_create_loc_conf (ngx_conf_t * cf );
9297static char * ngx_http_zstd_merge_loc_conf (ngx_conf_t * cf , void * parent ,
9398 void * child );
99+ static ngx_int_t ngx_http_zstd_add_variables (ngx_conf_t * cf );
100+ static ngx_int_t ngx_http_zstd_ratio_variable (ngx_http_request_t * r ,
101+ ngx_http_variable_value_t * vv , uintptr_t data );
94102static void * ngx_http_zstd_filter_alloc (void * opaque , size_t size );
95103static void ngx_http_zstd_filter_free (void * opaque , void * address );
96104static char * ngx_http_zstd_comp_level (ngx_conf_t * cf , void * post , void * data );
@@ -151,7 +159,7 @@ static ngx_command_t ngx_http_zstd_filter_commands[] = {
151159
152160
153161static ngx_http_module_t ngx_http_zstd_filter_module_ctx = {
154- NULL , /* preconfiguration */
162+ ngx_http_zstd_add_variables , /* preconfiguration */
155163 ngx_http_zstd_filter_init , /* postconfiguration */
156164
157165 ngx_http_zstd_create_main_conf , /* create main configuration */
@@ -476,6 +484,8 @@ ngx_http_zstd_filter_compress(ngx_http_request_t *r, ngx_http_zstd_ctx_t *ctx)
476484 ctx -> flush = 0 ;
477485 }
478486
487+ ctx -> bytes_out += ngx_buf_size (b );
488+
479489 cl -> next = NULL ;
480490 cl -> buf = b ;
481491
@@ -520,6 +530,8 @@ ngx_http_zstd_filter_add_data(ngx_http_request_t *r, ngx_http_zstd_ctx_t *ctx)
520530 ctx -> buffer_in .pos = 0 ;
521531 ctx -> buffer_in .size = ngx_buf_size (ctx -> in_buf );
522532
533+ ctx -> bytes_in += ngx_buf_size (ctx -> in_buf );
534+
523535 if (ctx -> buffer_in .size == 0 ) {
524536 return NGX_AGAIN ;
525537 }
@@ -885,6 +897,54 @@ ngx_http_zstd_filter_alloc(void *opaque, size_t size)
885897}
886898
887899
900+ static ngx_int_t
901+ ngx_http_zstd_add_variables (ngx_conf_t * cf )
902+ {
903+ ngx_http_variable_t * v ;
904+
905+ v = ngx_http_add_variable (cf , & ngx_http_zstd_ratio ,
906+ NGX_HTTP_VAR_NOCACHEABLE );
907+ if (v == NULL ) {
908+ return NGX_ERROR ;
909+ }
910+
911+ v -> get_handler = ngx_http_zstd_ratio_variable ;
912+
913+ return NGX_OK ;
914+ }
915+
916+
917+ static ngx_int_t
918+ ngx_http_zstd_ratio_variable (ngx_http_request_t * r ,
919+ ngx_http_variable_value_t * vv , uintptr_t data )
920+ {
921+ ngx_uint_t ratio_int , ratio_frac ;
922+ ngx_http_zstd_ctx_t * ctx ;
923+
924+ ctx = ngx_http_get_module_ctx (r , ngx_http_zstd_filter_module );
925+ if (ctx == NULL || !ctx -> done || ctx -> bytes_out == 0 ) {
926+ vv -> not_found = 1 ;
927+ return NGX_OK ;
928+ }
929+
930+ vv -> data = ngx_pnalloc (r -> pool , NGX_INT32_LEN + 3 );
931+ if (vv -> data == NULL ) {
932+ return NGX_ERROR ;
933+ }
934+
935+ ratio_int = (ngx_uint_t ) ctx -> bytes_in / ctx -> bytes_out ;
936+ ratio_frac = (ngx_uint_t ) (ctx -> bytes_in * 1000 / ctx -> bytes_out % 1000 );
937+
938+ vv -> len = ngx_sprintf (vv -> data , "%ui.%03ui" , ratio_int , ratio_frac )
939+ - vv -> data ;
940+
941+ vv -> valid = 1 ;
942+ vv -> no_cacheable = 1 ;
943+
944+ return NGX_OK ;
945+ }
946+
947+
888948static void
889949ngx_http_zstd_filter_free (void * opaque , void * address )
890950{
0 commit comments