1 /*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <grpc/support/port_platform.h>
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <grpc/compression.h>
25
26 #include "src/core/lib/compression/algorithm_metadata.h"
27 #include "src/core/lib/compression/compression_internal.h"
28 #include "src/core/lib/gpr/useful.h"
29 #include "src/core/lib/slice/slice_utils.h"
30 #include "src/core/lib/surface/api_trace.h"
31 #include "src/core/lib/transport/static_metadata.h"
32
grpc_compression_algorithm_is_message(grpc_compression_algorithm algorithm)33 int grpc_compression_algorithm_is_message(
34 grpc_compression_algorithm algorithm) {
35 return (algorithm >= GRPC_COMPRESS_DEFLATE && algorithm <= GRPC_COMPRESS_GZIP)
36 ? 1
37 : 0;
38 }
39
grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm)40 int grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm) {
41 return (algorithm == GRPC_COMPRESS_STREAM_GZIP) ? 1 : 0;
42 }
43
grpc_compression_algorithm_parse(grpc_slice name,grpc_compression_algorithm * algorithm)44 int grpc_compression_algorithm_parse(grpc_slice name,
45 grpc_compression_algorithm* algorithm) {
46 if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_IDENTITY)) {
47 *algorithm = GRPC_COMPRESS_NONE;
48 return 1;
49 } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_DEFLATE)) {
50 *algorithm = GRPC_COMPRESS_DEFLATE;
51 return 1;
52 } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_GZIP)) {
53 *algorithm = GRPC_COMPRESS_GZIP;
54 return 1;
55 } else if (grpc_slice_eq_static_interned(name,
56 GRPC_MDSTR_STREAM_SLASH_GZIP)) {
57 *algorithm = GRPC_COMPRESS_STREAM_GZIP;
58 return 1;
59 } else {
60 return 0;
61 }
62 }
63
grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,const char ** name)64 int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
65 const char** name) {
66 GRPC_API_TRACE("grpc_compression_algorithm_name(algorithm=%d, name=%p)", 2,
67 ((int)algorithm, name));
68 switch (algorithm) {
69 case GRPC_COMPRESS_NONE:
70 *name = "identity";
71 return 1;
72 case GRPC_COMPRESS_DEFLATE:
73 *name = "deflate";
74 return 1;
75 case GRPC_COMPRESS_GZIP:
76 *name = "gzip";
77 return 1;
78 case GRPC_COMPRESS_STREAM_GZIP:
79 *name = "stream/gzip";
80 return 1;
81 case GRPC_COMPRESS_ALGORITHMS_COUNT:
82 return 0;
83 }
84 return 0;
85 }
86
grpc_compression_algorithm_for_level(grpc_compression_level level,uint32_t accepted_encodings)87 grpc_compression_algorithm grpc_compression_algorithm_for_level(
88 grpc_compression_level level, uint32_t accepted_encodings) {
89 grpc_compression_algorithm algo;
90 if (level == GRPC_COMPRESS_LEVEL_NONE) {
91 return GRPC_COMPRESS_NONE;
92 } else if (level <= GRPC_COMPRESS_LEVEL_HIGH) {
93 // TODO(mxyan): Design algorithm to select from all algorithms, including
94 // stream compression algorithm
95 if (!grpc_compression_algorithm_from_message_stream_compression_algorithm(
96 &algo,
97 grpc_message_compression_algorithm_for_level(
98 level,
99 grpc_compression_bitset_to_message_bitset(accepted_encodings)),
100 static_cast<grpc_stream_compression_algorithm>(0))) {
101 gpr_log(GPR_ERROR, "Parse compression level error");
102 return GRPC_COMPRESS_NONE;
103 }
104 return algo;
105 } else {
106 gpr_log(GPR_ERROR, "Unknown compression level: %d", level);
107 return GRPC_COMPRESS_NONE;
108 }
109 }
110
grpc_compression_options_init(grpc_compression_options * opts)111 void grpc_compression_options_init(grpc_compression_options* opts) {
112 memset(opts, 0, sizeof(*opts));
113 /* all enabled by default */
114 opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
115 }
116
grpc_compression_options_enable_algorithm(grpc_compression_options * opts,grpc_compression_algorithm algorithm)117 void grpc_compression_options_enable_algorithm(
118 grpc_compression_options* opts, grpc_compression_algorithm algorithm) {
119 GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
120 }
121
grpc_compression_options_disable_algorithm(grpc_compression_options * opts,grpc_compression_algorithm algorithm)122 void grpc_compression_options_disable_algorithm(
123 grpc_compression_options* opts, grpc_compression_algorithm algorithm) {
124 GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
125 }
126
grpc_compression_options_is_algorithm_enabled(const grpc_compression_options * opts,grpc_compression_algorithm algorithm)127 int grpc_compression_options_is_algorithm_enabled(
128 const grpc_compression_options* opts,
129 grpc_compression_algorithm algorithm) {
130 return grpc_compression_options_is_algorithm_enabled_internal(opts,
131 algorithm);
132 }
133
grpc_compression_algorithm_slice(grpc_compression_algorithm algorithm)134 grpc_slice grpc_compression_algorithm_slice(
135 grpc_compression_algorithm algorithm) {
136 switch (algorithm) {
137 case GRPC_COMPRESS_NONE:
138 return GRPC_MDSTR_IDENTITY;
139 case GRPC_COMPRESS_DEFLATE:
140 return GRPC_MDSTR_DEFLATE;
141 case GRPC_COMPRESS_GZIP:
142 return GRPC_MDSTR_GZIP;
143 case GRPC_COMPRESS_STREAM_GZIP:
144 return GRPC_MDSTR_STREAM_SLASH_GZIP;
145 case GRPC_COMPRESS_ALGORITHMS_COUNT:
146 return grpc_empty_slice();
147 }
148 return grpc_empty_slice();
149 }
150
grpc_compression_algorithm_from_slice(const grpc_slice & str)151 grpc_compression_algorithm grpc_compression_algorithm_from_slice(
152 const grpc_slice& str) {
153 if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) {
154 return GRPC_COMPRESS_NONE;
155 }
156 if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_DEFLATE)) {
157 return GRPC_COMPRESS_DEFLATE;
158 }
159 if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) {
160 return GRPC_COMPRESS_GZIP;
161 }
162 if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_STREAM_SLASH_GZIP)) {
163 return GRPC_COMPRESS_STREAM_GZIP;
164 }
165 return GRPC_COMPRESS_ALGORITHMS_COUNT;
166 }
167
grpc_compression_encoding_mdelem(grpc_compression_algorithm algorithm)168 grpc_mdelem grpc_compression_encoding_mdelem(
169 grpc_compression_algorithm algorithm) {
170 switch (algorithm) {
171 case GRPC_COMPRESS_NONE:
172 return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
173 case GRPC_COMPRESS_DEFLATE:
174 return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
175 case GRPC_COMPRESS_GZIP:
176 return GRPC_MDELEM_GRPC_ENCODING_GZIP;
177 case GRPC_COMPRESS_STREAM_GZIP:
178 return GRPC_MDELEM_GRPC_ENCODING_GZIP;
179 default:
180 break;
181 }
182 return GRPC_MDNULL;
183 }
184