mirror of https://github.com/grpc/grpc.git
commit
344834b40b
140 changed files with 3967 additions and 464 deletions
@ -1,56 +1 @@ |
||||
gRPC in 3 minutes (Python) |
||||
======================== |
||||
|
||||
Background |
||||
------------- |
||||
For this sample, we've already generated the server and client stubs from |
||||
[helloworld.proto][] and we'll be using a specific reference platform. |
||||
|
||||
|
||||
Install gRPC: |
||||
```sh |
||||
$ pip install grpcio |
||||
``` |
||||
Or, to install it system wide: |
||||
```sh |
||||
$ sudo pip install grpcio |
||||
``` |
||||
|
||||
If you're on Windows, make sure you installed the `pip.exe` component when you |
||||
installed Python. Invoke as above but with `pip.exe` instead of `pip` (you may |
||||
also need to invoke from a `cmd.exe` ran as administrator): |
||||
```sh |
||||
$ pip.exe install grpcio |
||||
``` |
||||
|
||||
Download the example |
||||
```sh |
||||
$ # Clone the repository to get the example code: |
||||
$ git clone https://github.com/grpc/grpc |
||||
$ # Navigate to the "hello, world" Python example: |
||||
$ cd grpc/examples/python/helloworld |
||||
``` |
||||
|
||||
Try it! |
||||
------- |
||||
|
||||
- Run the server |
||||
|
||||
```sh |
||||
$ python2.7 greeter_server.py & |
||||
``` |
||||
|
||||
- Run the client |
||||
|
||||
```sh |
||||
$ python2.7 greeter_client.py |
||||
``` |
||||
|
||||
Tutorial |
||||
-------- |
||||
|
||||
You can find a more detailed tutorial in [gRPC Basics: Python][] |
||||
|
||||
[helloworld.proto]:../protos/helloworld.proto |
||||
[Install gRPC Python]:../../src/python#installation |
||||
[gRPC Basics: Python]:http://www.grpc.io/docs/tutorials/basic/python.html |
||||
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) |
||||
|
@ -1 +1 @@ |
||||
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs) |
||||
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) |
||||
|
@ -1 +1,3 @@ |
||||
An example showing two stubs sharing a channel and two servicers sharing a server. |
||||
|
||||
More complete documentation lives at [grpc.io](http://www.grpc.io/docs/tutorials/basic/python.html). |
||||
|
@ -0,0 +1,180 @@ |
||||
/*
|
||||
* |
||||
* Copyright 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 "src/core/lib/support/percent_encoding.h" |
||||
|
||||
#include <grpc/support/log.h> |
||||
|
||||
const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8] = { |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff, |
||||
0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
||||
const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8] = { |
||||
0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
||||
|
||||
static bool is_unreserved_character(uint8_t c, |
||||
const uint8_t *unreserved_bytes) { |
||||
return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0; |
||||
} |
||||
|
||||
gpr_slice gpr_percent_encode_slice(gpr_slice slice, |
||||
const uint8_t *unreserved_bytes) { |
||||
static const uint8_t hex[] = "0123456789ABCDEF"; |
||||
|
||||
// first pass: count the number of bytes needed to output this string
|
||||
size_t output_length = 0; |
||||
const uint8_t *slice_start = GPR_SLICE_START_PTR(slice); |
||||
const uint8_t *slice_end = GPR_SLICE_END_PTR(slice); |
||||
const uint8_t *p; |
||||
bool any_reserved_bytes = false; |
||||
for (p = slice_start; p < slice_end; p++) { |
||||
bool unres = is_unreserved_character(*p, unreserved_bytes); |
||||
output_length += unres ? 1 : 3; |
||||
any_reserved_bytes |= !unres; |
||||
} |
||||
// no unreserved bytes: return the string unmodified
|
||||
if (!any_reserved_bytes) { |
||||
return gpr_slice_ref(slice); |
||||
} |
||||
// second pass: actually encode
|
||||
gpr_slice out = gpr_slice_malloc(output_length); |
||||
uint8_t *q = GPR_SLICE_START_PTR(out); |
||||
for (p = slice_start; p < slice_end; p++) { |
||||
if (is_unreserved_character(*p, unreserved_bytes)) { |
||||
*q++ = *p; |
||||
} else { |
||||
*q++ = '%'; |
||||
*q++ = hex[*p >> 4]; |
||||
*q++ = hex[*p & 15]; |
||||
} |
||||
} |
||||
GPR_ASSERT(q == GPR_SLICE_END_PTR(out)); |
||||
return out; |
||||
} |
||||
|
||||
static bool valid_hex(const uint8_t *p, const uint8_t *end) { |
||||
if (p >= end) return false; |
||||
return (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || |
||||
(*p >= 'A' && *p <= 'F'); |
||||
} |
||||
|
||||
static uint8_t dehex(uint8_t c) { |
||||
if (c >= '0' && c <= '9') return (uint8_t)(c - '0'); |
||||
if (c >= 'A' && c <= 'F') return (uint8_t)(c - 'A' + 10); |
||||
if (c >= 'a' && c <= 'f') return (uint8_t)(c - 'a' + 10); |
||||
GPR_UNREACHABLE_CODE(return 255); |
||||
} |
||||
|
||||
bool gpr_strict_percent_decode_slice(gpr_slice slice_in, |
||||
const uint8_t *unreserved_bytes, |
||||
gpr_slice *slice_out) { |
||||
const uint8_t *p = GPR_SLICE_START_PTR(slice_in); |
||||
const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in); |
||||
size_t out_length = 0; |
||||
bool any_percent_encoded_stuff = false; |
||||
while (p != in_end) { |
||||
if (*p == '%') { |
||||
if (!valid_hex(++p, in_end)) return false; |
||||
if (!valid_hex(++p, in_end)) return false; |
||||
p++; |
||||
out_length++; |
||||
any_percent_encoded_stuff = true; |
||||
} else if (is_unreserved_character(*p, unreserved_bytes)) { |
||||
p++; |
||||
out_length++; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
if (!any_percent_encoded_stuff) { |
||||
*slice_out = gpr_slice_ref(slice_in); |
||||
return true; |
||||
} |
||||
p = GPR_SLICE_START_PTR(slice_in); |
||||
*slice_out = gpr_slice_malloc(out_length); |
||||
uint8_t *q = GPR_SLICE_START_PTR(*slice_out); |
||||
while (p != in_end) { |
||||
if (*p == '%') { |
||||
*q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2])); |
||||
p += 3; |
||||
} else { |
||||
*q++ = *p++; |
||||
} |
||||
} |
||||
GPR_ASSERT(q == GPR_SLICE_END_PTR(*slice_out)); |
||||
return true; |
||||
} |
||||
|
||||
gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in) { |
||||
const uint8_t *p = GPR_SLICE_START_PTR(slice_in); |
||||
const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in); |
||||
size_t out_length = 0; |
||||
bool any_percent_encoded_stuff = false; |
||||
while (p != in_end) { |
||||
if (*p == '%') { |
||||
if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) { |
||||
p++; |
||||
out_length++; |
||||
} else { |
||||
p += 3; |
||||
out_length++; |
||||
any_percent_encoded_stuff = true; |
||||
} |
||||
} else { |
||||
p++; |
||||
out_length++; |
||||
} |
||||
} |
||||
if (!any_percent_encoded_stuff) { |
||||
return gpr_slice_ref(slice_in); |
||||
} |
||||
p = GPR_SLICE_START_PTR(slice_in); |
||||
gpr_slice out = gpr_slice_malloc(out_length); |
||||
uint8_t *q = GPR_SLICE_START_PTR(out); |
||||
while (p != in_end) { |
||||
if (*p == '%') { |
||||
if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) { |
||||
*q++ = *p++; |
||||
} else { |
||||
*q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2])); |
||||
p += 3; |
||||
} |
||||
} else { |
||||
*q++ = *p++; |
||||
} |
||||
} |
||||
GPR_ASSERT(q == GPR_SLICE_END_PTR(out)); |
||||
return out; |
||||
} |
@ -0,0 +1,78 @@ |
||||
/*
|
||||
* |
||||
* Copyright 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H |
||||
#define GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H |
||||
|
||||
/* Percent encoding and decoding of slices.
|
||||
Transforms arbitrary strings into safe-for-transmission strings by using |
||||
variants of percent encoding (RFC 3986). |
||||
Two major variants are supplied: one that strictly matches URL encoding, |
||||
and another which applies percent encoding only to non-http2 header |
||||
bytes (the 'compatible' variant) */ |
||||
|
||||
#include <stdbool.h> |
||||
|
||||
#include <grpc/support/slice.h> |
||||
|
||||
/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
|
||||
gpr_percent_encode_slice, gpr_strict_percent_decode_slice). |
||||
Flags [A-Za-z0-9-_.~] as unreserved bytes for the percent encoding routines |
||||
*/ |
||||
extern const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8]; |
||||
/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
|
||||
gpr_percent_encode_slice, gpr_strict_percent_decode_slice). |
||||
Flags ascii7 non-control characters excluding '%' as unreserved bytes for the |
||||
percent encoding routines */ |
||||
extern const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8]; |
||||
|
||||
/* Percent-encode a slice, returning the new slice (this cannot fail):
|
||||
unreserved_bytes is a bitfield indicating which bytes are considered |
||||
unreserved and thus do not need percent encoding */ |
||||
gpr_slice gpr_percent_encode_slice(gpr_slice slice, |
||||
const uint8_t *unreserved_bytes); |
||||
/* Percent-decode a slice, strictly.
|
||||
If the input is legal (contains no unreserved bytes, and legal % encodings), |
||||
returns true and sets *slice_out to the decoded slice. |
||||
If the input is not legal, returns false and leaves *slice_out untouched. |
||||
unreserved_bytes is a bitfield indicating which bytes are considered |
||||
unreserved and thus do not need percent encoding */ |
||||
bool gpr_strict_percent_decode_slice(gpr_slice slice_in, |
||||
const uint8_t *unreserved_bytes, |
||||
gpr_slice *slice_out); |
||||
/* Percent-decode a slice, permissively.
|
||||
If a % triplet can not be decoded, pass it through verbatim. |
||||
This cannot fail. */ |
||||
gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in); |
||||
|
||||
#endif /* GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H */ |
@ -1,138 +0,0 @@ |
||||
# Copyright 2015, 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. |
||||
|
||||
require 'grpc' |
||||
|
||||
describe GRPC::Pool do |
||||
Pool = GRPC::Pool |
||||
|
||||
describe '#new' do |
||||
it 'raises if a non-positive size is used' do |
||||
expect { Pool.new(0) }.to raise_error |
||||
expect { Pool.new(-1) }.to raise_error |
||||
expect { Pool.new(Object.new) }.to raise_error |
||||
end |
||||
|
||||
it 'is constructed OK with a positive size' do |
||||
expect { Pool.new(1) }.not_to raise_error |
||||
end |
||||
end |
||||
|
||||
describe '#jobs_waiting' do |
||||
it 'at start, it is zero' do |
||||
p = Pool.new(1) |
||||
expect(p.jobs_waiting).to be(0) |
||||
end |
||||
|
||||
it 'it increases, with each scheduled job if the pool is not running' do |
||||
p = Pool.new(1) |
||||
job = proc {} |
||||
expect(p.jobs_waiting).to be(0) |
||||
5.times do |i| |
||||
p.schedule(&job) |
||||
expect(p.jobs_waiting).to be(i + 1) |
||||
end |
||||
end |
||||
|
||||
it 'it decreases as jobs are run' do |
||||
p = Pool.new(1) |
||||
job = proc {} |
||||
expect(p.jobs_waiting).to be(0) |
||||
3.times do |
||||
p.schedule(&job) |
||||
end |
||||
p.start |
||||
sleep 2 |
||||
expect(p.jobs_waiting).to be(0) |
||||
end |
||||
end |
||||
|
||||
describe '#schedule' do |
||||
it 'return if the pool is already stopped' do |
||||
p = Pool.new(1) |
||||
p.stop |
||||
job = proc {} |
||||
expect { p.schedule(&job) }.to_not raise_error |
||||
end |
||||
|
||||
it 'adds jobs that get run by the pool' do |
||||
p = Pool.new(1) |
||||
p.start |
||||
o, q = Object.new, Queue.new |
||||
job = proc { q.push(o) } |
||||
p.schedule(&job) |
||||
expect(q.pop).to be(o) |
||||
p.stop |
||||
end |
||||
end |
||||
|
||||
describe '#stop' do |
||||
it 'works when there are no scheduled tasks' do |
||||
p = Pool.new(1) |
||||
expect { p.stop }.not_to raise_error |
||||
end |
||||
|
||||
it 'stops jobs when there are long running jobs' do |
||||
p = Pool.new(1) |
||||
p.start |
||||
o, q = Object.new, Queue.new |
||||
job = proc do |
||||
sleep(5) # long running |
||||
q.push(o) |
||||
end |
||||
p.schedule(&job) |
||||
sleep(1) # should ensure the long job gets scheduled |
||||
expect { p.stop }.not_to raise_error |
||||
end |
||||
end |
||||
|
||||
describe '#start' do |
||||
it 'runs pre-scheduled jobs' do |
||||
p = Pool.new(2) |
||||
o, q = Object.new, Queue.new |
||||
n = 5 # arbitrary |
||||
n.times { p.schedule(o, &q.method(:push)) } |
||||
p.start |
||||
n.times { expect(q.pop).to be(o) } |
||||
p.stop |
||||
end |
||||
|
||||
it 'runs jobs as they are scheduled ' do |
||||
p = Pool.new(2) |
||||
o, q = Object.new, Queue.new |
||||
p.start |
||||
n = 5 # arbitrary |
||||
n.times do |
||||
p.schedule(o, &q.method(:push)) |
||||
expect(q.pop).to be(o) |
||||
end |
||||
p.stop |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,276 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, 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/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/time.h> |
||||
#include <grpc/support/useful.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); |
||||
} |
||||
|
||||
/* Request/response with metadata and payload.*/ |
||||
static void test_cacheable_request_response_with_metadata_and_payload( |
||||
grpc_end2end_test_config config) { |
||||
grpc_call *c; |
||||
grpc_call *s; |
||||
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||
grpc_byte_buffer *request_payload = |
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1); |
||||
grpc_byte_buffer *response_payload = |
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1); |
||||
gpr_timespec deadline = five_seconds_time(); |
||||
grpc_metadata meta_c[2] = { |
||||
{"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}}, |
||||
{"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}}; |
||||
grpc_metadata meta_s[2] = { |
||||
{"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}}, |
||||
{"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}}; |
||||
grpc_end2end_test_fixture f = begin_test( |
||||
config, "test_cacheable_request_response_with_metadata_and_payload", NULL, |
||||
NULL); |
||||
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_byte_buffer *request_payload_recv = NULL; |
||||
grpc_byte_buffer *response_payload_recv = NULL; |
||||
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; |
||||
|
||||
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, |
||||
"/foo", "foo.test.google.fr", deadline, NULL); |
||||
GPR_ASSERT(c); |
||||
|
||||
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); |
||||
|
||||
memset(ops, 0, sizeof(ops)); |
||||
op = ops; |
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op->data.send_initial_metadata.count = 2; |
||||
op->data.send_initial_metadata.metadata = meta_c; |
||||
op->flags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; |
||||
op->reserved = NULL; |
||||
op++; |
||||
op->op = GRPC_OP_SEND_MESSAGE; |
||||
op->data.send_message = request_payload; |
||||
op->flags = 0; |
||||
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_MESSAGE; |
||||
op->data.recv_message = &response_payload_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); |
||||
|
||||
memset(ops, 0, sizeof(ops)); |
||||
op = ops; |
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op->data.send_initial_metadata.count = 2; |
||||
op->data.send_initial_metadata.metadata = meta_s; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
op->op = GRPC_OP_RECV_MESSAGE; |
||||
op->data.recv_message = &request_payload_recv; |
||||
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_verify(cqv); |
||||
|
||||
memset(ops, 0, sizeof(ops)); |
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
||||
op->data.recv_close_on_server.cancelled = &was_cancelled; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
op->op = GRPC_OP_SEND_MESSAGE; |
||||
op->data.send_message = response_payload; |
||||
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_OK; |
||||
op->data.send_status_from_server.status_details = "xyz"; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); |
||||
GPR_ASSERT(GRPC_CALL_OK == error); |
||||
|
||||
CQ_EXPECT_COMPLETION(cqv, tag(103), 1); |
||||
CQ_EXPECT_COMPLETION(cqv, tag(1), 1); |
||||
cq_verify(cqv); |
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_OK); |
||||
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")); |
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { |
||||
// Our simple proxy does not support cacheable requests
|
||||
} else { |
||||
GPR_ASSERT(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST & call_details.flags); |
||||
} |
||||
GPR_ASSERT(was_cancelled == 0); |
||||
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); |
||||
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); |
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1")); |
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv, "key2", "val2")); |
||||
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3")); |
||||
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4")); |
||||
|
||||
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); |
||||
|
||||
grpc_byte_buffer_destroy(request_payload); |
||||
grpc_byte_buffer_destroy(response_payload); |
||||
grpc_byte_buffer_destroy(request_payload_recv); |
||||
grpc_byte_buffer_destroy(response_payload_recv); |
||||
|
||||
end_test(&f); |
||||
config.tear_down_data(&f); |
||||
} |
||||
|
||||
void simple_cacheable_request(grpc_end2end_test_config config) { |
||||
test_cacheable_request_response_with_metadata_and_payload(config); |
||||
} |
||||
|
||||
void simple_cacheable_request_pre_init(void) {} |
@ -0,0 +1 @@ |
||||
:Ę%cE'yzŠ |
@ -0,0 +1 @@ |
||||
x;x_%C88 |
@ -0,0 +1 @@ |
||||
))'x;x_%C88xy(Pyz) |
@ -0,0 +1 @@ |
||||
_x;x)x;x_x;x_%88%8888: |
@ -0,0 +1 @@ |
||||
x8 |
@ -0,0 +1 @@ |
||||
x);x(_%88x;x_%88 |
@ -0,0 +1 @@ |
||||
)x;x_x;x_%88%88: |
@ -0,0 +1 @@ |
||||
x;:Ę%)x_%C8cE'yzŠ8 |
@ -0,0 +1 @@ |
||||
x;x_%88 |
@ -0,0 +1 @@ |
||||
)))'x;x_%C88)'x;x_%C89xyyzxyyz) |
@ -0,0 +1 @@ |
||||
))'x;x_%C88xyyz) |
@ -0,0 +1 @@ |
||||
x%8 |
@ -0,0 +1 @@ |
||||
x);x(_%88x;x_xxyyz |
@ -0,0 +1,2 @@ |
||||
)'xyyz!úyzŠ[zxĘ%ccyzyzy'z*zŠ |
||||
Š |
@ -0,0 +1,2 @@ |
||||
)'xyyz)úyzŠ[zxĘ%cCyzyzy'z*zŠ |
||||
Š |
@ -0,0 +1 @@ |
||||
ハ:%Dx;:ハ%)x_%C8cc |
@ -0,0 +1 @@ |
||||
) |
@ -0,0 +1 @@ |
||||
xyz |
@ -0,0 +1,66 @@ |
||||
/*
|
||||
* |
||||
* Copyright 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 <stdbool.h> |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/support/percent_encoding.h" |
||||
#include "test/core/util/memory_counters.h" |
||||
|
||||
bool squelch = true; |
||||
bool leak_check = true; |
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
||||
struct grpc_memory_counters counters; |
||||
grpc_memory_counters_init(); |
||||
gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); |
||||
gpr_slice output; |
||||
if (gpr_strict_percent_decode_slice( |
||||
input, gpr_url_percent_encoding_unreserved_bytes, &output)) { |
||||
gpr_slice_unref(output); |
||||
} |
||||
if (gpr_strict_percent_decode_slice( |
||||
input, gpr_compatible_percent_encoding_unreserved_bytes, &output)) { |
||||
gpr_slice_unref(output); |
||||
} |
||||
gpr_slice_unref(gpr_permissive_percent_decode_slice(input)); |
||||
gpr_slice_unref(input); |
||||
counters = grpc_memory_counters_snapshot(); |
||||
grpc_memory_counters_destroy(); |
||||
GPR_ASSERT(counters.total_size_relative == 0); |
||||
return 0; |
||||
} |
@ -0,0 +1,3 @@ |
||||
_x;7y |
||||
xyz')S)xy-zý |
||||
Æ* |
@ -0,0 +1 @@ |
||||
xyx |
@ -0,0 +1 @@ |
||||
.yx.yxxxyzxyyzxy |
@ -0,0 +1 @@ |
||||
xyrxyxyzxxyzxyzxyxyy |
@ -0,0 +1,3 @@ |
||||
xy |
||||
xyz |
||||
)S-掐 |
@ -0,0 +1,3 @@ |
||||
xy |
||||
xyz |
||||
)S)ニ* |
@ -0,0 +1,4 @@ |
||||
x;7y |
||||
xyz |
||||
)S)xyz |
||||
Æ* |
@ -0,0 +1 @@ |
||||
xyzxy |
@ -0,0 +1,3 @@ |
||||
_x;7y |
||||
xyz')S)xyz |
||||
Æ* |
@ -0,0 +1,2 @@ |
||||
xyz |
||||
)S |
@ -0,0 +1 @@ |
||||
.yx |
@ -0,0 +1,4 @@ |
||||
x;y |
||||
xyz |
||||
)S)xyz |
||||
Æ* |
@ -0,0 +1,5 @@ |
||||
x;y |
||||
xøyz |
||||
)S)xyz |
||||
Æ.y~ |
||||
)S |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue