src/http/v3/ngx_http_v3_encode.c - nginx source code

Functions defined

Source code


  1. /*
  2. * Copyright (C) Roman Arutyunyan
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_http.h>


  8. uintptr_t
  9. ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value)
  10. {
  11.     if (value <= 63) {
  12.         if (p == NULL) {
  13.             return 1;
  14.         }

  15.         *p++ = value;
  16.         return (uintptr_t) p;
  17.     }

  18.     if (value <= 16383) {
  19.         if (p == NULL) {
  20.             return 2;
  21.         }

  22.         *p++ = 0x40 | (value >> 8);
  23.         *p++ = value;
  24.         return (uintptr_t) p;
  25.     }

  26.     if (value <= 1073741823) {
  27.         if (p == NULL) {
  28.             return 4;
  29.         }

  30.         *p++ = 0x80 | (value >> 24);
  31.         *p++ = (value >> 16);
  32.         *p++ = (value >> 8);
  33.         *p++ = value;
  34.         return (uintptr_t) p;
  35.     }

  36.     if (p == NULL) {
  37.         return 8;
  38.     }

  39.     *p++ = 0xc0 | (value >> 56);
  40.     *p++ = (value >> 48);
  41.     *p++ = (value >> 40);
  42.     *p++ = (value >> 32);
  43.     *p++ = (value >> 24);
  44.     *p++ = (value >> 16);
  45.     *p++ = (value >> 8);
  46.     *p++ = value;
  47.     return (uintptr_t) p;
  48. }


  49. uintptr_t
  50. ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value, ngx_uint_t prefix)
  51. {
  52.     ngx_uint_t  thresh, n;

  53.     thresh = (1 << prefix) - 1;

  54.     if (value < thresh) {
  55.         if (p == NULL) {
  56.             return 1;
  57.         }

  58.         *p++ |= value;
  59.         return (uintptr_t) p;
  60.     }

  61.     value -= thresh;

  62.     if (p == NULL) {
  63.         for (n = 2; value >= 128; n++) {
  64.             value >>= 7;
  65.         }

  66.         return n;
  67.     }

  68.     *p++ |= thresh;

  69.     while (value >= 128) {
  70.         *p++ = 0x80 | value;
  71.         value >>= 7;
  72.     }

  73.     *p++ = value;

  74.     return (uintptr_t) p;
  75. }


  76. uintptr_t
  77. ngx_http_v3_encode_field_section_prefix(u_char *p, ngx_uint_t insert_count,
  78.     ngx_uint_t sign, ngx_uint_t delta_base)
  79. {
  80.     if (p == NULL) {
  81.         return ngx_http_v3_encode_prefix_int(NULL, insert_count, 8)
  82.                + ngx_http_v3_encode_prefix_int(NULL, delta_base, 7);
  83.     }

  84.     *p = 0;
  85.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, insert_count, 8);

  86.     *p = sign ? 0x80 : 0;
  87.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, delta_base, 7);

  88.     return (uintptr_t) p;
  89. }


  90. uintptr_t
  91. ngx_http_v3_encode_field_ri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index)
  92. {
  93.     /* Indexed Field Line */

  94.     if (p == NULL) {
  95.         return ngx_http_v3_encode_prefix_int(NULL, index, 6);
  96.     }

  97.     *p = dynamic ? 0x80 : 0xc0;

  98.     return ngx_http_v3_encode_prefix_int(p, index, 6);
  99. }


  100. uintptr_t
  101. ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index,
  102.     u_char *data, size_t len)
  103. {
  104.     size_t   hlen;
  105.     u_char  *p1, *p2;

  106.     /* Literal Field Line With Name Reference */

  107.     if (p == NULL) {
  108.         return ngx_http_v3_encode_prefix_int(NULL, index, 4)
  109.                + ngx_http_v3_encode_prefix_int(NULL, len, 7)
  110.                + len;
  111.     }

  112.     *p = dynamic ? 0x40 : 0x50;
  113.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4);

  114.     p1 = p;
  115.     *p = 0;
  116.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7);

  117.     if (data) {
  118.         p2 = p;
  119.         hlen = ngx_http_huff_encode(data, len, p, 0);

  120.         if (hlen) {
  121.             p = p1;
  122.             *p = 0x80;
  123.             p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7);

  124.             if (p != p2) {
  125.                 ngx_memmove(p, p2, hlen);
  126.             }

  127.             p += hlen;

  128.         } else {
  129.             p = ngx_cpymem(p, data, len);
  130.         }
  131.     }

  132.     return (uintptr_t) p;
  133. }


  134. uintptr_t
  135. ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name, ngx_str_t *value)
  136. {
  137.     size_t   hlen;
  138.     u_char  *p1, *p2;

  139.     /* Literal Field Line With Literal Name */

  140.     if (p == NULL) {
  141.         return ngx_http_v3_encode_prefix_int(NULL, name->len, 3)
  142.                + name->len
  143.                + ngx_http_v3_encode_prefix_int(NULL, value->len, 7)
  144.                + value->len;
  145.     }

  146.     p1 = p;
  147.     *p = 0x20;
  148.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3);

  149.     p2 = p;
  150.     hlen = ngx_http_huff_encode(name->data, name->len, p, 1);

  151.     if (hlen) {
  152.         p = p1;
  153.         *p = 0x28;
  154.         p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 3);

  155.         if (p != p2) {
  156.             ngx_memmove(p, p2, hlen);
  157.         }

  158.         p += hlen;

  159.     } else {
  160.         ngx_strlow(p, name->data, name->len);
  161.         p += name->len;
  162.     }

  163.     p1 = p;
  164.     *p = 0;
  165.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7);

  166.     p2 = p;
  167.     hlen = ngx_http_huff_encode(value->data, value->len, p, 0);

  168.     if (hlen) {
  169.         p = p1;
  170.         *p = 0x80;
  171.         p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7);

  172.         if (p != p2) {
  173.             ngx_memmove(p, p2, hlen);
  174.         }

  175.         p += hlen;

  176.     } else {
  177.         p = ngx_cpymem(p, value->data, value->len);
  178.     }

  179.     return (uintptr_t) p;
  180. }


  181. uintptr_t
  182. ngx_http_v3_encode_field_pbi(u_char *p, ngx_uint_t index)
  183. {
  184.     /* Indexed Field Line With Post-Base Index */

  185.     if (p == NULL) {
  186.         return ngx_http_v3_encode_prefix_int(NULL, index, 4);
  187.     }

  188.     *p = 0x10;

  189.     return ngx_http_v3_encode_prefix_int(p, index, 4);
  190. }


  191. uintptr_t
  192. ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index, u_char *data,
  193.     size_t len)
  194. {
  195.     size_t   hlen;
  196.     u_char  *p1, *p2;

  197.     /* Literal Field Line With Post-Base Name Reference */

  198.     if (p == NULL) {
  199.         return ngx_http_v3_encode_prefix_int(NULL, index, 3)
  200.                + ngx_http_v3_encode_prefix_int(NULL, len, 7)
  201.                + len;
  202.     }

  203.     *p = 0;
  204.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3);

  205.     p1 = p;
  206.     *p = 0;
  207.     p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7);

  208.     if (data) {
  209.         p2 = p;
  210.         hlen = ngx_http_huff_encode(data, len, p, 0);

  211.         if (hlen) {
  212.             p = p1;
  213.             *p = 0x80;
  214.             p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7);

  215.             if (p != p2) {
  216.                 ngx_memmove(p, p2, hlen);
  217.             }

  218.             p += hlen;

  219.         } else {
  220.             p = ngx_cpymem(p, data, len);
  221.         }
  222.     }

  223.     return (uintptr_t) p;
  224. }