aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2016-03-30 17:19:29 -0700
committerGravatar David Garcia Quintas <dgq@google.com>2016-03-30 22:56:18 -0700
commite3a49f82c4009112a96eca233b13a48f4350079a (patch)
treec296d2d094e2213122babd4d54ed5758ef45d54b /src/core
parenta5dc80d22ae03f76525f030fb1bfd47c0d8266a2 (diff)
Added & and = to URI queries
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lib/client_config/uri_parser.c56
-rw-r--r--src/core/lib/client_config/uri_parser.h8
2 files changed, 64 insertions, 0 deletions
diff --git a/src/core/lib/client_config/uri_parser.c b/src/core/lib/client_config/uri_parser.c
index d3228dec5f..d818d4c4d1 100644
--- a/src/core/lib/client_config/uri_parser.c
+++ b/src/core/lib/client_config/uri_parser.c
@@ -38,8 +38,12 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/support/string.h"
+
/** a size_t default value... maps to all 1's */
#define NOT_SET (~(size_t)0)
@@ -133,6 +137,51 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) {
return 1;
}
+static void do_nothing(void *ignored) {}
+static void parse_query_parts(grpc_uri *uri) {
+ static const char *QUERY_PARTS_SEPARATOR = "&";
+ static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
+ GPR_ASSERT(uri->query != NULL);
+ if (uri->query[0] == '\0') {
+ uri->query_parts = NULL;
+ uri->query_parts_values = NULL;
+ uri->num_query_parts = 0;
+ return;
+ }
+ gpr_slice query_slice =
+ gpr_slice_new(uri->query, strlen(uri->query), do_nothing);
+ gpr_slice_buffer query_parts; /* the &-separated elements of the query */
+ gpr_slice_buffer query_param_parts; /* the =-separated subelements */
+
+ gpr_slice_buffer_init(&query_parts);
+ gpr_slice_buffer_init(&query_param_parts);
+
+ gpr_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
+ uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
+ uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
+ uri->num_query_parts = query_parts.count;
+ for (size_t i = 0; i < query_parts.count; i++) {
+ gpr_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
+ &query_param_parts);
+ GPR_ASSERT(query_param_parts.count > 0);
+ uri->query_parts[i] =
+ gpr_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
+ if (query_param_parts.count > 1) {
+ /* TODO(dgq): only the first value after the separator is considered.
+ * Perhaps all chars after the first separator for the query part should
+ * be included, even if they include the separator. */
+ uri->query_parts_values[i] =
+ gpr_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
+ } else {
+ uri->query_parts_values[i] = NULL;
+ }
+ gpr_slice_buffer_reset_and_unref(&query_param_parts);
+ }
+ gpr_slice_buffer_destroy(&query_parts);
+ gpr_slice_buffer_destroy(&query_param_parts);
+ gpr_slice_unref(query_slice);
+}
+
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
grpc_uri *uri;
size_t scheme_begin = 0;
@@ -227,6 +276,7 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
uri->path = copy_component(uri_text, path_begin, path_end);
uri->query = copy_component(uri_text, query_begin, query_end);
uri->fragment = copy_component(uri_text, fragment_begin, fragment_end);
+ parse_query_parts(uri);
return uri;
}
@@ -237,6 +287,12 @@ void grpc_uri_destroy(grpc_uri *uri) {
gpr_free(uri->authority);
gpr_free(uri->path);
gpr_free(uri->query);
+ for (size_t i = 0; i < uri->num_query_parts; ++i) {
+ gpr_free(uri->query_parts[i]);
+ gpr_free(uri->query_parts_values[i]);
+ }
+ gpr_free(uri->query_parts);
+ gpr_free(uri->query_parts_values);
gpr_free(uri->fragment);
gpr_free(uri);
}
diff --git a/src/core/lib/client_config/uri_parser.h b/src/core/lib/client_config/uri_parser.h
index d70d451e60..115dd5a2f6 100644
--- a/src/core/lib/client_config/uri_parser.h
+++ b/src/core/lib/client_config/uri_parser.h
@@ -34,11 +34,19 @@
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H
#define GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H
+#include <stddef.h>
+
typedef struct {
char *scheme;
char *authority;
char *path;
char *query;
+ /** Query substrings separated by '&' */
+ char **query_parts;
+ /** Number of elements in \a query_parts and \a query_parts_values */
+ size_t num_query_parts;
+ /** Split each query part by '='. NULL if not present. */
+ char **query_parts_values;
char *fragment;
} grpc_uri;