Allow spaces in content-encoding

reviewable/pr12708/r1
Muxi Yan 8 years ago
parent 92d1bc11ba
commit d4bb9bddd6
  1. 41
      src/core/lib/slice/slice_string_helpers.c
  2. 5
      src/core/lib/slice/slice_string_helpers.h
  3. 2
      src/core/lib/surface/call.c
  4. 67
      test/core/slice/slice_string_helpers_test.c

@ -56,24 +56,57 @@ static int slice_find_separator_offset(const grpc_slice str, const char *sep,
return 0;
}
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
static void skip_leading_trailing_spaces(const uint8_t *str_buffer, size_t *begin, size_t *end) {
while (*begin < *end && str_buffer[*begin] == ' ') {
(*begin)++;
}
while (*begin < *end && str_buffer[*end - 1] == ' ') {
(*end)--;
}
}
static void grpc_slice_split_inner(grpc_slice str, const char *sep, grpc_slice_buffer *dst, bool no_space) {
const size_t sep_len = strlen(sep);
size_t begin, end;
const uint8_t *str_buffer = GRPC_SLICE_START_PTR(str);
size_t sep_pos;
GPR_ASSERT(sep_len > 0);
if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) {
do {
sep_pos = end;
if (no_space) {
skip_leading_trailing_spaces(str_buffer, &begin, &end);
}
grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
} while (slice_find_separator_offset(str, sep, end + sep_len, &begin,
} while (slice_find_separator_offset(str, sep, sep_pos + sep_len, &begin,
&end) != 0);
begin = sep_pos + sep_len;
end = GRPC_SLICE_LENGTH(str);
if (no_space) {
skip_leading_trailing_spaces(str_buffer, &begin, &end);
}
grpc_slice_buffer_add_indexed(
dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
dst, grpc_slice_sub(str, begin, end));
} else { /* no sep found, add whole input */
grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
begin = 0;
end = GRPC_SLICE_LENGTH(str);
if (no_space) {
skip_leading_trailing_spaces(str_buffer, &begin, &end);
}
grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
}
}
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
grpc_slice_split_inner(str, sep, dst, false);
}
void grpc_slice_split_without_space(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
grpc_slice_split_inner(str, sep, dst, true);
}
bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result) {
return gpr_parse_bytes_to_uint32((const char *)GRPC_SLICE_START_PTR(str),
GRPC_SLICE_LENGTH(str), result) != 0;

@ -39,6 +39,11 @@ char *grpc_dump_slice(grpc_slice slice, uint32_t flags);
* should be a properly initialized instance. */
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
/** Split \a str by the separator \a sep and remove the leading and trailing
* spaces of each resulting token. Results are stored in \a dst, which should be
* a properly initialized instance. */
void grpc_slice_split_without_space(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result);
#ifdef __cplusplus

@ -875,7 +875,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
accept_encoding_slice = GRPC_MDVALUE(mdel);
grpc_slice_buffer_init(&accept_encoding_parts);
grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
grpc_slice_split_without_space(accept_encoding_slice, ",", &accept_encoding_parts);
GPR_BITSET(encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
for (i = 0; i < accept_encoding_parts.count; i++) {

@ -127,9 +127,76 @@ static void test_strsplit(void) {
gpr_free(parts);
}
static void test_strsplit_nospace(void) {
grpc_slice_buffer *parts;
grpc_slice str;
LOG_TEST_NAME("test_strsplit_nospace");
parts = gpr_malloc(sizeof(grpc_slice_buffer));
grpc_slice_buffer_init(parts);
str = grpc_slice_from_copied_string("one ,two, three , four");
grpc_slice_split_without_space(str, ",", parts);
GPR_ASSERT(4 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one"));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "two"));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[2], "three"));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[3], "four"));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
/* separator not present in string */
str = grpc_slice_from_copied_string("one two three four ");
grpc_slice_split_without_space(str, ",", parts);
GPR_ASSERT(1 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one two three four"));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
/* separator at the end */
str = grpc_slice_from_copied_string("foo,");
grpc_slice_split_without_space(str, ",", parts);
GPR_ASSERT(2 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "foo"));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
/* separator at the beginning */
str = grpc_slice_from_copied_string(" , foo");
grpc_slice_split_without_space(str, ",", parts);
GPR_ASSERT(2 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "foo"));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
/* standalone separator */
str = grpc_slice_from_copied_string(", ");
grpc_slice_split_without_space(str, ", ", parts);
GPR_ASSERT(2 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
/* empty input */
str = grpc_slice_from_copied_string("");
grpc_slice_split_without_space(str, ",", parts);
GPR_ASSERT(1 == parts->count);
GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
grpc_slice_buffer_reset_and_unref(parts);
grpc_slice_unref(str);
grpc_slice_buffer_destroy(parts);
gpr_free(parts);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_dump_slice();
test_strsplit();
test_strsplit_nospace();
return 0;
}

Loading…
Cancel
Save