目次
  • 1.后台
    • 比来创造一个答题
    • nginx对于此是怎么处置惩罚的呢?
  • 两.nginx措置流程
    • 总结

      1.靠山

      咱们体系外有一个罪能,否以配备content-type范例来决议能否翻开gzip缩短。

      那个配备取nginx民间的gzip_type差异之处正在于,nginx民间的是写逝世正在设备文件外的,一切乞求皆见效;咱们自研的是,差别用户的gzip_type否以差别。

      比来发明一个答题

      content-type配备为:image/jpeg,然则后端相应的Content-Type为"

      image/jped;charset:UTF-8"时,因为代码外是将设置的content-type取呼应头外字符串做粗略对照,因而,上述场景,其实不能准确翻开gzip罪能。

      nginx对于此是若何怎样处置惩罚的呢?

      后端相应的Content-Type连结为image/jped;charset:UTF-8。

      一、配备gzip_type 如高,gzip收效:

      gzip_type image/jpeg;

      两、安排gzip_type如高,gzip没有奏效:(nginx民间文档外也不说起上面的配备法子)

      gzip_type "image/jpeg;charset:UTF-8";

      两.nginx措置流程

      正在入止header_filter时,对于content-Type作了校验:

      static ngx_int_t
      ngx_http_gzip_header_filter(ngx_http_request_t *r)
      {
          ngx_table_elt_t       *h;
          ngx_http_gzip_ctx_t   *ctx;
          ngx_http_gzip_conf_t  *conf;
      
          conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
      
          if (!conf->enable
              || (r->headers_out.status != NGX_HTTP_OK
                  && r->headers_out.status != NGX_HTTP_FORBIDDEN
                  && r->headers_out.status != NGX_HTTP_NOT_FOUND)
              || (r->headers_out.content_encoding
                  && r->headers_out.content_encoding->value.len)
              || (r->headers_out.content_length_n != -1
                  && r->headers_out.content_length_n < conf->min_length)
                  // ngx_http_test_content_type外对于content_type作了校验
              || ngx_http_test_content_type(r, &conf->types) == NULL
              || r->header_only)
          {
              return ngx_http_next_header_filter(r);
          }
          ...
          }
      

      ngx_http_test_content_type界说如高:

      void *
      ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
      {
          u_char      c, *lowcase;
          size_t      len;
          ngx_uint_t  i, hash;
      
          if (types_hash->size == 0) {
              return (void *) 4;
          }
      
          if (r->headers_out.content_type.len == 0) {
              return NULL;
          }
      
          len = r->headers_out.content_type_len;
      
          if (r->headers_out.content_type_lowcase == NULL) {
      
              lowcase = ngx_pnalloc(r->pool, len);
              if (lowcase == NULL) {
                  return NULL;
              }
      
              r->headers_out.content_type_lowcase = lowcase;
      
              hash = 0;
      
              for (i = 0; i < len; i++) {
                  c = ngx_tolower(r->headers_out.content_type.data[i]);
                  hash = ngx_hash(hash, c);
                  lowcase[i] = c;
              }
      
              r->headers_out.content_type_hash = hash;
          }
      
          return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
                               r->headers_out.content_type_lowcase, len);
      }
      

      否以望没,将content-type头域形式转换为了年夜写,并应用了r->headers_out.content_type_len少度的形式,取设置的types入止比力。

      然则针对于第1种环境,设置以及现实相应头亮亮是没有相称的啊,是那么立室顺遂的?

      利用gdb挨断点,创造

      • r->headers_out.content_type为:
      • {len = 两4, data = “image/jpeg;charset=UTF-8”}
      • 然则,
      • r->headers_out.content_type_len倒是10!那个取下面为何纷歧致呢?

      找到设备content_type之处:

      static ngx_int_t
      ngx_http_set_content_type_header(ngx_http_request_t *r,
          ngx_http_lua_header_val_t *hv, ngx_str_t *value)
      {
          ngx_uint_t          i;
      
      	// 此时,r->headers_out.content_type_len取 value->len 模仿相称的
          r->headers_out.content_type_len = value->len;
      
      
      #if 1
      
          for (i = 0; i < value->len; i++) {
              if (value->data[i] == ';') {
              	// 找到第一个分号,而后修正了r->headers_out.content_type_len
                  r->headers_out.content_type_len = i;
                  break;
              }
          }
      #endif
      
          r->headers_out.content_type = *value;
          r->headers_out.content_type_hash = hv->hash;
          r->headers_out.content_type_lowcase = NULL;
      
          value->len = 0;
      
          return ngx_http_set_header_helper(r, hv, value, NULL, 1);
      }
      

      否以望没,nginx只利用了Content-Type相应头外第一个分号前的形式入止立室。

      总结

      以上为小我私家经验,心愿能给大师一个参考,也心愿大家2多多撑持剧本之野。

      点赞(48) 打赏

      评论列表 共有 0 条评论

      暂无评论

      微信小程序

      微信扫一扫体验

      立即
      投稿

      微信公众账号

      微信扫一扫加关注

      发表
      评论
      返回
      顶部