Merge github.com:grpc/grpc into split-me-baby-one-more-time

pull/2286/head
Craig Tiller 9 years ago
commit 3b27de1fc4
  1. 2
      Makefile
  2. 3
      include/grpc/grpc.h
  3. 7
      include/grpc/impl/codegen/grpc_types.h
  4. 4
      src/core/lib/channel/http_client_filter.c
  5. 18
      src/core/lib/channel/http_server_filter.c
  6. 15
      src/core/lib/surface/call.c
  7. 30
      src/core/lib/surface/server.c
  8. 19
      src/core/lib/transport/static_metadata.c
  9. 106
      src/core/lib/transport/static_metadata.h
  10. 7
      src/core/lib/transport/transport.h
  11. 3
      src/cpp/server/server.cc
  12. 2
      src/python/grpcio/grpc/_cython/imports.generated.h
  13. 2
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  14. 9
      test/core/bad_client/bad_client.c
  15. 6
      test/core/end2end/end2end_nosec_tests.c
  16. 6
      test/core/end2end/end2end_tests.c
  17. 9
      test/core/end2end/fixtures/proxy.c
  18. 1
      test/core/end2end/gen_build_yaml.py
  19. 248
      test/core/end2end/tests/idempotent_request.c
  20. 1
      test/core/end2end/tests/simple_request.c
  21. 16
      test/core/surface/server_test.c
  22. 29
      tools/codegen/core/gen_static_metadata.py
  23. 2
      tools/run_tests/sources_and_headers.json
  24. 621
      tools/run_tests/tests.json
  25. 2
      vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
  26. 3
      vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
  27. 2
      vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
  28. 3
      vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters

@ -5830,6 +5830,7 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/graceful_server_shutdown.c \
test/core/end2end/tests/high_initial_seqno.c \
test/core/end2end/tests/hpack_size.c \
test/core/end2end/tests/idempotent_request.c \
test/core/end2end/tests/invoke_large_request.c \
test/core/end2end/tests/large_metadata.c \
test/core/end2end/tests/max_concurrent_streams.c \
@ -5904,6 +5905,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/graceful_server_shutdown.c \
test/core/end2end/tests/high_initial_seqno.c \
test/core/end2end/tests/hpack_size.c \
test/core/end2end/tests/idempotent_request.c \
test/core/end2end/tests/invoke_large_request.c \
test/core/end2end/tests/large_metadata.c \
test/core/end2end/tests/max_concurrent_streams.c \

@ -297,7 +297,8 @@ GRPCAPI grpc_call_error grpc_server_request_call(
Must be called before grpc_server_start.
Returns NULL on failure. */
GRPCAPI void *grpc_server_register_method(grpc_server *server,
const char *method, const char *host);
const char *method, const char *host,
uint32_t flags);
/** Request notification of a new pre-registered call. 'cq_for_notification'
must have been registered to the server via

@ -199,6 +199,12 @@ typedef enum grpc_call_error {
/** Mask of all valid flags. */
#define GRPC_WRITE_USED_MASK (GRPC_WRITE_BUFFER_HINT | GRPC_WRITE_NO_COMPRESS)
/* Initial metadata flags */
/** Signal that the call is idempotent */
#define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
/** Mask of all valid flags */
#define GRPC_INITIAL_METADATA_USED_MASK GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
/** A single metadata element */
typedef struct grpc_metadata {
const char *key;
@ -250,6 +256,7 @@ typedef struct {
char *host;
size_t host_capacity;
gpr_timespec deadline;
uint32_t flags;
void *reserved;
} grpc_call_details;

@ -112,7 +112,9 @@ static void hc_mutate_op(grpc_call_element *elem,
/* Send : prefixed headers, which have to be before any application
layer headers. */
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
GRPC_MDELEM_METHOD_POST);
op->send_idempotent_request
? GRPC_MDELEM_METHOD_PUT
: GRPC_MDELEM_METHOD_POST);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
channeld->static_scheme);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,

@ -41,7 +41,7 @@
typedef struct call_data {
uint8_t seen_path;
uint8_t seen_post;
uint8_t seen_method;
uint8_t sent_status;
uint8_t seen_scheme;
uint8_t seen_te_trailers;
@ -50,6 +50,7 @@ typedef struct call_data {
grpc_linked_mdelem content_type;
grpc_metadata_batch *recv_initial_metadata;
bool *recv_idempotent_request;
/** Closure to call when finished with the hs_on_recv hook */
grpc_closure *on_done_recv;
/** Receive closures are chained: we inject this closure as the on_done_recv
@ -72,11 +73,16 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* Check if it is one of the headers we care about. */
if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_SCHEME_HTTP ||
md == GRPC_MDELEM_SCHEME_HTTPS ||
md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
/* swallow it */
if (md == GRPC_MDELEM_METHOD_POST) {
calld->seen_post = 1;
calld->seen_method = 1;
*calld->recv_idempotent_request = false;
} else if (md == GRPC_MDELEM_METHOD_PUT) {
calld->seen_method = 1;
*calld->recv_idempotent_request = true;
} else if (md->key == GRPC_MDSTR_SCHEME) {
calld->seen_scheme = 1;
} else if (md == GRPC_MDELEM_TE_TRAILERS) {
@ -142,7 +148,7 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) {
/* Have we seen the required http2 transport headers?
(:method, :scheme, content-type, with :path and :authority covered
at the channel level right now) */
if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers &&
if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers &&
calld->seen_path && calld->seen_authority) {
/* do nothing */
} else {
@ -152,7 +158,7 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) {
if (!calld->seen_authority) {
gpr_log(GPR_ERROR, "Missing :authority header");
}
if (!calld->seen_post) {
if (!calld->seen_method) {
gpr_log(GPR_ERROR, "Missing :method header");
}
if (!calld->seen_scheme) {
@ -185,7 +191,9 @@ static void hs_mutate_op(grpc_call_element *elem,
if (op->recv_initial_metadata) {
/* substitute our callback for the higher callback */
GPR_ASSERT(op->recv_idempotent_request != NULL);
calld->recv_initial_metadata = op->recv_initial_metadata;
calld->recv_idempotent_request = op->recv_idempotent_request;
calld->on_done_recv = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->hs_on_recv;
}

@ -911,7 +911,7 @@ static void set_cancelled_value(grpc_status_code status, void *dest) {
*(int *)dest = (status != GRPC_STATUS_OK);
}
static int are_write_flags_valid(uint32_t flags) {
static bool are_write_flags_valid(uint32_t flags) {
/* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
const uint32_t allowed_write_positions =
(GRPC_WRITE_USED_MASK | GRPC_WRITE_INTERNAL_USED_MASK);
@ -919,6 +919,15 @@ static int are_write_flags_valid(uint32_t flags) {
return !(flags & invalid_positions);
}
static bool are_initial_metadata_flags_valid(uint32_t flags, bool is_client) {
/* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
uint32_t invalid_positions = ~GRPC_INITIAL_METADATA_USED_MASK;
if (!is_client) {
invalid_positions |= GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
}
return !(flags & invalid_positions);
}
static batch_control *allocate_batch_control(grpc_call *call) {
size_t i;
for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) {
@ -1198,7 +1207,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
switch (op->op) {
case GRPC_OP_SEND_INITIAL_METADATA:
/* Flag validation: currently allow no flags */
if (op->flags != 0) {
if (!are_initial_metadata_flags_valid(op->flags, call->is_client)) {
error = GRPC_CALL_ERROR_INVALID_FLAGS;
goto done_with_error;
}
@ -1222,6 +1231,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->metadata_batch[0][0].deadline = call->send_deadline;
stream_op.send_initial_metadata =
&call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
stream_op.send_idempotent_request =
(op->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) != 0;
break;
case GRPC_OP_SEND_MESSAGE:
if (!are_write_flags_valid(op->flags)) {

@ -100,6 +100,7 @@ typedef struct requested_call {
typedef struct channel_registered_method {
registered_method *server_registered_method;
uint32_t flags;
grpc_mdstr *method;
grpc_mdstr *host;
} channel_registered_method;
@ -152,6 +153,7 @@ struct call_data {
grpc_completion_queue *cq_new;
grpc_metadata_batch *recv_initial_metadata;
bool recv_idempotent_request;
grpc_metadata_array initial_metadata;
grpc_closure got_initial_metadata;
@ -171,6 +173,7 @@ struct request_matcher {
struct registered_method {
char *method;
char *host;
uint32_t flags;
request_matcher request_matcher;
registered_method *next;
};
@ -468,6 +471,9 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
if (!rm) break;
if (rm->host != calld->host) continue;
if (rm->method != calld->path) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
!calld->recv_idempotent_request)
continue;
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher);
return;
@ -480,6 +486,9 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
if (!rm) break;
if (rm->host != NULL) continue;
if (rm->method != calld->path) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
!calld->recv_idempotent_request)
continue;
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher);
return;
@ -598,9 +607,11 @@ static void server_mutate_op(grpc_call_element *elem,
call_data *calld = elem->call_data;
if (op->recv_initial_metadata != NULL) {
GPR_ASSERT(op->recv_idempotent_request == NULL);
calld->recv_initial_metadata = op->recv_initial_metadata;
calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
op->recv_idempotent_request = &calld->recv_idempotent_request;
}
}
@ -830,10 +841,12 @@ static int streq(const char *a, const char *b) {
}
void *grpc_server_register_method(grpc_server *server, const char *method,
const char *host) {
const char *host, uint32_t flags) {
registered_method *m;
GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
3, (server, method, host));
GRPC_API_TRACE(
"grpc_server_register_method(server=%p, method=%s, host=%s, "
"flags=0x%08x)",
4, (server, method, host, flags));
if (!method) {
gpr_log(GPR_ERROR,
"grpc_server_register_method method string cannot be NULL");
@ -846,12 +859,18 @@ void *grpc_server_register_method(grpc_server *server, const char *method,
return NULL;
}
}
if ((flags & ~GRPC_INITIAL_METADATA_USED_MASK) != 0) {
gpr_log(GPR_ERROR, "grpc_server_register_method invalid flags 0x%08x",
flags);
return NULL;
}
m = gpr_malloc(sizeof(registered_method));
memset(m, 0, sizeof(*m));
request_matcher_init(&m->request_matcher, server->max_requested_calls);
m->method = gpr_strdup(method);
m->host = gpr_strdup(host);
m->next = server->registered_methods;
m->flags = flags;
server->registered_methods = m;
return m;
}
@ -930,6 +949,7 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
if (probes > max_probes) max_probes = probes;
crm = &chand->registered_methods[(hash + probes) % slots];
crm->server_registered_method = rm;
crm->flags = rm->flags;
crm->host = host;
crm->method = method;
}
@ -1247,6 +1267,10 @@ static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
cpstr(&rc->data.batch.details->method,
&rc->data.batch.details->method_capacity, calld->path);
rc->data.batch.details->deadline = calld->deadline;
rc->data.batch.details->flags =
0 | (calld->recv_idempotent_request
? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
: 0);
break;
case REGISTERED_CALL:
*rc->data.registered.deadline = calld->deadline;

@ -1,5 +1,4 @@
/*
*
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
@ -28,19 +27,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* WARNING: Auto-generated code.
*
* To make changes to this file, change
* tools/codegen/core/gen_static_metadata.py,
* and then re-run it.
* tools/codegen/core/gen_static_metadata.py, and then re-run it.
*
* See metadata.h for an explanation of the interface here, and metadata.c for
* an
* explanation of what's going on.
* an explanation of what's going on.
*/
#include "src/core/lib/transport/static_metadata.h"
@ -52,7 +48,7 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
{11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35,
@ -60,10 +56,10 @@ const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33,
42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53,
46, 0, 46, 1, 46, 2, 50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35,
62, 35, 63, 35, 64, 35, 65, 35, 66, 40, 66, 68, 67, 78, 67, 79, 69, 35,
70, 35, 71, 35, 72, 35, 73, 35, 74, 35, 75, 41, 75, 51, 75, 52, 76, 35,
77, 35, 80, 3, 80, 4, 80, 5, 80, 6, 80, 7, 80, 8, 80, 9, 81, 35,
82, 83, 84, 35, 85, 35, 86, 35, 87, 35, 88, 35};
62, 35, 63, 35, 64, 35, 65, 35, 66, 40, 66, 68, 66, 71, 67, 79, 67, 80,
69, 35, 70, 35, 72, 35, 73, 35, 74, 35, 75, 35, 76, 41, 76, 51, 76, 52,
77, 35, 78, 35, 81, 3, 81, 4, 81, 5, 81, 6, 81, 7, 81, 8, 81, 9,
82, 35, 83, 84, 85, 35, 86, 35, 87, 35, 88, 35, 89, 35};
const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"0",
@ -137,6 +133,7 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"POST",
"proxy-authenticate",
"proxy-authorization",
"PUT",
"range",
"referer",
"refresh",

@ -1,5 +1,4 @@
/*
*
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
@ -28,19 +27,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* WARNING: Auto-generated code.
*
* To make changes to this file, change
* tools/codegen/core/gen_static_metadata.py,
* and then re-run it.
* tools/codegen/core/gen_static_metadata.py, and then re-run it.
*
* See metadata.h for an explanation of the interface here, and metadata.c for
* an
* explanation of what's going on.
* an explanation of what's going on.
*/
#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H
@ -48,7 +44,7 @@
#include "src/core/lib/transport/metadata.h"
#define GRPC_STATIC_MDSTR_COUNT 89
#define GRPC_STATIC_MDSTR_COUNT 90
extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
/* "0" */
#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
@ -193,44 +189,46 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[69])
/* "proxy-authorization" */
#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[70])
/* "PUT" */
#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[71])
/* "range" */
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[71])
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[72])
/* "referer" */
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[72])
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[73])
/* "refresh" */
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[73])
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[74])
/* "retry-after" */
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[74])
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[75])
/* ":scheme" */
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[75])
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[76])
/* "server" */
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[76])
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[77])
/* "set-cookie" */
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[77])
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[78])
/* "/" */
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[78])
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[79])
/* "/index.html" */
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[79])
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[80])
/* ":status" */
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[80])
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[81])
/* "strict-transport-security" */
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[81])
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[82])
/* "te" */
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[82])
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[83])
/* "trailers" */
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[83])
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[84])
/* "transfer-encoding" */
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[84])
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[85])
/* "user-agent" */
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[85])
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[86])
/* "vary" */
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[86])
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[87])
/* "via" */
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[87])
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[88])
/* "www-authenticate" */
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[88])
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[89])
#define GRPC_STATIC_MDELEM_COUNT 78
#define GRPC_STATIC_MDELEM_COUNT 79
extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "accept-charset": "" */
@ -343,61 +341,63 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[49])
/* ":method": "POST" */
#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[50])
/* ":method": "PUT" */
#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[51])
/* ":path": "/" */
#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[51])
#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[52])
/* ":path": "/index.html" */
#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[52])
#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[53])
/* "proxy-authenticate": "" */
#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[53])
#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[54])
/* "proxy-authorization": "" */
#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[54])
#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[55])
/* "range": "" */
#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[55])
#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[56])
/* "referer": "" */
#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[56])
#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[57])
/* "refresh": "" */
#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[57])
#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[58])
/* "retry-after": "" */
#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[58])
#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[59])
/* ":scheme": "grpc" */
#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[59])
#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[60])
/* ":scheme": "http" */
#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[60])
#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[61])
/* ":scheme": "https" */
#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[61])
#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[62])
/* "server": "" */
#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[62])
#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[63])
/* "set-cookie": "" */
#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[63])
#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[64])
/* ":status": "200" */
#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[64])
#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[65])
/* ":status": "204" */
#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[65])
#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[66])
/* ":status": "206" */
#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[66])
#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[67])
/* ":status": "304" */
#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[67])
#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[68])
/* ":status": "400" */
#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[68])
#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[69])
/* ":status": "404" */
#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[69])
#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[70])
/* ":status": "500" */
#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[70])
#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[71])
/* "strict-transport-security": "" */
#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
(&grpc_static_mdelem_table[71])
(&grpc_static_mdelem_table[72])
/* "te": "trailers" */
#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[72])
#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[73])
/* "transfer-encoding": "" */
#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[73])
#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[74])
/* "user-agent": "" */
#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[74])
#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[75])
/* "vary": "" */
#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[75])
#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[76])
/* "via": "" */
#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[76])
#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[77])
/* "www-authenticate": "" */
#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[77])
#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[78])
extern const uint8_t
grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];

@ -103,8 +103,12 @@ typedef struct grpc_transport_stream_op {
have been completed. */
grpc_closure *on_complete;
/** Send initial metadata to the peer, from the provided metadata batch. */
/** Send initial metadata to the peer, from the provided metadata batch.
idempotent_request MUST be set if this is non-null */
grpc_metadata_batch *send_initial_metadata;
/** Iff send_initial_metadata != NULL, flags if this is an idempotent request
or not */
bool send_idempotent_request;
/** Send trailing metadata to the peer, from the provided metadata batch. */
grpc_metadata_batch *send_trailing_metadata;
@ -114,6 +118,7 @@ typedef struct grpc_transport_stream_op {
/** Receive initial metadata from the stream, into provided metadata batch. */
grpc_metadata_batch *recv_initial_metadata;
bool *recv_idempotent_request;
/** Should be enqueued when initial metadata is ready to be processed. */
grpc_closure *recv_initial_metadata_ready;

@ -264,6 +264,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
void* const tag_;
bool in_flight_;
const bool has_request_payload_;
uint32_t incoming_flags_;
grpc_call* call_;
grpc_call_details* call_details_;
gpr_timespec deadline_;
@ -334,7 +335,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) {
}
RpcServiceMethod* method = it->get();
void* tag = grpc_server_register_method(server_, method->name(),
host ? host->c_str() : nullptr);
host ? host->c_str() : nullptr, 0);
if (tag == nullptr) {
gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
method->name());

@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import;
typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
extern grpc_server_request_call_type grpc_server_request_call_import;
#define grpc_server_request_call grpc_server_request_call_import
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host);
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags);
extern grpc_server_register_method_type grpc_server_register_method_import;
#define grpc_server_register_method grpc_server_register_method_import
typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);

@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import;
typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
extern grpc_server_request_call_type grpc_server_request_call_import;
#define grpc_server_request_call grpc_server_request_call_import
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host);
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags);
extern grpc_server_register_method_type grpc_server_register_method_import;
#define grpc_server_register_method grpc_server_register_method_import
typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);

@ -33,6 +33,9 @@
#include "test/core/bad_client/bad_client.h"
#include <grpc/support/alloc.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/http_server_filter.h"
@ -41,10 +44,6 @@
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/surface/server.h"
#include <grpc/support/alloc.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
typedef struct {
grpc_server *server;
grpc_completion_queue *cq;
@ -110,7 +109,7 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
grpc_server_register_completion_queue(a.server, a.cq, NULL);
a.registered_method =
grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD,
GRPC_BAD_CLIENT_REGISTERED_HOST);
GRPC_BAD_CLIENT_REGISTERED_HOST, 0);
grpc_server_start(a.server);
transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0);
server_setup_transport(&a, transport);

@ -56,6 +56,7 @@ extern void empty_batch(grpc_end2end_test_config config);
extern void graceful_server_shutdown(grpc_end2end_test_config config);
extern void high_initial_seqno(grpc_end2end_test_config config);
extern void hpack_size(grpc_end2end_test_config config);
extern void idempotent_request(grpc_end2end_test_config config);
extern void invoke_large_request(grpc_end2end_test_config config);
extern void large_metadata(grpc_end2end_test_config config);
extern void max_concurrent_streams(grpc_end2end_test_config config);
@ -97,6 +98,7 @@ void grpc_end2end_tests(int argc, char **argv,
graceful_server_shutdown(config);
high_initial_seqno(config);
hpack_size(config);
idempotent_request(config);
invoke_large_request(config);
large_metadata(config);
max_concurrent_streams(config);
@ -184,6 +186,10 @@ void grpc_end2end_tests(int argc, char **argv,
hpack_size(config);
continue;
}
if (0 == strcmp("idempotent_request", argv[i])) {
idempotent_request(config);
continue;
}
if (0 == strcmp("invoke_large_request", argv[i])) {
invoke_large_request(config);
continue;

@ -57,6 +57,7 @@ extern void empty_batch(grpc_end2end_test_config config);
extern void graceful_server_shutdown(grpc_end2end_test_config config);
extern void high_initial_seqno(grpc_end2end_test_config config);
extern void hpack_size(grpc_end2end_test_config config);
extern void idempotent_request(grpc_end2end_test_config config);
extern void invoke_large_request(grpc_end2end_test_config config);
extern void large_metadata(grpc_end2end_test_config config);
extern void max_concurrent_streams(grpc_end2end_test_config config);
@ -99,6 +100,7 @@ void grpc_end2end_tests(int argc, char **argv,
graceful_server_shutdown(config);
high_initial_seqno(config);
hpack_size(config);
idempotent_request(config);
invoke_large_request(config);
large_metadata(config);
max_concurrent_streams(config);
@ -190,6 +192,10 @@ void grpc_end2end_tests(int argc, char **argv,
hpack_size(config);
continue;
}
if (0 == strcmp("idempotent_request", argv[i])) {
idempotent_request(config);
continue;
}
if (0 == strcmp("invoke_large_request", argv[i])) {
invoke_large_request(config);
continue;

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -338,10 +338,10 @@ static void on_new_call(void *arg, int success) {
proxy->new_call_details.deadline, NULL);
gpr_ref_init(&pc->refs, 1);
op.flags = 0;
op.reserved = NULL;
op.op = GRPC_OP_RECV_INITIAL_METADATA;
op.flags = 0;
op.data.recv_initial_metadata = &pc->p2s_initial_metadata;
refpc(pc, "on_p2s_recv_initial_metadata");
err = grpc_call_start_batch(
@ -349,6 +349,7 @@ static void on_new_call(void *arg, int success) {
GPR_ASSERT(err == GRPC_CALL_OK);
op.op = GRPC_OP_SEND_INITIAL_METADATA;
op.flags = proxy->new_call_details.flags;
op.data.send_initial_metadata.count = pc->c2p_initial_metadata.count;
op.data.send_initial_metadata.metadata = pc->c2p_initial_metadata.metadata;
refpc(pc, "on_p2s_sent_initial_metadata");
@ -357,6 +358,7 @@ static void on_new_call(void *arg, int success) {
GPR_ASSERT(err == GRPC_CALL_OK);
op.op = GRPC_OP_RECV_MESSAGE;
op.flags = 0;
op.data.recv_message = &pc->c2p_msg;
refpc(pc, "on_c2p_recv_msg");
err = grpc_call_start_batch(pc->c2p, &op, 1,
@ -364,6 +366,7 @@ static void on_new_call(void *arg, int success) {
GPR_ASSERT(err == GRPC_CALL_OK);
op.op = GRPC_OP_RECV_MESSAGE;
op.flags = 0;
op.data.recv_message = &pc->p2s_msg;
refpc(pc, "on_p2s_recv_msg");
err = grpc_call_start_batch(pc->p2s, &op, 1,
@ -371,6 +374,7 @@ static void on_new_call(void *arg, int success) {
GPR_ASSERT(err == GRPC_CALL_OK);
op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op.flags = 0;
op.data.recv_status_on_client.trailing_metadata =
&pc->p2s_trailing_metadata;
op.data.recv_status_on_client.status = &pc->p2s_status;
@ -383,6 +387,7 @@ static void on_new_call(void *arg, int success) {
GPR_ASSERT(err == GRPC_CALL_OK);
op.op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op.flags = 0;
op.data.recv_close_on_server.cancelled = &pc->c2p_server_cancelled;
refpc(pc, "on_c2p_closed");
err = grpc_call_start_batch(pc->c2p, &op, 1, new_closure(on_c2p_closed, pc),

@ -104,6 +104,7 @@ END2END_TESTS = {
'hpack_size': default_test_options._replace(proxyable=False,
traceable=False),
'high_initial_seqno': default_test_options,
'idempotent_request': default_test_options,
'invoke_large_request': default_test_options,
'large_metadata': default_test_options,
'max_concurrent_streams': default_test_options._replace(proxyable=False),

@ -0,0 +1,248 @@
/*
*
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/core/end2end/end2end_tests.h"
#include <stdio.h>
#include <string.h>
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "src/core/lib/support/string.h"
#include "test/core/end2end/cq_verifier.h"
enum { TIMEOUT = 200000 };
static void *tag(intptr_t t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
config.init_server(&f, server_args);
config.init_client(&f, client_args);
return f;
}
static gpr_timespec n_seconds_time(int n) {
return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
}
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
static void drain_cq(grpc_completion_queue *cq) {
grpc_event ev;
do {
ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
} while (ev.type != GRPC_QUEUE_SHUTDOWN);
}
static void shutdown_server(grpc_end2end_test_fixture *f) {
if (!f->server) return;
grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
GPR_ASSERT(grpc_completion_queue_pluck(
f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
.type == GRPC_OP_COMPLETE);
grpc_server_destroy(f->server);
f->server = NULL;
}
static void shutdown_client(grpc_end2end_test_fixture *f) {
if (!f->client) return;
grpc_channel_destroy(f->client);
f->client = NULL;
}
static void end_test(grpc_end2end_test_fixture *f) {
shutdown_server(f);
shutdown_client(f);
grpc_completion_queue_shutdown(f->cq);
drain_cq(f->cq);
grpc_completion_queue_destroy(f->cq);
}
static void simple_request_body(grpc_end2end_test_fixture f) {
grpc_call *c;
grpc_call *s;
gpr_timespec deadline = five_seconds_time();
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
char *peer;
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
"/foo", "foo.test.google.fr:1234", deadline,
NULL);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
GPR_ASSERT(peer != NULL);
gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
gpr_free(peer);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
op->reserved = NULL;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op->reserved = NULL;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op->flags = 0;
op->reserved = NULL;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
error =
grpc_server_request_call(f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101));
GPR_ASSERT(GRPC_CALL_OK == error);
cq_expect_completion(cqv, tag(101), 1);
cq_verify(cqv);
peer = grpc_call_get_peer(s);
GPR_ASSERT(peer != NULL);
gpr_log(GPR_DEBUG, "server_peer=%s", peer);
gpr_free(peer);
peer = grpc_call_get_peer(c);
GPR_ASSERT(peer != NULL);
gpr_log(GPR_DEBUG, "client_peer=%s", peer);
gpr_free(peer);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = NULL;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op->flags = 0;
op->reserved = NULL;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op->reserved = NULL;
op++;
error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
cq_expect_completion(cqv, tag(102), 1);
cq_expect_completion(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);
cq_verifier_destroy(cqv);
}
static void test_invoke_simple_request(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
f = begin_test(config, "test_invoke_simple_request", NULL, NULL);
simple_request_body(f);
end_test(&f);
config.tear_down_data(&f);
}
static void test_invoke_10_simple_requests(grpc_end2end_test_config config) {
int i;
grpc_end2end_test_fixture f =
begin_test(config, "test_invoke_10_simple_requests", NULL, NULL);
for (i = 0; i < 10; i++) {
simple_request_body(f);
gpr_log(GPR_INFO, "Passed simple request %d", i);
}
end_test(&f);
config.tear_down_data(&f);
}
void idempotent_request(grpc_end2end_test_config config) {
int i;
for (i = 0; i < 10; i++) {
test_invoke_simple_request(config);
}
test_invoke_10_simple_requests(config);
}

@ -203,6 +203,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
gpr_free(details);

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -42,11 +42,19 @@ void test_register_method_fail(void) {
grpc_server *server = grpc_server_create(NULL, NULL);
void *method;
void *method_old;
method = grpc_server_register_method(server, NULL, NULL);
method = grpc_server_register_method(server, NULL, NULL, 0);
GPR_ASSERT(method == NULL);
method_old = grpc_server_register_method(server, "m", "h");
method_old = grpc_server_register_method(server, "m", "h", 0);
GPR_ASSERT(method_old != NULL);
method = grpc_server_register_method(server, "m", "h");
method = grpc_server_register_method(server, "m", "h", 0);
GPR_ASSERT(method == NULL);
method_old = grpc_server_register_method(
server, "m2", "h2", GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST);
GPR_ASSERT(method_old != NULL);
method = grpc_server_register_method(server, "m2", "h2", 0);
GPR_ASSERT(method == NULL);
method = grpc_server_register_method(
server, "m2", "h2", GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST);
GPR_ASSERT(method == NULL);
grpc_server_destroy(server);
}

@ -69,6 +69,7 @@ CONFIG = [
(':scheme', 'grpc'),
(':authority', ''),
(':method', 'GET'),
(':method', 'PUT'),
(':path', '/'),
(':path', '/index.html'),
(':status', '204'),
@ -232,20 +233,20 @@ with open(sys.argv[0]) as my_source:
if line[0] != '#':
break
copyright.append(line)
put_banner([H,C], [line[1:].strip() for line in copyright])
put_banner([H,C], [line[2:].rstrip() for line in copyright])
put_banner([H,C],
"""WARNING: Auto-generated code.
To make changes to this file, change tools/codegen/core/gen_static_metadata.py,
and then re-run it.
To make changes to this file, change
tools/codegen/core/gen_static_metadata.py, and then re-run it.
See metadata.h for an explanation of the interface here, and metadata.c for an
explanation of what's going on.
See metadata.h for an explanation of the interface here, and metadata.c for
an explanation of what's going on.
""".splitlines())
print >>H, '#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H'
print >>H, '#define GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H'
print >>H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
print >>H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
print >>H
print >>H, '#include "src/core/lib/transport/metadata.h"'
print >>H
@ -264,13 +265,13 @@ print >>C
print >>H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
print >>H, 'extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
print >>H, 'extern gpr_uintptr grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
print >>H, 'extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
for i, elem in enumerate(all_elems):
print >>H, '/* "%s": "%s" */' % elem
print >>H, '#define %s (&grpc_static_mdelem_table[%d])' % (mangle(elem).upper(), i)
print >>H
print >>C, 'grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
print >>C, 'gpr_uintptr grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {'
print >>C, 'uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {'
print >>C, ' %s' % ','.join('%d' % static_userdata.get(elem, 0) for elem in all_elems)
print >>C, '};'
print >>C
@ -285,8 +286,8 @@ def md_idx(m):
if m == m2:
return i
print >>H, 'extern const gpr_uint8 grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2];'
print >>C, 'const gpr_uint8 grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2] = {'
print >>H, 'extern const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2];'
print >>C, 'const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2] = {'
print >>C, ','.join('%d' % str_idx(x) for x in itertools.chain.from_iterable([a,b] for a, b in all_elems))
print >>C, '};'
print >>C
@ -297,15 +298,15 @@ print >>C, '%s' % ',\n'.join(' "%s"' % s for s in all_strs)
print >>C, '};'
print >>C
print >>H, 'extern const gpr_uint8 grpc_static_accept_encoding_metadata[%d];' % (1 << len(COMPRESSION_ALGORITHMS))
print >>C, 'const gpr_uint8 grpc_static_accept_encoding_metadata[%d] = {' % (1 << len(COMPRESSION_ALGORITHMS))
print >>H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (1 << len(COMPRESSION_ALGORITHMS))
print >>C, 'const uint8_t grpc_static_accept_encoding_metadata[%d] = {' % (1 << len(COMPRESSION_ALGORITHMS))
print >>C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems)
print >>C, '};'
print >>C
print >>H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]])'
print >>H, '#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H */'
print >>H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */'
H.close()
C.close()

@ -6627,6 +6627,7 @@
"test/core/end2end/tests/graceful_server_shutdown.c",
"test/core/end2end/tests/high_initial_seqno.c",
"test/core/end2end/tests/hpack_size.c",
"test/core/end2end/tests/idempotent_request.c",
"test/core/end2end/tests/invoke_large_request.c",
"test/core/end2end/tests/large_metadata.c",
"test/core/end2end/tests/max_concurrent_streams.c",
@ -6683,6 +6684,7 @@
"test/core/end2end/tests/graceful_server_shutdown.c",
"test/core/end2end/tests/high_initial_seqno.c",
"test/core/end2end/tests/hpack_size.c",
"test/core/end2end/tests/idempotent_request.c",
"test/core/end2end/tests/invoke_large_request.c",
"test/core/end2end/tests/large_metadata.c",
"test/core/end2end/tests/max_concurrent_streams.c",

@ -4649,6 +4649,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_census_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -5441,6 +5463,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_compress_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -6216,6 +6260,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_fakesec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -6989,6 +7054,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -7679,6 +7766,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+pipe_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -8255,6 +8358,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+poll_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -8831,6 +8950,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+poll+pipe_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -9487,6 +9622,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+trace_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -10262,6 +10419,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_oauth2_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -10955,6 +11133,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_proxy_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -11585,6 +11784,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -12215,6 +12435,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair+trace_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -12866,6 +13107,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair_1byte_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -13599,7 +13861,7 @@
},
{
"args": [
"invoke_large_request"
"idempotent_request"
],
"ci_platforms": [
"windows",
@ -13621,7 +13883,7 @@
},
{
"args": [
"large_metadata"
"invoke_large_request"
],
"ci_platforms": [
"windows",
@ -13643,7 +13905,7 @@
},
{
"args": [
"max_concurrent_streams"
"large_metadata"
],
"ci_platforms": [
"windows",
@ -13665,7 +13927,29 @@
},
{
"args": [
"max_message_length"
"max_concurrent_streams"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_ssl_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"max_message_length"
],
"ci_platforms": [
"windows",
@ -14287,6 +14571,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_ssl+poll_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -14885,6 +15185,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_ssl_proxy_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -15541,6 +15862,26 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_uds_test",
"platforms": [
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -16177,6 +16518,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_uds+poll_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -16833,6 +17190,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_census_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -17603,6 +17982,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_compress_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -18373,6 +18774,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -19047,6 +19470,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+pipe_nosec_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -19607,6 +20046,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+poll_nosec_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -20167,6 +20622,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+poll+pipe_nosec_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"
@ -20801,6 +21272,28 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_full+trace_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -21492,6 +21985,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_proxy_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -22101,6 +22615,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -22710,6 +23245,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair+trace_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -23340,6 +23896,27 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"windows",
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_sockpair_1byte_nosec_test",
"platforms": [
"windows",
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -23997,6 +24574,26 @@
"posix"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_uds_nosec_test",
"platforms": [
"linux",
"mac",
"posix"
]
},
{
"args": [
"invoke_large_request"
@ -24617,6 +25214,22 @@
"linux"
]
},
{
"args": [
"idempotent_request"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "h2_uds+poll_nosec_test",
"platforms": [
"linux"
]
},
{
"args": [
"invoke_large_request"

@ -185,6 +185,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\hpack_size.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\idempotent_request.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\invoke_large_request.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\large_metadata.c">

@ -52,6 +52,9 @@
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\hpack_size.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\idempotent_request.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\invoke_large_request.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>

@ -187,6 +187,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\hpack_size.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\idempotent_request.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\invoke_large_request.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\large_metadata.c">

@ -55,6 +55,9 @@
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\hpack_size.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\idempotent_request.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\invoke_large_request.c">
<Filter>test\core\end2end\tests</Filter>
</ClCompile>

Loading…
Cancel
Save