You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2016/07/29 15:12:38 UTC

svn commit: r1754534 - in /httpd/httpd/trunk/modules/http2: h2_filter.c h2_mplx.c h2_mplx.h h2_session.c h2_stream.c h2_stream.h

Author: icing
Date: Fri Jul 29 15:12:38 2016
New Revision: 1754534

URL: http://svn.apache.org/viewvc?rev=1754534&view=rev
Log:
mod_http2: complete implemenmtation of draft-http2-debug-state

Modified:
    httpd/httpd/trunk/modules/http2/h2_filter.c
    httpd/httpd/trunk/modules/http2/h2_mplx.c
    httpd/httpd/trunk/modules/http2/h2_mplx.h
    httpd/httpd/trunk/modules/http2/h2_session.c
    httpd/httpd/trunk/modules/http2/h2_stream.c
    httpd/httpd/trunk/modules/http2/h2_stream.h

Modified: httpd/httpd/trunk/modules/http2/h2_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_filter.c?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_filter.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_filter.c Fri Jul 29 15:12:38 2016
@@ -15,6 +15,7 @@
 
 #include <assert.h>
 
+#include <apr_strings.h>
 #include <httpd.h>
 #include <http_core.h>
 #include <http_log.h>
@@ -32,6 +33,7 @@
 #include "h2_stream.h"
 #include "h2_request.h"
 #include "h2_response.h"
+#include "h2_stream.h"
 #include "h2_session.h"
 #include "h2_util.h"
 #include "h2_version.h"
@@ -223,13 +225,68 @@ static void add_settings(apr_bucket_brig
     bbout(bb, "  }%s\n", last? "" : ",");
 }
 
+static void add_peer_settings(apr_bucket_brigade *bb, h2_session *s, int last) 
+{
+    bbout(bb, "  \"peerSettings\": {\n");
+    bbout(bb, "    \"SETTINGS_MAX_CONCURRENT_STREAMS\": %d,\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS)); 
+    bbout(bb, "    \"SETTINGS_MAX_FRAME_SIZE\": %d,\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_MAX_FRAME_SIZE)); 
+    bbout(bb, "    \"SETTINGS_INITIAL_WINDOW_SIZE\": %d,\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE)); 
+    bbout(bb, "    \"SETTINGS_ENABLE_PUSH\": %d,\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_ENABLE_PUSH)); 
+    bbout(bb, "    \"SETTINGS_HEADER_TABLE_SIZE\": %d,\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE)); 
+    bbout(bb, "    \"SETTINGS_MAX_HEADER_LIST_SIZE\": %d\n", 
+        nghttp2_session_get_remote_settings(s->ngh2, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)); 
+    bbout(bb, "  }%s\n", last? "" : ",");
+}
+
+typedef struct {
+    apr_bucket_brigade *bb;
+    h2_session *s;
+    int idx;
+} stream_ctx_t;
+
+static int add_stream(h2_stream *stream, void *ctx)
+{
+    stream_ctx_t *x = ctx;
+    int32_t flowIn, flowOut;
+    
+    flowIn = nghttp2_session_get_stream_effective_local_window_size(x->s->ngh2, stream->id); 
+    flowOut = nghttp2_session_get_stream_remote_window_size(x->s->ngh2, stream->id);
+    bbout(x->bb, "%s\n    \"%d\": {\n", (x->idx? "," : ""), stream->id);
+    bbout(x->bb, "    \"state\": \"%s\",\n", h2_stream_state_str(stream));
+    bbout(x->bb, "    \"flowIn\": %d,\n", flowIn);
+    bbout(x->bb, "    \"flowOut\": %d,\n", flowOut);
+    bbout(x->bb, "    \"dataIn\": %"APR_UINT64_T_FMT",\n", stream->in_data_octets);  
+    bbout(x->bb, "    \"dataOut\": %"APR_UINT64_T_FMT"\n", stream->out_data_octets);  
+    bbout(x->bb, "    }");
+    
+    ++x->idx;
+    return 1;
+} 
+
+static void add_streams(apr_bucket_brigade *bb, h2_session *s, int last) 
+{
+    stream_ctx_t x;
+    
+    x.bb = bb;
+    x.s = s;
+    x.idx = 0;
+    bbout(bb, "  \"streams\": {");
+    h2_mplx_stream_do(s->mplx, add_stream, &x);
+    bbout(bb, "\n  }%s\n", last? "" : ",");
+}
+
 static void add_push(apr_bucket_brigade *bb, h2_session *s, 
                      h2_stream *stream, int last) 
 {
     h2_push_diary *diary;
     apr_status_t status;
     
-    bbout(bb, "  \"push\": {\n");
+    bbout(bb, "    \"push\": {\n");
     diary = s->push_diary;
     if (diary) {
         const char *data;
@@ -241,51 +298,50 @@ static void add_push(apr_bucket_brigade
                                           &data, &len);
         if (status == APR_SUCCESS) {
             base64_digest = h2_util_base64url_encode(data, len, bb->p);
-            bbout(bb, "    \"cacheDigest\": \"%s\",\n", base64_digest);
+            bbout(bb, "      \"cacheDigest\": \"%s\",\n", base64_digest);
         }
     }
-    bbout(bb, "    \"promises\": %d,\n", s->pushes_promised);
-    bbout(bb, "    \"submits\": %d,\n", s->pushes_submitted);
-    bbout(bb, "    \"resets\": %d\n", s->pushes_reset);
-    bbout(bb, "  }%s\n", last? "" : ",");
+    bbout(bb, "      \"promises\": %d,\n", s->pushes_promised);
+    bbout(bb, "      \"submits\": %d,\n", s->pushes_submitted);
+    bbout(bb, "      \"resets\": %d\n", s->pushes_reset);
+    bbout(bb, "    }%s\n", last? "" : ",");
 }
 
 static void add_in(apr_bucket_brigade *bb, h2_session *s, int last) 
 {
-    bbout(bb, "  \"in\": {\n");
-    bbout(bb, "    \"requests\": %d,\n", s->remote.emitted_count);
-    bbout(bb, "    \"resets\": %d, \n", s->streams_reset);
-    bbout(bb, "    \"frames\": %ld,\n", (long)s->frames_received);
-    bbout(bb, "    \"octets\": %"APR_UINT64_T_FMT"\n", s->io.bytes_read);
-    bbout(bb, "  }%s\n", last? "" : ",");
+    bbout(bb, "    \"in\": {\n");
+    bbout(bb, "      \"requests\": %d,\n", s->remote.emitted_count);
+    bbout(bb, "      \"resets\": %d, \n", s->streams_reset);
+    bbout(bb, "      \"frames\": %ld,\n", (long)s->frames_received);
+    bbout(bb, "      \"octets\": %"APR_UINT64_T_FMT"\n", s->io.bytes_read);
+    bbout(bb, "    }%s\n", last? "" : ",");
 }
 
 static void add_out(apr_bucket_brigade *bb, h2_session *s, int last) 
 {
-    bbout(bb, "  \"out\": {\n");
-    bbout(bb, "    \"responses\": %d,\n", s->responses_submitted);
-    bbout(bb, "    \"frames\": %ld,\n", (long)s->frames_sent);
-    bbout(bb, "    \"octets\": %"APR_UINT64_T_FMT"\n", s->io.bytes_written);
-    bbout(bb, "  }%s\n", last? "" : ",");
+    bbout(bb, "    \"out\": {\n");
+    bbout(bb, "      \"responses\": %d,\n", s->responses_submitted);
+    bbout(bb, "      \"frames\": %ld,\n", (long)s->frames_sent);
+    bbout(bb, "      \"octets\": %"APR_UINT64_T_FMT"\n", s->io.bytes_written);
+    bbout(bb, "    }%s\n", last? "" : ",");
 }
 
-/*
-int32_t nghttp2_session_get_effective_local_window_size(session);
-int32_t
-nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session,
-                                                       int32_t stream_id);
-                                                       int32_t
-nghttp2_session_get_stream_remote_window_size(nghttp2_session *session,
-                                              int32_t stream_id);
-int32_t
-nghttp2_session_get_remote_window_size(nghttp2_session *session);
+static void add_stats(apr_bucket_brigade *bb, h2_session *s, 
+                     h2_stream *stream, int last) 
+{
+    bbout(bb, "  \"stats\": {\n");
+    add_in(bb, s, 0);
+    add_out(bb, s, 0);
+    add_push(bb, s, stream, 1);
+    bbout(bb, "  }%s\n", last? "" : ",");
+}
 
-*/
 static apr_status_t h2_status_stream_filter(h2_stream *stream)
 {
     h2_session *s = stream->session;
     conn_rec *c = s->c;
     apr_bucket_brigade *bb;
+    int32_t connFlowIn, connFlowOut;
     
     if (!stream->response) {
         return APR_EINVAL;
@@ -299,20 +355,25 @@ static apr_status_t h2_status_stream_fil
     apr_table_unset(stream->response->headers, "Content-Length");
     stream->response->content_length = -1;
     
+    connFlowIn = nghttp2_session_get_effective_local_window_size(s->ngh2); 
+    connFlowOut = nghttp2_session_get_remote_window_size(s->ngh2);
+    apr_table_setn(stream->response->headers, "conn-flow-in", 
+                   apr_itoa(stream->pool, connFlowIn));
+    apr_table_setn(stream->response->headers, "conn-flow-out", 
+                   apr_itoa(stream->pool, connFlowOut));
+     
     bbout(bb, "{\n");
     add_settings(bb, s, 0);
-    bbout(bb, "  \"connFlowIn\": %d,\n", 
-          nghttp2_session_get_effective_local_window_size(s->ngh2));
-    bbout(bb, "  \"connFlowOut\": %d,\n", 
-          nghttp2_session_get_remote_window_size(s->ngh2));
+    add_peer_settings(bb, s, 0);
+    bbout(bb, "  \"connFlowIn\": %d,\n", connFlowIn);
+    bbout(bb, "  \"connFlowOut\": %d,\n", connFlowOut);
     bbout(bb, "  \"sentGoAway\": %d,\n", 
           (s->state == H2_SESSION_ST_LOCAL_SHUTDOWN
            || s->state == H2_SESSION_ST_DONE));
 
-    add_in(bb, s, 0);
-    add_out(bb, s, 0);
-
-    add_push(bb, s, stream, 1);
+    add_streams(bb, s, 0);
+    
+    add_stats(bb, s, stream, 1);
     bbout(bb, "}\n");
     
     return APR_SUCCESS;

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Fri Jul 29 15:12:38 2016
@@ -467,6 +467,33 @@ static int stream_done_iter(void *ctx, v
     return 0;
 }
 
+typedef struct {
+    h2_mplx_stream_cb *cb;
+    void *ctx;
+} stream_iter_ctx_t;
+
+static int stream_iter_wrap(void *ctx, void *stream)
+{
+    stream_iter_ctx_t *x = ctx;
+    return x->cb(stream, x->ctx);
+}
+
+apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx)
+{
+    apr_status_t status;
+    int acquired;
+    
+    if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
+        stream_iter_ctx_t x;
+        x.cb = cb;
+        x.ctx = ctx;
+        h2_ihash_iter(m->streams, stream_iter_wrap, &x);
+        
+        leave_mutex(m, acquired);
+    }
+    return status;
+}
+
 static int task_print(void *ctx, void *val)
 {
     h2_mplx *m = ctx;

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.h?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.h Fri Jul 29 15:12:38 2016
@@ -230,6 +230,11 @@ apr_status_t h2_mplx_dispatch_master_eve
 
 apr_status_t h2_mplx_suspend_stream(h2_mplx *m, int stream_id);
 
+
+typedef int h2_mplx_stream_cb(struct h2_stream *s, void *ctx);
+
+apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx);
+
 /*******************************************************************************
  * Output handling of streams.
  ******************************************************************************/

Modified: httpd/httpd/trunk/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.c?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.c Fri Jul 29 15:12:38 2016
@@ -628,7 +628,8 @@ static int on_send_data_cb(nghttp2_sessi
         
     apr_brigade_cleanup(session->bbtmp);
     if (status == APR_SUCCESS) {
-        stream->data_frames_sent++;
+        stream->out_data_frames++;
+        stream->out_data_octets += length;
         return 0;
     }
     else {

Modified: httpd/httpd/trunk/modules/http2/h2_stream.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.c?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.c Fri Jul 29 15:12:38 2016
@@ -462,6 +462,9 @@ apr_status_t h2_stream_write_data(h2_str
     
     status = h2_beam_send(stream->input, stream->tmp, APR_BLOCK_READ);
     apr_brigade_cleanup(stream->tmp);
+    stream->in_data_frames++;
+    stream->in_data_octets += len;
+    
     return status;
 }
 
@@ -695,3 +698,26 @@ const h2_priority *h2_stream_get_priorit
     return NULL;
 }
 
+const char *h2_stream_state_str(h2_stream *stream)
+{
+    switch (stream->state) {
+        case H2_STREAM_ST_IDLE:
+            return "IDLE";
+        case H2_STREAM_ST_OPEN:
+            return "OPEN";
+        case H2_STREAM_ST_RESV_LOCAL:
+            return "RESERVED_LOCAL";
+        case H2_STREAM_ST_RESV_REMOTE:
+            return "RESERVED_REMOTE";
+        case H2_STREAM_ST_CLOSED_INPUT:
+            return "HALF_CLOSED_REMOTE";
+        case H2_STREAM_ST_CLOSED_OUTPUT:
+            return "HALF_CLOSED_LOCAL";
+        case H2_STREAM_ST_CLOSED:
+            return "CLOSED";
+        default:
+            return "UNKNOWN";
+            
+    }
+}
+

Modified: httpd/httpd/trunk/modules/http2/h2_stream.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.h?rev=1754534&r1=1754533&r2=1754534&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.h Fri Jul 29 15:12:38 2016
@@ -65,7 +65,10 @@ struct h2_stream {
     unsigned int submitted : 1; /* response HEADER has been sent */
     
     apr_off_t input_remaining;  /* remaining bytes on input as advertised via content-length */
-    apr_off_t data_frames_sent; /* # of DATA frames sent out for this stream */
+    apr_off_t out_data_frames;  /* # of DATA frames sent */
+    apr_off_t out_data_octets;  /* # of DATA octets (payload) sent */
+    apr_off_t in_data_frames;   /* # of DATA frames received */
+    apr_off_t in_data_octets;   /* # of DATA octets (payload) received */
 };
 
 
@@ -277,4 +280,10 @@ apr_status_t h2_stream_submit_pushes(h2_
  */
 const struct h2_priority *h2_stream_get_priority(h2_stream *stream);
 
+/**
+ * Return a textual representation of the stream state as in RFC 7540
+ * nomenclator, all caps, underscores.
+ */
+const char *h2_stream_state_str(h2_stream *stream);
+
 #endif /* defined(__mod_h2__h2_stream__) */