diff --git a/src/ngx_http_modsecurity_body_filter.c b/src/ngx_http_modsecurity_body_filter.c
index 725f986..5b7abce 100644
--- a/src/ngx_http_modsecurity_body_filter.c
+++ b/src/ngx_http_modsecurity_body_filter.c
@@ -56,6 +56,11 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
         return ngx_http_next_body_filter(r, in);
     }
 
+    if (ctx->modsec_transaction == NULL) {
+        // we have freed the modsec_transaction
+        return ngx_http_next_body_filter(r, in);
+    }
+
     if (ctx->intervention_triggered) {
         return ngx_http_next_body_filter(r, in);
     }
@@ -179,6 +184,14 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
         dd("buffer was not fully loaded! ctx: %p", ctx);
     }
 
+    if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
+        dd("it's switching protocols, clean transaction for %p", ctx);
+        // I don't think there are any response body
+        ngx_http_modsecurity_log_handler(r);
+
+        ngx_http_modsecurity_cleanup(ctx);
+    }
+
 /* XXX: xflt_filter() -- return NGX_OK here */
     return ngx_http_next_body_filter(r, in);
 }
diff --git a/src/ngx_http_modsecurity_common.h b/src/ngx_http_modsecurity_common.h
index 60218c4..313bdfe 100644
--- a/src/ngx_http_modsecurity_common.h
+++ b/src/ngx_http_modsecurity_common.h
@@ -142,6 +142,7 @@ ngx_http_modsecurity_ctx_t *ngx_http_modsecurity_create_ctx(ngx_http_request_t *
 char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p);
 ngx_pool_t *ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool);
 void ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool);
+void ngx_http_modsecurity_cleanup(void *data);
 
 /* ngx_http_modsecurity_body_filter.c */
 ngx_int_t ngx_http_modsecurity_body_filter_init(void);
diff --git a/src/ngx_http_modsecurity_log.c b/src/ngx_http_modsecurity_log.c
index d713a65..f9f1410 100644
--- a/src/ngx_http_modsecurity_log.c
+++ b/src/ngx_http_modsecurity_log.c
@@ -72,6 +72,11 @@ ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
         return NGX_OK;
     }
 
+    if (!ctx->modsec_transaction) {
+        // it's already clean and logged in 101
+        return NGX_OK;
+    }
+
     dd("calling msc_process_logging for %p", ctx);
     old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
     msc_process_logging(ctx->modsec_transaction);
diff --git a/src/ngx_http_modsecurity_module.c b/src/ngx_http_modsecurity_module.c
index b6f33f5..f2d204d 100644
--- a/src/ngx_http_modsecurity_module.c
+++ b/src/ngx_http_modsecurity_module.c
@@ -240,7 +240,12 @@ ngx_http_modsecurity_cleanup(void *data)
 
     ctx = (ngx_http_modsecurity_ctx_t *) data;
 
+    if (!ctx->modsec_transaction) {
+        // it's already clean in 101
+        return;
+    }
     msc_transaction_cleanup(ctx->modsec_transaction);
+    ctx->modsec_transaction = NULL;
 
 #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
     /*