Want to subscribe to topics you're interested in?
Become a Member

Nginx Hurray! HTTP/2 server push for NGINX

Discussion in 'Nginx and PHP-FPM news & discussions' started by bassie, Jun 7, 2017.

  1. Revenge

    Revenge Active Member

    401
    84
    28
    Feb 21, 2016
    Portugal
    Ratings:
    +299
    Local Time:
    11:54 AM
    1.9.x
    10.1.x
    Most clients today have all those files in the cache. Is this really gonna make a site faster or it will em up using more bandwidth, because it will push all files even if the client already have that file in cache?

    Probably browsers will be able to cancel the push if it detects the file already exist in cache. If this is true, server push will only benefit new clients, correct?
     
  2. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    and yes browser cache is a tricky situation that needs some work on
    wonder if nginx's http2_max_concurrent_pushes outlined at nginx: 641306096f5b is equivalent to Apache H2PushDiarySize ?
    mod_http2 - Apache HTTP Server Version 2.4
    h2o web server has cache aware HTTP/2 server push HTTP/2 Directives - Configure - H2O - the optimized HTTP/2 server
     
    • Informative Informative x 1
  3. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    Thought I'd implement the suggestion of doing conditional preload link header serving only when a preset cookie doesn't exist (pushcheck=visited). Using nginx mapping of $cookie_pushcheck to add_header tested on Centmin Mod's HTTP/2 HTTPS demo site at https://http2.centminmod.com/ with just plain Nginx 1.13.8 preload header (no HTTP/2 server push) just to see if it works and seems to so far.

    On first visit in Chrome/Opera web browser when pushcheck=visited cookie doesn't exist, the preload link header is added for /purecss/pure-min.css CSS file. But when you refresh the page on demo site in web browser, the preload link header is removed as it detected pushcheck=visited cookie is set.

    Code (Text):
    curl -I https://http2.centminmod.com/
    HTTP/1.1 200 OK
    Date: Sun, 11 Feb 2018 01:25:47 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 6103
    Last-Modified: Sun, 11 Feb 2018 01:14:19 GMT
    Connection: keep-alive
    Vary: Accept-Encoding
    ETag: "5a7f98eb-17d7"
    Server: nginx centminmod
    X-Powered-By: centminmod
    Set-Cookie: pushcheck=visited
    Link: </purecss/pure-min.css>; rel=preload; as=style
    Accept-Ranges: bytes
    

    Place in nginx.conf http{} context below the variables_hash_* settings that already exist
    Code (Text):
    map $cookie_pushcheck $push_cookie {
       default "</purecss/pure-min.css>; rel=preload; as=style";
       "~*visited" '';
    }
    

    In nginx HTTPS vhost domain.com.ssl.conf in location context you desire
    Code (Text):
    location /  {
       #http2_push_preload on;
       add_header Set-Cookie "pushcheck=visited";
       add_header Link $push_cookie;
    }
    
     
  4. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    • Informative Informative x 1
  5. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
  6. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    • Like Like x 1
  7. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    patch to fix the problem is currently being created.
    Code:
    # HG changeset patch
    # User Ruslan Ermilov <ru at nginx.com>
    # Date 1518444403 -10800
    #      Mon Feb 12 17:06:43 2018 +0300
    # Node ID 4e72b3bfdeaa9917bbdc89a7fa75580c6bec41a7
    # Parent  8b0553239592f5d0fd419e5116b9d343838685cf
    HTTP/2: push additional headers (ticket #1478).
    
    When pushing requests, copy and push Accept-Encoding, Accept-Language,
    and User-Agent header fields from the original request.
    
    diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c
    --- a/src/http/v2/ngx_http_v2_filter_module.c
    +++ b/src/http/v2/ngx_http_v2_filter_module.c
    @@ -50,20 +50,37 @@
     #define NGX_HTTP_V2_STATUS_404_INDEX      13
     #define NGX_HTTP_V2_STATUS_500_INDEX      14
     
    +#define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
    +#define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
     #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX  28
     #define NGX_HTTP_V2_CONTENT_TYPE_INDEX    31
     #define NGX_HTTP_V2_DATE_INDEX            33
     #define NGX_HTTP_V2_LAST_MODIFIED_INDEX   44
     #define NGX_HTTP_V2_LOCATION_INDEX        46
     #define NGX_HTTP_V2_SERVER_INDEX          54
    +#define NGX_HTTP_V2_USER_AGENT_INDEX      58
     #define NGX_HTTP_V2_VARY_INDEX            59
     
     #define NGX_HTTP_V2_NO_TRAILERS           (ngx_http_v2_out_frame_t *) -1
     
     
    +typedef struct {
    +    ngx_str_t                             authority;
    +#if (NGX_HTTP_GZIP)
    +    ngx_str_t                             accept_encoding;
    +#endif
    +#if (NGX_HTTP_HEADERS)
    +    ngx_str_t                             accept_language;
    +#endif
    +    ngx_str_t                             user_agent;
    +} ngx_http_v2_push_ctx_t;
    +
    +
     static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r);
     static ngx_int_t ngx_http_v2_push_resource(ngx_http_request_t *r,
    -    ngx_str_t *path, ngx_str_t *authority);
    +    ngx_str_t *path, ngx_http_v2_push_ctx_t *ctx);
    +static ngx_int_t ngx_http_v2_indexed_header_encode(ngx_http_request_t *r,
    +    u_char index, ngx_str_t *value, ngx_str_t *header);
     
     static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
         u_char *tmp, ngx_uint_t lower);
    @@ -685,16 +702,17 @@ ngx_http_v2_push_resources(ngx_http_requ
     {
         u_char                     *start, *end, *last;
         ngx_int_t                   rc;
    -    ngx_str_t                   path, authority;
    +    ngx_str_t                   path;
         ngx_uint_t                  i, push;
         ngx_table_elt_t           **h;
         ngx_http_v2_loc_conf_t     *h2lcf;
    +    ngx_http_v2_push_ctx_t      ctx;
         ngx_http_complex_value_t   *pushes;
     
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http2 push resources");
     
    -    ngx_str_null(&authority);
    +    ngx_memzero(&ctx, sizeof(ngx_http_v2_push_ctx_t));
     
         h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
     
    @@ -715,7 +733,7 @@ ngx_http_v2_push_resources(ngx_http_requ
                     continue;
                 }
     
    -            rc = ngx_http_v2_push_resource(r, &path, &authority);
    +            rc = ngx_http_v2_push_resource(r, &path, &ctx);
     
                 if (rc == NGX_ERROR) {
                     return NGX_ERROR;
    @@ -880,7 +898,7 @@ ngx_http_v2_push_resources(ngx_http_requ
             if (push && path.len
                 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/'))
             {
    -            rc = ngx_http_v2_push_resource(r, &path, &authority);
    +            rc = ngx_http_v2_push_resource(r, &path, &ctx);
     
                 if (rc == NGX_ERROR) {
                     return NGX_ERROR;
    @@ -905,11 +923,17 @@ ngx_http_v2_push_resources(ngx_http_requ
     
     static ngx_int_t
     ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path,
    -    ngx_str_t *authority)
    +    ngx_http_v2_push_ctx_t *ctx)
     {
         u_char                    *start, *pos, *tmp;
         size_t                     len;
    -    ngx_table_elt_t           *host;
    +    ngx_table_elt_t           *host, *user_agent;
    +#if (NGX_HTTP_GZIP)
    +    ngx_table_elt_t           *accept_encoding;
    +#endif
    +#if (NGX_HTTP_HEADERS)
    +    ngx_table_elt_t           *accept_language;
    +#endif
         ngx_connection_t          *fc;
         ngx_http_v2_stream_t      *stream;
         ngx_http_v2_out_frame_t   *frame;
    @@ -950,31 +974,69 @@ ngx_http_v2_push_resource(ngx_http_reque
             return NGX_ABORT;
         }
     
    -    if (authority->len == 0) {
    -
    -        len = 1 + NGX_HTTP_V2_INT_OCTETS + host->value.len;
    -
    -        tmp = ngx_palloc(r->pool, len);
    -        pos = ngx_pnalloc(r->pool, len);
    -
    -        if (pos == NULL || tmp == NULL) {
    +#if (NGX_HTTP_GZIP)
    +    accept_encoding = r->headers_in.accept_encoding;
    +#endif
    +
    +#if (NGX_HTTP_HEADERS)
    +    accept_language = r->headers_in.accept_language;
    +#endif
    +
    +    user_agent = r->headers_in.user_agent;
    +
    +    if (ctx->authority.len == 0) {
    +
    +        if (ngx_http_v2_indexed_header_encode(r, NGX_HTTP_V2_AUTHORITY_INDEX,
    +                                              &host->value, &ctx->authority)
    +            != NGX_OK)
    +        {
                 return NGX_ERROR;
             }
     
    -        authority->data = pos;
    -
    -        *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_AUTHORITY_INDEX);
    -        pos = ngx_http_v2_write_value(pos, host->value.data, host->value.len,
    -                                      tmp);
    -
    -        authority->len = pos - authority->data;
    +#if (NGX_HTTP_GZIP)
    +        if (accept_encoding
    +            && ngx_http_v2_indexed_header_encode(r,
    +                   NGX_HTTP_V2_ACCEPT_ENCODING_INDEX,
    +                   &accept_encoding->value, &ctx->accept_encoding)
    +               != NGX_OK)
    +        {
    +            return NGX_ERROR;
    +        }
    +#endif
    +
    +#if (NGX_HTTP_HEADERS)
    +        if (accept_language
    +            && ngx_http_v2_indexed_header_encode(r,
    +                   NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX,
    +                   &accept_language->value, &ctx->accept_language)
    +               != NGX_OK)
    +        {
    +            return NGX_ERROR;
    +        }
    +#endif
    +
    +        if (user_agent
    +            && ngx_http_v2_indexed_header_encode(r,
    +                   NGX_HTTP_V2_USER_AGENT_INDEX,
    +                   &user_agent->value, &ctx->user_agent)
    +               != NGX_OK)
    +        {
    +            return NGX_ERROR;
    +        }
         }
     
         len = (h2c->table_update ? 1 : 0)
               + 1
               + 1 + NGX_HTTP_V2_INT_OCTETS + path->len
    -          + authority->len
    -          + 1;
    +          + ctx->authority.len
    +          + 1
    +#if (NGX_HTTP_GZIP)
    +          + ctx->accept_encoding.len
    +#endif
    +#if (NGX_HTTP_HEADERS)
    +          + ctx->accept_language.len
    +#endif
    +          + ctx->user_agent.len;
     
         tmp = ngx_palloc(r->pool, len);
         pos = ngx_pnalloc(r->pool, len);
    @@ -1006,7 +1068,7 @@ ngx_http_v2_push_resource(ngx_http_reque
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
                        "http2 push header: \":authority: %V\"", &host->value);
     
    -    pos = ngx_cpymem(pos, authority->data, authority->len);
    +    pos = ngx_cpymem(pos, ctx->authority.data, ctx->authority.len);
     
     #if (NGX_HTTP_SSL)
         if (fc->ssl) {
    @@ -1022,6 +1084,36 @@ ngx_http_v2_push_resource(ngx_http_reque
             *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX);
         }
     
    +#if (NGX_HTTP_GZIP)
    +    if (accept_encoding) {
    +        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
    +                       "http2 push header: \"accept-encoding: %V\"",
    +                       &accept_encoding->value);
    +
    +        pos = ngx_cpymem(pos, ctx->accept_encoding.data,
    +                         ctx->accept_encoding.len);
    +    }
    +#endif
    +
    +#if (NGX_HTTP_HEADERS)
    +    if (accept_language) {
    +        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
    +                       "http2 push header: \"accept-language: %V\"",
    +                       &accept_language->value);
    +
    +        pos = ngx_cpymem(pos, ctx->accept_language.data,
    +                         ctx->accept_language.len);
    +    }
    +#endif
    +
    +    if (user_agent) {
    +        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
    +                       "http2 push header: \"user-agent: %V\"",
    +                       &user_agent->value);
    +
    +        pos = ngx_cpymem(pos, ctx->user_agent.data, ctx->user_agent.len);
    +    }
    +
         frame = ngx_http_v2_create_push_frame(r, start, pos);
         if (frame == NULL) {
             return NGX_ERROR;
    @@ -1036,6 +1128,33 @@ ngx_http_v2_push_resource(ngx_http_reque
     }
     
     
    +static ngx_int_t
    +ngx_http_v2_indexed_header_encode(ngx_http_request_t *r, u_char index,
    +    ngx_str_t *value, ngx_str_t *header)
    +{
    +    size_t   len;
    +    u_char  *pos, *tmp;
    +
    +    len = 1 + NGX_HTTP_V2_INT_OCTETS + value->len;
    +
    +    tmp = ngx_palloc(r->pool, len);
    +    pos = ngx_pnalloc(r->pool, len);
    +
    +    if (pos == NULL || tmp == NULL) {
    +        return NGX_ERROR;
    +    }
    +
    +    header->data = pos;
    +
    +    *pos++ = ngx_http_v2_inc_indexed(index);
    +    pos = ngx_http_v2_write_value(pos, value->data, value->len, tmp);
    +
    +    header->len = pos - header->data;
    +
    +    return NGX_OK;
    +}
    +
    +
     static u_char *
     ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
         ngx_uint_t lower)
     
    • Informative Informative x 2
  8. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    nice believe it's evolving out of discussion at [PATCH] HTTP/2: copy additional headers in the pushed requests ? :)

    ok evolved from this dicussion Re: [PATCH] HTTP/2: added support for setting custom push request headers :)

    patch may need more work Re: [PATCH] HTTP/2: added support for setting custom push request headers

     
    • Informative Informative x 2
  9. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
  10. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    Thats their testing mechanismsm setup only? Guess that needs to be in place first
     
  11. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    Haha you're right. It seems logical to me that they will put the patch in later :) Or its the existing patch(with fix) from the dev forum.
     
  12. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    Nginx announced they pushed back 1.13.9 release till next week NGINX, Inc. on Twitter

     
  13. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    It is because of your ticket. You little bas....;)
     
    • Funny Funny x 1
  14. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    LOL... there maybe other issues that I ran into just need to confirm i.e. Chrome vs Canary vs Firefox HTTP/2 Push etc.
     
  15. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    • Like Like x 1
  16. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    sweet thanks for the heads up Commits · nginx/nginx · GitHub :cool:

    update to latest Nginx 1.13.9 master code
    Looking good gzip compressed HTTP/2 Pushed CSS files

    upload_2018-2-16_2-50-4.png

    nghttp stats output * next to pushed CSS files indicates HTTP/2 Server Push
    Code (Text):
    nghttp -nas https://http2.domain.com/
    
    ***** Statistics *****
    
    Request timing:
      responseEnd: the  time  when  last  byte of  response  was  received
                   relative to connectEnd
     requestStart: the time  just before  first byte  of request  was sent
                   relative  to connectEnd.   If  '*' is  shown, this  was
                   pushed by server.
          process: responseEnd - requestStart
             code: HTTP status code
             size: number  of  bytes  received as  response  body  without
                   inflation.
              URI: request URI
    
    see http://www.w3.org/TR/resource-timing/#processing-model
    
    sorted by 'complete'
    
    id  responseEnd requestStart  process code size request path
     13     +1.27ms       +141us   1.13ms  200   1K /
      2     +1.63ms *     +411us   1.22ms  200   4K /purecss/pure-min.css
      4     +2.08ms *     +449us   1.64ms  200   1K /purecss/grids-responsive-min.css
    


    nghttp HTTP/2 Push Promise frames with retained encoding headers for gzip
    Code (Text):
    nghttp -nav https://http2.domain.com/
    [  0.003] Connected
    The negotiated protocol: h2
    [  0.010] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
              (niv=2)
              [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
              [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.010] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
              (dep_stream_id=0, weight=201, exclusive=0)
    [  0.010] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
              (dep_stream_id=0, weight=101, exclusive=0)
    [  0.010] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
              (dep_stream_id=0, weight=1, exclusive=0)
    [  0.010] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
              (dep_stream_id=7, weight=1, exclusive=0)
    [  0.010] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
              (dep_stream_id=3, weight=1, exclusive=0)
    [  0.010] send HEADERS frame <length=43, flags=0x25, stream_id=13>
              ; END_STREAM | END_HEADERS | PRIORITY
              (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
              ; Open new stream
              :method: GET
              :path: /
              :scheme: https
              :authority: http2.domain.com
              accept: */*
              accept-encoding: gzip, deflate
              user-agent: nghttp2/1.31.0-DEV
    [  0.010] recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
              (niv=3)
              [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
              [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
              [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
    [  0.010] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
              (window_size_increment=2147418112)
    [  0.010] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [  0.011] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [  0.011] recv (stream_id=13) :method: GET
    [  0.011] recv (stream_id=13) :path: /purecss/pure-min.css
    [  0.011] recv (stream_id=13) :scheme: https
    [  0.011] recv (stream_id=13) :authority: http2.domain.com
    [  0.011] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.011] recv (stream_id=13) user-agent: nghttp2/1.31.0-DEV
    [  0.011] recv PUSH_PROMISE frame <length=65, flags=0x04, stream_id=13>
              ; END_HEADERS
              (padlen=0, promised_stream_id=2)
    [  0.011] recv (stream_id=13) :method: GET
    [  0.011] recv (stream_id=13) :path: /purecss/grids-responsive-min.css
    [  0.011] recv (stream_id=13) :scheme: https
    [  0.011] recv (stream_id=13) :authority: http2.domain.com
    [  0.011] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.011] recv (stream_id=13) user-agent: nghttp2/1.31.0-DEV
    [  0.011] recv PUSH_PROMISE frame <length=72, flags=0x04, stream_id=13>
              ; END_HEADERS
              (padlen=0, promised_stream_id=4)
    [  0.011] recv (stream_id=13) :status: 200
    [  0.011] recv (stream_id=13) date: Thu, 15 Feb 2018 16:50:49 GMT
    [  0.011] recv (stream_id=13) content-type: text/html; charset=utf-8
    [  0.011] recv (stream_id=13) last-modified: Wed, 14 Feb 2018 04:07:54 GMT
    [  0.011] recv (stream_id=13) vary: Accept-Encoding
    [  0.011] recv (stream_id=13) etag: W/"5a83b61a-1791"
    [  0.011] recv (stream_id=13) server: nginx centminmod
    [  0.011] recv (stream_id=13) x-powered-by: centminmod
    [  0.011] recv (stream_id=13) link: </purecss/pure-min.css>; rel=preload; as=style
    [  0.011] recv (stream_id=13) link: </purecss/grids-responsive-min.css>; rel=preload; as=style
    [  0.011] recv (stream_id=13) content-encoding: gzip
    [  0.011] recv HEADERS frame <length=248, flags=0x04, stream_id=13>
              ; END_HEADERS
              (padlen=0)
              ; First response header
    [  0.012] recv DATA frame <length=1933, flags=0x01, stream_id=13>
              ; END_STREAM
    [  0.012] recv (stream_id=2) :status: 200
    [  0.012] recv (stream_id=2) date: Thu, 15 Feb 2018 16:50:49 GMT
    [  0.012] recv (stream_id=2) content-type: text/css
    [  0.012] recv (stream_id=2) last-modified: Tue, 27 Sep 2016 15:04:57 GMT
    [  0.012] recv (stream_id=2) vary: Accept-Encoding
    [  0.012] recv (stream_id=2) etag: W/"57ea8a99-4386"
    [  0.012] recv (stream_id=2) server: nginx centminmod
    [  0.012] recv (stream_id=2) x-powered-by: centminmod
    [  0.012] recv (stream_id=2) expires: Sat, 17 Mar 2018 16:50:49 GMT
    [  0.012] recv (stream_id=2) cache-control: max-age=2592000
    [  0.012] recv (stream_id=2) access-control-allow-origin: *
    [  0.012] recv (stream_id=2) cache-control: public, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800
    [  0.012] recv (stream_id=2) content-encoding: gzip
    [  0.012] recv HEADERS frame <length=310, flags=0x04, stream_id=2>
              ; END_HEADERS
              (padlen=0)
              ; First push response header
    [  0.013] recv DATA frame <length=4097, flags=0x01, stream_id=2>
              ; END_STREAM
    [  0.013] recv (stream_id=4) :status: 200
    [  0.013] recv (stream_id=4) date: Thu, 15 Feb 2018 16:50:49 GMT
    [  0.013] recv (stream_id=4) content-type: text/css
    [  0.013] recv (stream_id=4) last-modified: Tue, 27 Sep 2016 15:04:57 GMT
    [  0.013] recv (stream_id=4) vary: Accept-Encoding
    [  0.013] recv (stream_id=4) etag: W/"57ea8a99-2646"
    [  0.013] recv (stream_id=4) server: nginx centminmod
    [  0.013] recv (stream_id=4) x-powered-by: centminmod
    [  0.013] recv (stream_id=4) expires: Sat, 17 Mar 2018 16:50:49 GMT
    [  0.013] recv (stream_id=4) cache-control: max-age=2592000
    [  0.013] recv (stream_id=4) access-control-allow-origin: *
    [  0.013] recv (stream_id=4) cache-control: public, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800
    [  0.013] recv (stream_id=4) content-encoding: gzip
    [  0.013] recv HEADERS frame <length=310, flags=0x04, stream_id=4>
              ; END_HEADERS
              (padlen=0)
              ; First push response header
    [  0.013] recv DATA frame <length=1484, flags=0x01, stream_id=4>
              ; END_STREAM
    [  0.014] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
              (last_stream_id=4, error_code=NO_ERROR(0x00), opaque_data(0)=[])
    


    Original uncompressed size
    Code (Text):
    ls -lah purecss/
    total 32K
    drwxr-sr-x 2 nginx nginx   58 Feb 14 04:07 .
    drwxr-s--- 3 nginx nginx  225 Feb 14 04:06 ..
    -rw-r--r-- 1 nginx nginx 9.6K Sep 27  2016 grids-responsive-min.css
    -rw-r--r-- 1 nginx nginx  17K Sep 27  2016 pure-min.css
    

    From Chrome 64 net-internals HTTP/2

    upload_2018-2-16_2-54-44.png
    upload_2018-2-16_2-55-49.png

    Nginx Cache Aware HTTP/2 Server Push



    Testing my outlined cache aware Nginx 1.13.9 HTTP/2 Server Push using custom cookie detection. First load has pushed initiator column CSS files where Nginx detects no custom cookies. Second reload is when Nginx detects custom cookies and assumes repeat visit, so skip HTTP/2 Push and server

    cache-aware-http2-push.gif
     
    • Winner Winner x 1
  17. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
    Great.
    Please update the centminmod branch with the latest code.
    Thanks.
     
  18. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
  19. bassie

    bassie Active Member

    865
    201
    43
    Apr 29, 2016
    Ratings:
    +607
    Local Time:
    12:54 PM
  20. eva2000

    eva2000 Administrator Staff Member

    35,035
    7,734
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +11,928
    Local Time:
    8:54 PM
    Nginx 1.15.x
    MariaDB 5.5/10.x
..