aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar yang-g <yangg@google.com>2016-01-15 14:08:58 -0800
committerGravatar yang-g <yangg@google.com>2016-01-15 14:08:58 -0800
commit5d7b6a21dfe6edc2328022c5804ebd5ffdc4fe9f (patch)
tree14510a2bc1dc2fe506170e940e7969bf2208675e /src
parentdf2778d45f57f0647448e566b5bb7e3643b51ebb (diff)
parent623ca7dd9408fea1b6e88be0ca1e0f845a0533e8 (diff)
Merge remote-tracking branch 'upstream/master' into epollset
Diffstat (limited to 'src')
-rw-r--r--src/core/census/initialize.c7
-rw-r--r--src/core/surface/call.c13
-rw-r--r--src/core/surface/validate_metadata.c73
-rw-r--r--src/core/transport/chttp2/bin_encoder.c7
-rw-r--r--src/core/transport/chttp2/bin_encoder.h4
-rw-r--r--src/core/transport/chttp2/hpack_encoder.c7
-rw-r--r--src/core/transport/chttp2/hpack_parser.c7
-rw-r--r--src/core/transport/metadata.c36
-rw-r--r--src/core/transport/metadata.h4
-rw-r--r--src/cpp/util/byte_buffer.cc3
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj18
-rw-r--r--src/csharp/Grpc.Core/packages.config2
-rw-r--r--src/csharp/buildall.bat3
-rw-r--r--src/node/ext/call.cc10
-rw-r--r--src/node/ext/call_credentials.cc2
-rw-r--r--src/node/ext/node_grpc.cc50
-rw-r--r--src/node/ext/timeval.cc2
-rw-r--r--src/node/interop/async_delay_queue.js6
-rw-r--r--src/node/jsdoc_conf.json6
-rw-r--r--src/node/src/common.js4
-rw-r--r--src/node/src/metadata.js20
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.h6
-rw-r--r--src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj21
-rwxr-xr-xsrc/proto/gen_build_yaml.py33
-rw-r--r--src/proto/grpc/testing/duplicate/echo_duplicate.proto4
-rw-r--r--src/proto/grpc/testing/echo.proto4
-rw-r--r--src/python/grpcio/commands.py50
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py1
-rwxr-xr-xsrc/ruby/.rspec6
-rwxr-xr-xsrc/ruby/Gemfile4
-rwxr-xr-xsrc/ruby/Rakefile58
-rw-r--r--src/ruby/ext/grpc/extconf.rb68
-rw-r--r--src/ruby/ext/grpc/rb_call.c58
-rw-r--r--src/ruby/ext/grpc/rb_call_credentials.c27
-rw-r--r--src/ruby/ext/grpc/rb_channel.c18
-rw-r--r--src/ruby/ext/grpc/rb_event_thread.c153
-rw-r--r--src/ruby/ext/grpc/rb_event_thread.h37
-rwxr-xr-xsrc/ruby/grpc.gemspec45
-rw-r--r--src/ruby/lib/grpc.rb7
-rw-r--r--src/ruby/lib/grpc/generic/client_stub.rb18
-rw-r--r--src/ruby/lib/grpc/generic/service.rb6
-rw-r--r--src/ruby/lib/grpc/version.rb4
-rwxr-xr-xsrc/ruby/pb/test/client.rb27
-rw-r--r--src/ruby/spec/call_spec.rb2
-rw-r--r--src/ruby/spec/channel_spec.rb21
-rw-r--r--src/ruby/spec/client_server_spec.rb2
-rw-r--r--src/ruby/spec/generic/active_call_spec.rb3
-rw-r--r--src/ruby/spec/generic/client_stub_spec.rb51
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb23
-rw-r--r--src/ruby/spec/generic/service_spec.rb9
-rw-r--r--src/ruby/spec/pb/health/checker_spec.rb17
51 files changed, 670 insertions, 397 deletions
diff --git a/src/core/census/initialize.c b/src/core/census/initialize.c
index 8d60f790eb..989708d42c 100644
--- a/src/core/census/initialize.c
+++ b/src/core/census/initialize.c
@@ -39,12 +39,11 @@ int census_initialize(int features) {
if (features_enabled != CENSUS_FEATURE_NONE) {
return 1;
}
- if (features != CENSUS_FEATURE_NONE) {
+ if (features == CENSUS_FEATURE_NONE) {
return 1;
- } else {
- features_enabled = features;
- return 0;
}
+ features_enabled = features;
+ return 0;
}
void census_shutdown(void) { features_enabled = CENSUS_FEATURE_NONE; }
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index b1ba2afa8b..880666bb38 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -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
@@ -37,6 +37,7 @@
#include <string.h>
#include <grpc/compression.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -562,12 +563,16 @@ static int prepare_application_metadata(grpc_call *call, int count,
GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
l->md = grpc_mdelem_from_string_and_buffer(
md->key, (const uint8_t *)md->value, md->value_length);
- if (!grpc_mdstr_is_legal_header(l->md->key)) {
+ if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
+ GRPC_MDSTR_LENGTH(l->md->key))) {
gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
grpc_mdstr_as_c_string(l->md->key));
return 0;
- } else if (!grpc_mdstr_is_bin_suffixed(l->md->key) &&
- !grpc_mdstr_is_legal_nonbin_header(l->md->value)) {
+ } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key),
+ GRPC_MDSTR_LENGTH(l->md->key)) &&
+ !grpc_header_nonbin_value_is_legal(
+ grpc_mdstr_as_c_string(l->md->value),
+ GRPC_MDSTR_LENGTH(l->md->value))) {
gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
return 0;
}
diff --git a/src/core/surface/validate_metadata.c b/src/core/surface/validate_metadata.c
new file mode 100644
index 0000000000..df2e80b4b7
--- /dev/null
+++ b/src/core/surface/validate_metadata.c
@@ -0,0 +1,73 @@
+/*
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <grpc/support/port_platform.h>
+
+static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) {
+ const char *p = s;
+ const char *e = s + len;
+ for (; p != e; p++) {
+ int idx = *p;
+ int byte = idx / 8;
+ int bit = idx % 8;
+ if ((legal_bits[byte] & (1 << bit)) == 0) return 0;
+ }
+ return 1;
+}
+
+int grpc_header_key_is_legal(const char *key, size_t length) {
+ static const uint8_t legal_header_bits[256 / 8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00,
+ 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ if (length == 0) {
+ return 0;
+ }
+ return conforms_to(key, length, legal_header_bits);
+}
+
+int grpc_header_nonbin_value_is_legal(const char *value, size_t length) {
+ static const uint8_t legal_header_bits[256 / 8] = {
+ 0x00, 0x00, 0x00, 0x00, 0xff, 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};
+ return conforms_to(value, length, legal_header_bits);
+}
+
+int grpc_is_binary_header(const char *key, size_t length) {
+ if (length < 5) return 0;
+ return 0 == memcmp(key + length - 4, "-bin", 4);
+}
diff --git a/src/core/transport/chttp2/bin_encoder.c b/src/core/transport/chttp2/bin_encoder.c
index a6a8e3e035..f26bc7e29b 100644
--- a/src/core/transport/chttp2/bin_encoder.c
+++ b/src/core/transport/chttp2/bin_encoder.c
@@ -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
@@ -283,8 +283,3 @@ gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input) {
GPR_ASSERT(in == GPR_SLICE_END_PTR(input));
return output;
}
-
-int grpc_is_binary_header(const char *key, size_t length) {
- if (length < 5) return 0;
- return 0 == memcmp(key + length - 4, "-bin", 4);
-}
diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h
index d3e5a855dd..036fddf998 100644
--- a/src/core/transport/chttp2/bin_encoder.h
+++ b/src/core/transport/chttp2/bin_encoder.h
@@ -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
@@ -51,6 +51,4 @@ gpr_slice grpc_chttp2_huffman_compress(gpr_slice input);
return y; */
gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input);
-int grpc_is_binary_header(const char *key, size_t length);
-
#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */
diff --git a/src/core/transport/chttp2/hpack_encoder.c b/src/core/transport/chttp2/hpack_encoder.c
index d6a352afd5..89a80d896c 100644
--- a/src/core/transport/chttp2/hpack_encoder.c
+++ b/src/core/transport/chttp2/hpack_encoder.c
@@ -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
@@ -36,6 +36,11 @@
#include <assert.h>
#include <string.h>
+/* This is here for grpc_is_binary_header
+ * TODO(murgatroid99): Remove this
+ */
+#include <grpc/grpc.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index 16395d6be1..a63c7db1f6 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -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
@@ -38,6 +38,11 @@
#include <string.h>
#include <assert.h>
+/* This is here for grpc_is_binary_header
+ * TODO(murgatroid99): Remove this
+ */
+#include <grpc/grpc.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index ada889983c..14912af7df 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -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
@@ -688,37 +688,3 @@ gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {
gpr_mu_unlock(&shard->mu);
return slice;
}
-
-static int conforms_to(grpc_mdstr *s, const uint8_t *legal_bits) {
- const uint8_t *p = GPR_SLICE_START_PTR(s->slice);
- const uint8_t *e = GPR_SLICE_END_PTR(s->slice);
- for (; p != e; p++) {
- int idx = *p;
- int byte = idx / 8;
- int bit = idx % 8;
- if ((legal_bits[byte] & (1 << bit)) == 0) return 0;
- }
- return 1;
-}
-
-int grpc_mdstr_is_legal_header(grpc_mdstr *s) {
- static const uint8_t legal_header_bits[256 / 8] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
- 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- return conforms_to(s, legal_header_bits);
-}
-
-int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) {
- static const uint8_t legal_header_bits[256 / 8] = {
- 0x00, 0x00, 0x00, 0x00, 0xff, 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};
- return conforms_to(s, legal_header_bits);
-}
-
-int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) {
- /* TODO(ctiller): consider caching this */
- return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice),
- GPR_SLICE_LENGTH(s->slice));
-}
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index a7c9fd6e84..8742846be7 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -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
@@ -142,6 +142,8 @@ void grpc_mdelem_unref(grpc_mdelem *md);
Does not promise that the returned string has no embedded nulls however. */
const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
+#define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice))
+
int grpc_mdstr_is_legal_header(grpc_mdstr *s);
int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s);
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index df873eb1ce..2952f94b24 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -69,6 +69,7 @@ void ByteBuffer::Dump(std::vector<Slice>* slices) const {
while (grpc_byte_buffer_reader_next(&reader, &s)) {
slices->push_back(Slice(s, Slice::STEAL_REF));
}
+ grpc_byte_buffer_reader_destroy(&reader);
}
size_t ByteBuffer::Length() const {
@@ -88,4 +89,4 @@ ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) {
return *this;
}
-} // namespace grpc \ No newline at end of file
+} // namespace grpc
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 5b3da7c6c9..852b212114 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -8,7 +8,7 @@
<RootNamespace>Grpc.Core</RootNamespace>
<AssemblyName>Grpc.Core</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <NuGetPackageImportStamp>be3e9d03</NuGetPackageImportStamp>
+ <NuGetPackageImportStamp>c0512805</NuGetPackageImportStamp>
<DocumentationFile>bin\$(Configuration)\Grpc.Core.Xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -19,6 +19,7 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <NativeDependenciesConfiguration>Debug</NativeDependenciesConfiguration>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -26,6 +27,7 @@
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -36,6 +38,7 @@
<WarningLevel>4</WarningLevel>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ <NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -133,7 +136,7 @@
ignored, which gives us the desired effect. -->
<When Condition=" '$(OS)' != 'Unix' ">
<ItemGroup>
- <Content Include="..\..\..\vsprojects\Debug\grpc_csharp_ext.dll">
+ <Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
@@ -142,15 +145,6 @@
</Choose>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
- <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
- </Target>
- <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
- <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
<ItemGroup />
<ItemGroup />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config
index 89600744a7..86a48c512e 100644
--- a/src/csharp/Grpc.Core/packages.config
+++ b/src/csharp/Grpc.Core/packages.config
@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
- <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
<package id="Ix-Async" version="1.2.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/csharp/buildall.bat b/src/csharp/buildall.bat
index d85896c255..08d4bdb335 100644
--- a/src/csharp/buildall.bat
+++ b/src/csharp/buildall.bat
@@ -9,7 +9,8 @@ cd /d %~dp0
@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
@rem Build the C# native extension
-msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:PlatformToolset=v120 || goto :error
+msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Debug /p:PlatformToolset=v120 || goto :error
+msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
msbuild Grpc.sln /p:Configuration=Debug || goto :error
msbuild Grpc.sln /p:Configuration=Release || goto :error
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index c6e10bc1ff..da312886ce 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -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
@@ -95,10 +95,6 @@ Local<Value> nanErrorWithCode(const char *msg, grpc_call_error code) {
return scope.Escape(err);
}
-bool EndsWith(const char *str, const char *substr) {
- return strcmp(str+strlen(str)-strlen(substr), substr) == 0;
-}
-
bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array,
shared_ptr<Resources> resources) {
HandleScope scope;
@@ -126,7 +122,7 @@ bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array,
grpc_metadata *current = &array->metadata[array->count];
current->key = **utf8_key;
// Only allow binary headers for "-bin" keys
- if (EndsWith(current->key, "-bin")) {
+ if (grpc_is_binary_header(current->key, strlen(current->key))) {
if (::node::Buffer::HasInstance(value)) {
current->value = ::node::Buffer::Data(value);
current->value_length = ::node::Buffer::Length(value);
@@ -180,7 +176,7 @@ Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) {
} else {
array = Local<Array>::Cast(maybe_array.ToLocalChecked());
}
- if (EndsWith(elem->key, "-bin")) {
+ if (grpc_is_binary_header(elem->key, strlen(elem->key))) {
Nan::Set(array, index_map[elem->key],
MakeFastBuffer(
Nan::CopyBuffer(elem->value,
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index 8cbfb1ebea..91acb86254 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -32,6 +32,8 @@
*/
#include <node.h>
+#include <nan.h>
+#include <uv.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 5b5f3c1c5b..a2b8e0d22b 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -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
@@ -44,6 +44,7 @@
#include "completion_queue_async_worker.h"
#include "server_credentials.h"
+using v8::FunctionTemplate;
using v8::Local;
using v8::Value;
using v8::Object;
@@ -230,6 +231,40 @@ void InitWriteFlags(Local<Object> exports) {
Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS);
}
+NAN_METHOD(MetadataKeyIsLegal) {
+ if (!info[0]->IsString()) {
+ return Nan::ThrowTypeError(
+ "headerKeyIsLegal's argument must be a string");
+ }
+ Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
+ char *key_str = *Nan::Utf8String(key);
+ info.GetReturnValue().Set(static_cast<bool>(
+ grpc_header_key_is_legal(key_str, static_cast<size_t>(key->Length()))));
+}
+
+NAN_METHOD(MetadataNonbinValueIsLegal) {
+ if (!info[0]->IsString()) {
+ return Nan::ThrowTypeError(
+ "metadataNonbinValueIsLegal's argument must be a string");
+ }
+ Local<String> value = Nan::To<String>(info[0]).ToLocalChecked();
+ char *value_str = *Nan::Utf8String(value);
+ info.GetReturnValue().Set(static_cast<bool>(
+ grpc_header_nonbin_value_is_legal(
+ value_str, static_cast<size_t>(value->Length()))));
+}
+
+NAN_METHOD(MetadataKeyIsBinary) {
+ if (!info[0]->IsString()) {
+ return Nan::ThrowTypeError(
+ "metadataKeyIsLegal's argument must be a string");
+ }
+ Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
+ char *key_str = *Nan::Utf8String(key);
+ info.GetReturnValue().Set(static_cast<bool>(
+ grpc_is_binary_header(key_str, static_cast<size_t>(key->Length()))));
+}
+
void init(Local<Object> exports) {
Nan::HandleScope scope;
grpc_init();
@@ -247,6 +282,19 @@ void init(Local<Object> exports) {
grpc::node::Server::Init(exports);
grpc::node::CompletionQueueAsyncWorker::Init(exports);
grpc::node::ServerCredentials::Init(exports);
+
+ // Attach a few utility functions directly to the module
+ Nan::Set(exports, Nan::New("metadataKeyIsLegal").ToLocalChecked(),
+ Nan::GetFunction(
+ Nan::New<FunctionTemplate>(MetadataKeyIsLegal)).ToLocalChecked());
+ Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(),
+ Nan::GetFunction(
+ Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal)
+ ).ToLocalChecked());
+ Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(),
+ Nan::GetFunction(
+ Nan::New<FunctionTemplate>(MetadataKeyIsBinary)
+ ).ToLocalChecked());
}
NODE_MODULE(grpc_node, init)
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index bf68513c48..64015e8412 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -46,7 +46,7 @@ gpr_timespec MillisecondsToTimespec(double millis) {
} else if (millis == -std::numeric_limits<double>::infinity()) {
return gpr_inf_past(GPR_CLOCK_REALTIME);
} else {
- return gpr_time_from_micros(static_cast<int64_t>(millis * 1000),
+ return gpr_time_from_micros(static_cast<long>(millis * 1000),
GPR_CLOCK_REALTIME);
}
}
diff --git a/src/node/interop/async_delay_queue.js b/src/node/interop/async_delay_queue.js
index 2bd3ca4da3..df57209637 100644
--- a/src/node/interop/async_delay_queue.js
+++ b/src/node/interop/async_delay_queue.js
@@ -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
@@ -36,8 +36,8 @@
var _ = require('lodash');
/**
- * This class represents a queue of callbacks that must happen sequentially, each
- * with a specific delay after the previous event.
+ * This class represents a queue of callbacks that must happen sequentially,
+ * each with a specific delay after the previous event.
*/
function AsyncDelayQueue() {
this.queue = [];
diff --git a/src/node/jsdoc_conf.json b/src/node/jsdoc_conf.json
index 876a8e19c6..c3a0174f0e 100644
--- a/src/node/jsdoc_conf.json
+++ b/src/node/jsdoc_conf.json
@@ -3,13 +3,13 @@
"allowUnknownTags": true
},
"source": {
- "include": [ "index.js", "src" ],
- "includePattern": ".+\\.js(doc)?$",
+ "include": [ "src/node/index.js", "src/node/src" ],
+ "includePattern": "src/node/.+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"opts": {
"package": "package.json",
- "readme": "README.md"
+ "readme": "src/node/README.md"
},
"plugins": [],
"templates": {
diff --git a/src/node/src/common.js b/src/node/src/common.js
index e4fe5a8e03..2e6c01c4d7 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -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
@@ -125,7 +125,7 @@ exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service) {
var prefix = '/' + fullyQualifiedName(service) + '/';
return _.object(_.map(service.children, function(method) {
return [_.camelCase(method.name), {
- path: prefix + _.capitalize(method.name),
+ path: prefix + method.name,
requestStream: method.requestStream,
responseStream: method.responseStream,
requestSerialize: serializeCls(method.resolvedRequestType.build()),
diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js
index 0a2f1489b6..fef79f959e 100644
--- a/src/node/src/metadata.js
+++ b/src/node/src/metadata.js
@@ -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
@@ -49,6 +49,8 @@
var _ = require('lodash');
+var grpc = require('bindings')('grpc_node');
+
/**
* Class for storing metadata. Keys are normalized to lowercase ASCII.
* @constructor
@@ -58,15 +60,16 @@ function Metadata() {
}
function normalizeKey(key) {
- if (!(/^[A-Za-z\d_-]+$/.test(key))) {
- throw new Error('Metadata keys must be nonempty strings containing only ' +
- 'alphanumeric characters and hyphens');
+ key = key.toLowerCase();
+ if (grpc.metadataKeyIsLegal(key)) {
+ return key;
+ } else {
+ throw new Error('Metadata key contains illegal characters');
}
- return key.toLowerCase();
}
function validate(key, value) {
- if (_.endsWith(key, '-bin')) {
+ if (grpc.metadataKeyIsBinary(key)) {
if (!(value instanceof Buffer)) {
throw new Error('keys that end with \'-bin\' must have Buffer values');
}
@@ -75,9 +78,8 @@ function validate(key, value) {
throw new Error(
'keys that don\'t end with \'-bin\' must have String values');
}
- if (!(/^[\x20-\x7E]*$/.test(value))) {
- throw new Error('Metadata string values can only contain printable ' +
- 'ASCII characters and space');
+ if (!grpc.metadataNonbinValueIsLegal(value)) {
+ throw new Error('Metadata string value contains illegal characters');
}
}
}
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index c9fda42855..7a77ae60b6 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -241,11 +241,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.")
@protocol GRPCRequestHeaders <NSObject>
@property(nonatomic, readonly) NSUInteger count;
-- (id)objectForKeyedSubscript:(NSString *)key;
-- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key;
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)obj forKeyedSubscript:(id)key;
- (void)removeAllObjects;
-- (void)removeObjectForKey:(NSString *)key;
+- (void)removeObjectForKey:(id)key;
@end
#pragma clang diagnostic push
diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
index cfccdd453f..2f5716082b 100644
--- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
@@ -107,6 +107,7 @@
633BFFBF1B950B210007E424 /* Frameworks */,
633BFFC01B950B210007E424 /* Resources */,
AC2F6F9AB1C090BB0BEE6E4D /* Copy Pods Resources */,
+ A1738A987353B0BF2C64F0F7 /* Embed Pods Frameworks */,
);
buildRules = (
);
@@ -123,6 +124,7 @@
633BFFBA1B950B210007E424 /* Project object */ = {
isa = PBXProject;
attributes = {
+ LastSwiftUpdateCheck = 0710;
LastUpgradeCheck = 0640;
ORGANIZATIONNAME = gRPC;
TargetAttributes = {
@@ -177,6 +179,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
+ A1738A987353B0BF2C64F0F7 /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
AC2F6F9AB1C090BB0BEE6E4D /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -310,7 +327,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h";
- USER_HEADER_SEARCH_PATHS = "Pods/**";
+ USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
};
@@ -323,7 +340,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h";
- USER_HEADER_SEARCH_PATHS = "Pods/**";
+ USER_HEADER_SEARCH_PATHS = "";
};
name = Release;
};
diff --git a/src/proto/gen_build_yaml.py b/src/proto/gen_build_yaml.py
index 4e959830ea..e243d0defc 100755
--- a/src/proto/gen_build_yaml.py
+++ b/src/proto/gen_build_yaml.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python2.7
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -36,21 +36,36 @@ import os
import re
import sys
+def update_deps(key, proto_filename, deps, is_trans, visited):
+ if not proto_filename in visited:
+ visited.append(proto_filename)
+ with open(proto_filename) as inp:
+ for line in inp:
+ imp = re.search(r'import "([^"]*)"', line)
+ if not imp: continue
+ imp_proto = imp.group(1)
+ if key not in deps: deps[key] = []
+ deps[key].append(imp_proto[:-6])
+ if is_trans:
+ update_deps(key, imp_proto, deps, is_trans, visited)
+
def main():
+ proto_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+ os.chdir(os.path.join(proto_dir, '../..'))
+
deps = {}
- for root, dirs, files in os.walk(os.path.dirname(sys.argv[0])):
+ deps_trans = {}
+ for root, dirs, files in os.walk('src/proto'):
for f in files:
if f[-6:] != '.proto': continue
look_at = os.path.join(root, f)
- with open(look_at) as inp:
- for line in inp:
- imp = re.search(r'import "([^"]*)"', line)
- if not imp: continue
- if look_at[:-6] not in deps: deps[look_at[:-6]] = []
- deps[look_at[:-6]].append(imp.group(1)[:-6])
+ deps_for = look_at[:-6]
+ update_deps(deps_for, look_at, deps, False, []) # First level deps
+ update_deps(deps_for, look_at, deps_trans, True, []) # Transitive deps
json = {
- 'proto_deps': deps
+ 'proto_deps': deps,
+ 'proto_transitive_deps': deps_trans
}
print yaml.dump(json)
diff --git a/src/proto/grpc/testing/duplicate/echo_duplicate.proto b/src/proto/grpc/testing/duplicate/echo_duplicate.proto
index d5891db4ce..9d84de108e 100644
--- a/src/proto/grpc/testing/duplicate/echo_duplicate.proto
+++ b/src/proto/grpc/testing/duplicate/echo_duplicate.proto
@@ -1,5 +1,5 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,6 @@ import "src/proto/grpc/testing/echo_messages.proto";
package grpc.testing.duplicate;
-service TestService {
+service EchoTestService {
rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse);
}
diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto
index 0896f50a99..06c3bafbad 100644
--- a/src/proto/grpc/testing/echo.proto
+++ b/src/proto/grpc/testing/echo.proto
@@ -1,5 +1,5 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@ import "src/proto/grpc/testing/echo_messages.proto";
package grpc.testing;
-service TestService {
+service EchoTestService {
rpc Echo(EchoRequest) returns (EchoResponse);
rpc RequestStream(stream EchoRequest) returns (EchoResponse);
rpc ResponseStream(EchoRequest) returns (stream EchoResponse);
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 81dab1b518..e1a3f4bed3 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -40,6 +40,17 @@ import setuptools
from setuptools.command import build_py
from setuptools.command import test
+# Because we need to support building without Cython but simultaneously need to
+# subclass its command class when we need to and because distutils requires a
+# special hook to acquire a command class, we attempt to import Cython's
+# build_ext, and if that fails we import setuptools'.
+try:
+ # Due to the strange way Cython's Distutils module re-imports build_ext, we
+ # import the build_ext class directly.
+ from Cython.Distutils.build_ext import build_ext
+except ImportError:
+ from setuptools.command.build_ext import build_ext
+
PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
CONF_PY_ADDENDUM = """
@@ -51,6 +62,10 @@ html_theme = 'sphinx_rtd_theme'
"""
+class CommandError(Exception):
+ """Simple exception class for GRPC custom commands."""
+
+
class SphinxDocumentation(setuptools.Command):
"""Command to generate documentation via sphinx."""
@@ -104,10 +119,10 @@ class BuildProtoModules(setuptools.Command):
def run(self):
if not self.protoc_command:
- raise Exception('could not find protoc')
+ raise CommandError('could not find protoc')
if not self.grpc_python_plugin_command:
- raise Exception('could not find grpc_python_plugin '
- '(protoc plugin for GRPC Python)')
+ raise CommandError('could not find grpc_python_plugin '
+ '(protoc plugin for GRPC Python)')
include_regex = re.compile(self.include)
exclude_regex = re.compile(self.exclude) if self.exclude else None
paths = []
@@ -130,7 +145,7 @@ class BuildProtoModules(setuptools.Command):
subprocess.check_output(' '.join(command), cwd=root_directory, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
- raise Exception('Command:\n{}\nMessage:\n{}\nOutput:\n{}'.format(
+ raise CommandError('Command:\n{}\nMessage:\n{}\nOutput:\n{}'.format(
command, e.message, e.output))
@@ -156,13 +171,34 @@ class BuildPy(build_py.build_py):
"""Custom project build command."""
def run(self):
- # TODO(atash): make this warn if the proto modules couldn't be built rather
- # than cause build failure
- self.run_command('build_proto_modules')
+ try:
+ self.run_command('build_proto_modules')
+ except CommandError as error:
+ sys.stderr.write('warning: %s\n' % error.message)
self.run_command('build_project_metadata')
build_py.build_py.run(self)
+class BuildExt(build_ext):
+ """Custom build_ext command to enable compiler-specific flags."""
+
+ C_OPTIONS = {
+ 'unix': ('-pthread', '-std=gnu99'),
+ 'msvc': (),
+ }
+ LINK_OPTIONS = {}
+
+ def build_extensions(self):
+ compiler = self.compiler.compiler_type
+ if compiler in BuildExt.C_OPTIONS:
+ for extension in self.extensions:
+ extension.extra_compile_args += list(BuildExt.C_OPTIONS[compiler])
+ if compiler in BuildExt.LINK_OPTIONS:
+ for extension in self.extensions:
+ extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler])
+ build_ext.build_extensions(self)
+
+
class Gather(setuptools.Command):
"""Command to gather project dependencies."""
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 63cf0a4c74..952898d74a 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -188,6 +188,7 @@ CORE_SOURCE_FILES = [
'src/core/surface/server.c',
'src/core/surface/server_chttp2.c',
'src/core/surface/server_create.c',
+ 'src/core/surface/validate_metadata.c',
'src/core/surface/version.c',
'src/core/transport/byte_stream.c',
'src/core/transport/chttp2/alpn.c',
diff --git a/src/ruby/.rspec b/src/ruby/.rspec
deleted file mode 100755
index efeee2c1d2..0000000000
--- a/src/ruby/.rspec
+++ /dev/null
@@ -1,6 +0,0 @@
--I.
--Ipb
---backtrace
---require spec_helper
---format documentation
---color
diff --git a/src/ruby/Gemfile b/src/ruby/Gemfile
deleted file mode 100755
index 597a7d4f4b..0000000000
--- a/src/ruby/Gemfile
+++ /dev/null
@@ -1,4 +0,0 @@
-source 'https://rubygems.org'
-
-# Specify your gem's dependencies in grpc.gemspec
-gemspec
diff --git a/src/ruby/Rakefile b/src/ruby/Rakefile
deleted file mode 100755
index cc7832b12d..0000000000
--- a/src/ruby/Rakefile
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- ruby -*-
-require 'rake/extensiontask'
-require 'rspec/core/rake_task'
-require 'rubocop/rake_task'
-require 'bundler/gem_tasks'
-
-# Add rubocop style checking tasks
-RuboCop::RakeTask.new
-
-# Add the extension compiler task
-Rake::ExtensionTask.new 'grpc' do |ext|
- ext.lib_dir = File.join('lib', 'grpc')
-end
-
-# Define the test suites
-SPEC_SUITES = [
- { id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) },
- { id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic),
- tags: ['~bidi', '~server'] },
- { id: :bidi, title: 'bidi tests', dir: %w(spec/generic),
- tag: 'bidi' },
- { id: :server, title: 'rpc server thread tests', dir: %w(spec/generic),
- tag: 'server' },
- { id: :pb, title: 'protobuf service tests', dir: %w(spec/pb) }
-]
-namespace :suite do
- SPEC_SUITES.each do |suite|
- desc "Run all specs in the #{suite[:title]} spec suite"
- RSpec::Core::RakeTask.new(suite[:id]) do |t|
- ENV['COVERAGE_NAME'] = suite[:id].to_s
- spec_files = []
- suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
-
- if suite[:dir]
- suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
- end
- helper = 'spec/spec_helper.rb'
- spec_files << helper unless spec_files.include?(helper)
-
- t.pattern = spec_files
- t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
- if suite[:tags]
- t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
- end
- end
- end
-end
-
-# Define dependencies between the suites.
-task 'suite:wrapper' => [:compile, :rubocop]
-task 'suite:idiomatic' => 'suite:wrapper'
-task 'suite:bidi' => 'suite:wrapper'
-task 'suite:server' => 'suite:wrapper'
-task 'suite:pb' => 'suite:server'
-
-desc 'Compiles the gRPC extension then runs all the tests'
-task all: ['suite:idiomatic', 'suite:bidi', 'suite:pb', 'suite:server']
-task default: :all
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index db9385e961..018353ce5d 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -54,53 +54,30 @@ LIB_DIRS = [
LIBDIR
]
-def check_grpc_root
- grpc_root = ENV['GRPC_ROOT']
- if grpc_root.nil?
- r = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
- grpc_root = r if File.exist?(File.join(r, 'include/grpc/grpc.h'))
- end
- grpc_root
-end
+fail 'libdl not found' unless have_library('dl', 'dlopen')
+fail 'zlib not found' unless have_library('z', 'inflate')
+
+grpc_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
-grpc_pkg_config = system('pkg-config --exists grpc')
+grpc_config = ENV['GRPC_CONFIG'] || 'opt'
-if grpc_pkg_config
- $CFLAGS << ' ' + `pkg-config --static --cflags grpc`.strip + ' '
- $LDFLAGS << ' ' + `pkg-config --static --libs grpc`.strip + ' '
+if ENV.key?('GRPC_LIB_DIR')
+ grpc_lib_dir = File.join(grpc_root, ENV['GRPC_LIB_DIR'])
else
- dir_config('grpc', HEADER_DIRS, LIB_DIRS)
- fail 'libdl not found' unless have_library('dl', 'dlopen')
- fail 'zlib not found' unless have_library('z', 'inflate')
- begin
- fail 'Fail' unless have_library('gpr', 'gpr_now')
- fail 'Fail' unless have_library('grpc', 'grpc_channel_destroy')
- rescue
- # Check to see if GRPC_ROOT is defined or available
- grpc_root = check_grpc_root
-
- # Stop if there is still no grpc_root
- exit 1 if grpc_root.nil?
-
- grpc_config = ENV['GRPC_CONFIG'] || 'opt'
- if ENV.key?('GRPC_LIB_DIR')
- grpc_lib_dir = File.join(grpc_root, ENV['GRPC_LIB_DIR'])
- else
- grpc_lib_dir = File.join(File.join(grpc_root, 'libs'), grpc_config)
- end
- unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a'))
- print "Building internal gRPC\n"
- system("make -C #{grpc_root} static_c CONFIG=#{grpc_config}")
- end
- $CFLAGS << ' -I' + File.join(grpc_root, 'include')
- $LDFLAGS << ' -L' + grpc_lib_dir
- if grpc_config == 'gcov'
- $CFLAGS << ' -O0 -fprofile-arcs -ftest-coverage'
- $LDFLAGS << ' -fprofile-arcs -ftest-coverage -rdynamic'
- end
- raise 'gpr not found' unless have_library('gpr', 'gpr_now')
- raise 'grpc not found' unless have_library('grpc', 'grpc_channel_destroy')
- end
+ grpc_lib_dir = File.join(File.join(grpc_root, 'libs'), grpc_config)
+end
+
+unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a'))
+ print "Building internal gRPC\n"
+ system("make -C #{grpc_root} static_c CONFIG=#{grpc_config}")
+end
+
+$CFLAGS << ' -I' + File.join(grpc_root, 'include')
+$LDFLAGS << ' ' + File.join(grpc_lib_dir, 'libgrpc.a')
+$LDFLAGS << ' ' + File.join(grpc_lib_dir, 'libgpr.a')
+if grpc_config == 'gcov'
+ $CFLAGS << ' -O0 -fprofile-arcs -ftest-coverage'
+ $LDFLAGS << ' -fprofile-arcs -ftest-coverage -rdynamic'
end
$CFLAGS << ' -std=c99 '
@@ -109,4 +86,7 @@ $CFLAGS << ' -Wextra '
$CFLAGS << ' -pedantic '
$CFLAGS << ' -Werror '
+$LDFLAGS << ' -lssl '
+$LDFLAGS << ' -lcrypto '
+
create_makefile('grpc/grpc')
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 1647d9b484..43adafb73f 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -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
@@ -310,33 +310,61 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
grpc_metadata_array *md_ary = NULL;
long array_length;
long i;
+ char *key_str;
+ size_t key_len;
+ char *value_str;
+ size_t value_len;
+
+ if (TYPE(key) == T_SYMBOL) {
+ key_str = (char *)rb_id2name(SYM2ID(key));
+ key_len = strlen(key_str);
+ } else { /* StringValueCStr does all other type exclusions for us */
+ key_str = StringValueCStr(key);
+ key_len = RSTRING_LEN(key);
+ }
+
+ if (!grpc_header_key_is_legal(key_str, key_len)) {
+ rb_raise(rb_eArgError,
+ "'%s' is an invalid header key, must match [a-z0-9-_.]+",
+ key_str);
+ return ST_STOP;
+ }
/* Construct a metadata object from key and value and add it */
TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
&grpc_rb_md_ary_data_type, md_ary);
if (TYPE(val) == T_ARRAY) {
- /* If the value is an array, add capacity for each value in the array */
array_length = RARRAY_LEN(val);
+ /* If the value is an array, add capacity for each value in the array */
for (i = 0; i < array_length; i++) {
- if (TYPE(key) == T_SYMBOL) {
- md_ary->metadata[md_ary->count].key = (char *)rb_id2name(SYM2ID(key));
- } else { /* StringValueCStr does all other type exclusions for us */
- md_ary->metadata[md_ary->count].key = StringValueCStr(key);
+ value_str = RSTRING_PTR(rb_ary_entry(val, i));
+ value_len = RSTRING_LEN(rb_ary_entry(val, i));
+ if (!grpc_is_binary_header(key_str, key_len) &&
+ !grpc_header_nonbin_value_is_legal(value_str, value_len)) {
+ // The value has invalid characters
+ rb_raise(rb_eArgError,
+ "Header value '%s' has invalid characters", value_str);
+ return ST_STOP;
}
- md_ary->metadata[md_ary->count].value = RSTRING_PTR(rb_ary_entry(val, i));
- md_ary->metadata[md_ary->count].value_length =
- RSTRING_LEN(rb_ary_entry(val, i));
+ md_ary->metadata[md_ary->count].key = key_str;
+ md_ary->metadata[md_ary->count].value = value_str;
+ md_ary->metadata[md_ary->count].value_length = value_len;
md_ary->count += 1;
}
} else {
- if (TYPE(key) == T_SYMBOL) {
- md_ary->metadata[md_ary->count].key = (char *)rb_id2name(SYM2ID(key));
- } else { /* StringValueCStr does all other type exclusions for us */
- md_ary->metadata[md_ary->count].key = StringValueCStr(key);
+ value_str = RSTRING_PTR(val);
+ value_len = RSTRING_LEN(val);
+ if (!grpc_is_binary_header(key_str, key_len) &&
+ !grpc_header_nonbin_value_is_legal(value_str, value_len)) {
+ // The value has invalid characters
+ rb_raise(rb_eArgError,
+ "Header value '%s' has invalid characters", value_str);
+ return ST_STOP;
}
- md_ary->metadata[md_ary->count].value = RSTRING_PTR(val);
- md_ary->metadata[md_ary->count].value_length = RSTRING_LEN(val);
+ md_ary->metadata[md_ary->count].key = key_str;
+ md_ary->metadata[md_ary->count].value = value_str;
+ md_ary->metadata[md_ary->count].value_length = value_len;
md_ary->count += 1;
}
diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c
index acc5472799..4d719d7541 100644
--- a/src/ruby/ext/grpc/rb_call_credentials.c
+++ b/src/ruby/ext/grpc/rb_call_credentials.c
@@ -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
@@ -38,8 +38,10 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
#include "rb_call.h"
+#include "rb_event_thread.h"
#include "rb_grpc.h"
/* grpc_rb_cCallCredentials is the ruby class that proxies
@@ -87,7 +89,7 @@ static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args,
return result;
}
-static void *grpc_rb_call_credentials_callback_with_gil(void *param) {
+static void grpc_rb_call_credentials_callback_with_gil(void *param) {
callback_params *const params = (callback_params *)param;
VALUE auth_uri = rb_str_new_cstr(params->context.service_url);
/* Pass the arguments to the proc in a hash, which currently only has they key
@@ -113,21 +115,20 @@ static void *grpc_rb_call_credentials_callback_with_gil(void *param) {
params->callback(params->user_data, md_ary.metadata, md_ary.count, status,
error_details);
grpc_metadata_array_destroy(&md_ary);
-
- return NULL;
+ gpr_free(params);
}
static void grpc_rb_call_credentials_plugin_get_metadata(
void *state, grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb, void *user_data) {
- callback_params params;
- params.get_metadata = (VALUE)state;
- params.context = context;
- params.user_data = user_data;
- params.callback = cb;
-
- rb_thread_call_with_gvl(grpc_rb_call_credentials_callback_with_gil,
- (void*)(&params));
+ callback_params *params = gpr_malloc(sizeof(callback_params));
+ params->get_metadata = (VALUE)state;
+ params->context = context;
+ params->user_data = user_data;
+ params->callback = cb;
+
+ grpc_rb_event_queue_enqueue(grpc_rb_call_credentials_callback_with_gil,
+ (void*)(params));
}
static void grpc_rb_call_credentials_plugin_destroy(void *state) {
@@ -300,6 +301,8 @@ void Init_grpc_call_credentials() {
grpc_rb_call_credentials_compose, -1);
id_callback = rb_intern("__callback");
+
+ grpc_rb_event_queue_thread_start();
}
/* Gets the wrapped grpc_call_credentials from the ruby wrapper */
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index d5d82421f5..2fb8a5cdf0 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -59,6 +59,9 @@ static ID id_target;
* GCed before the channel */
static ID id_cqueue;
+/* id_insecure_channel is used to indicate that a channel is insecure */
+static VALUE id_insecure_channel;
+
/* grpc_rb_cChannel is the ruby class that proxies grpc_channel. */
static VALUE grpc_rb_cChannel = Qnil;
@@ -126,7 +129,8 @@ static VALUE grpc_rb_channel_alloc(VALUE cls) {
/*
call-seq:
- insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'})
+ insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'},
+ :this_channel_is_insecure)
creds = ...
secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
@@ -142,13 +146,18 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
grpc_channel_args args;
MEMZERO(&args, grpc_channel_args, 1);
- /* "21" == 2 mandatory args, 1 (credentials) is optional */
- rb_scan_args(argc, argv, "21", &target, &channel_args, &credentials);
+ /* "3" == 3 mandatory args */
+ rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);
TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
target_chars = StringValueCStr(target);
grpc_rb_hash_convert_to_channel_args(channel_args, &args);
- if (credentials == Qnil) {
+ if (TYPE(credentials) == T_SYMBOL) {
+ if (id_insecure_channel != SYM2ID(credentials)) {
+ rb_raise(rb_eTypeError,
+ "bad creds symbol, want :this_channel_is_insecure");
+ return Qnil;
+ }
ch = grpc_insecure_channel_create(target_chars, &args, NULL);
} else {
creds = grpc_rb_get_wrapped_channel_credentials(credentials);
@@ -408,6 +417,7 @@ void Init_grpc_channel() {
ID2SYM(rb_intern(GRPC_ARG_MAX_CONCURRENT_STREAMS)));
rb_define_const(grpc_rb_cChannel, "MAX_MESSAGE_LENGTH",
ID2SYM(rb_intern(GRPC_ARG_MAX_MESSAGE_LENGTH)));
+ id_insecure_channel = rb_intern("this_channel_is_insecure");
Init_grpc_propagate_masks();
Init_grpc_connectivity_states();
}
diff --git a/src/ruby/ext/grpc/rb_event_thread.c b/src/ruby/ext/grpc/rb_event_thread.c
new file mode 100644
index 0000000000..95af091317
--- /dev/null
+++ b/src/ruby/ext/grpc/rb_event_thread.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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 "rb_event_thread.h"
+
+#include <stdbool.h>
+
+#include <ruby/ruby.h>
+#include <ruby/thread.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <grpc/support/log.h>
+
+typedef struct grpc_rb_event {
+ // callback will be called with argument while holding the GVL
+ void (*callback)(void*);
+ void *argument;
+
+ struct grpc_rb_event *next;
+} grpc_rb_event;
+
+typedef struct grpc_rb_event_queue {
+ grpc_rb_event *head;
+ grpc_rb_event *tail;
+
+ gpr_mu mu;
+ gpr_cv cv;
+
+ // Indicates that the thread should stop waiting
+ bool abort;
+} grpc_rb_event_queue;
+
+static grpc_rb_event_queue event_queue;
+
+void grpc_rb_event_queue_enqueue(void (*callback)(void*),
+ void *argument) {
+ grpc_rb_event *event = gpr_malloc(sizeof(grpc_rb_event));
+ event->callback = callback;
+ event->argument = argument;
+ event->next = NULL;
+ gpr_mu_lock(&event_queue.mu);
+ if (event_queue.tail == NULL) {
+ event_queue.head = event_queue.tail = event;
+ } else {
+ event_queue.tail->next = event;
+ event_queue.tail = event;
+ }
+ gpr_cv_signal(&event_queue.cv);
+ gpr_mu_unlock(&event_queue.mu);
+}
+
+static grpc_rb_event *grpc_rb_event_queue_dequeue() {
+ grpc_rb_event *event;
+ if (event_queue.head == NULL) {
+ event = NULL;
+ } else {
+ event = event_queue.head;
+ if (event_queue.head->next == NULL) {
+ event_queue.head = event_queue.tail = NULL;
+ } else {
+ event_queue.head = event_queue.head->next;
+ }
+ }
+ return event;
+}
+
+static void grpc_rb_event_queue_destroy() {
+ gpr_mu_destroy(&event_queue.mu);
+ gpr_cv_destroy(&event_queue.cv);
+}
+
+static void *grpc_rb_wait_for_event_no_gil(void *param) {
+ grpc_rb_event *event = NULL;
+ gpr_mu_lock(&event_queue.mu);
+ while ((event = grpc_rb_event_queue_dequeue()) == NULL) {
+ gpr_cv_wait(&event_queue.cv,
+ &event_queue.mu,
+ gpr_inf_future(GPR_CLOCK_REALTIME));
+ if (event_queue.abort) {
+ gpr_mu_unlock(&event_queue.mu);
+ return NULL;
+ }
+ }
+ gpr_mu_unlock(&event_queue.mu);
+ return event;
+}
+
+static void grpc_rb_event_unblocking_func(void *arg) {
+ gpr_mu_lock(&event_queue.mu);
+ event_queue.abort = true;
+ gpr_cv_signal(&event_queue.cv);
+ gpr_mu_unlock(&event_queue.mu);
+}
+
+/* This is the implementation of the thread that handles auth metadata plugin
+ * events */
+static VALUE grpc_rb_event_thread(VALUE arg) {
+ grpc_rb_event *event;
+ while(true) {
+ event = (grpc_rb_event*)rb_thread_call_without_gvl(
+ grpc_rb_wait_for_event_no_gil, NULL,
+ grpc_rb_event_unblocking_func, NULL);
+ if (event == NULL) {
+ // Indicates that the thread needs to shut down
+ break;
+ } else {
+ event->callback(event->argument);
+ gpr_free(event);
+ }
+ }
+ grpc_rb_event_queue_destroy();
+ return Qnil;
+}
+
+void grpc_rb_event_queue_thread_start() {
+ event_queue.head = event_queue.tail = NULL;
+ event_queue.abort = false;
+ gpr_mu_init(&event_queue.mu);
+ gpr_cv_init(&event_queue.cv);
+
+ rb_thread_create(grpc_rb_event_thread, NULL);
+}
diff --git a/src/ruby/ext/grpc/rb_event_thread.h b/src/ruby/ext/grpc/rb_event_thread.h
new file mode 100644
index 0000000000..46638bfcf5
--- /dev/null
+++ b/src/ruby/ext/grpc/rb_event_thread.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+void grpc_rb_event_queue_thread_start();
+
+void grpc_rb_event_queue_enqueue(void (*callback)(void*),
+ void *argument);
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
deleted file mode 100755
index 363abe9a46..0000000000
--- a/src/ruby/grpc.gemspec
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- ruby -*-
-# encoding: utf-8
-$LOAD_PATH.push File.expand_path('../lib', __FILE__)
-require 'grpc/version'
-
-Gem::Specification.new do |s|
- s.name = 'grpc'
- s.version = GRPC::VERSION
- s.authors = ['gRPC Authors']
- s.email = 'temiola@google.com'
- s.homepage = 'https://github.com/google/grpc/tree/master/src/ruby'
- s.summary = 'GRPC system in Ruby'
- s.description = 'Send RPCs from Ruby using GRPC'
- s.license = 'BSD-3-Clause'
-
- s.required_ruby_version = '>= 2.0.0'
- s.requirements << 'libgrpc ~> 0.11.0 needs to be installed'
-
- s.files = %w( Rakefile )
- s.files += Dir.glob('bin/**/*')
- s.files += Dir.glob('ext/**/*')
- s.files += Dir.glob('lib/**/*')
- s.files += Dir.glob('pb/**/*')
- s.test_files = Dir.glob('spec/**/*')
- %w(math noproto).each do |b|
- s.executables += ["#{b}_client.rb", "#{b}_server.rb"]
- end
- s.executables += %w(grpc_ruby_interop_client grpc_ruby_interop_server)
- s.require_paths = %w( bin lib pb )
- s.platform = Gem::Platform::RUBY
-
- s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
- s.add_dependency 'googleauth', '~> 0.4'
-
- s.add_development_dependency 'bundler', '~> 1.9'
- s.add_development_dependency 'logging', '~> 2.0'
- s.add_development_dependency 'simplecov', '~> 0.9'
- s.add_development_dependency 'rake', '~> 10.4'
- s.add_development_dependency 'rake-compiler', '~> 0.9'
- s.add_development_dependency 'rspec', '~> 3.2'
- s.add_development_dependency 'rubocop', '~> 0.30.0'
- s.add_development_dependency 'signet', '~>0.6.0'
-
- s.extensions = %w(ext/grpc/extconf.rb)
-end
diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb
index 80b5743e91..1671ba3550 100644
--- a/src/ruby/lib/grpc.rb
+++ b/src/ruby/lib/grpc.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,6 +27,11 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ssl_roots_path = File.expand_path('../../../../etc/roots.pem', __FILE__)
+unless ENV['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH']
+ ENV['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = ssl_roots_path
+end
+
require 'grpc/errors'
require 'grpc/grpc'
require 'grpc/logconfig'
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 13100a614c..4da9ff086a 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -50,9 +50,8 @@ module GRPC
return alt_chan
end
kw['grpc.primary_user_agent'] = "grpc-ruby/#{VERSION}"
- return Core::Channel.new(host, kw) if creds.nil?
- unless creds.is_a?(Core::ChannelCredentials)
- fail(TypeError, '!ChannelCredentials')
+ unless creds.is_a?(Core::ChannelCredentials) || creds.is_a?(Symbol)
+ fail(TypeError, '!ChannelCredentials or Symbol')
end
Core::Channel.new(host, kw, creds)
end
@@ -68,7 +67,8 @@ module GRPC
# Minimally, a stub is created with the just the host of the gRPC service
# it wishes to access, e.g.,
#
- # my_stub = ClientStub.new(example.host.com:50505)
+ # my_stub = ClientStub.new(example.host.com:50505,
+ # :this_channel_is_insecure)
#
# Any arbitrary keyword arguments are treated as channel arguments used to
# configure the RPC connection to the host.
@@ -86,14 +86,14 @@ module GRPC
#
# @param host [String] the host the stub connects to
# @param q [Core::CompletionQueue] used to wait for events
+ # @param creds [Core::ChannelCredentials|Symbol] the channel credentials, or
+ # :this_channel_is_insecure
# @param channel_override [Core::Channel] a pre-created channel
# @param timeout [Number] the default timeout to use in requests
- # @param creds [Core::ChannelCredentials] the channel credentials
# @param kw [KeywordArgs]the channel arguments
- def initialize(host, q,
+ def initialize(host, q, creds,
channel_override: nil,
timeout: nil,
- creds: nil,
propagate_mask: nil,
**kw)
fail(TypeError, '!CompletionQueue') unless q.is_a?(Core::CompletionQueue)
@@ -464,7 +464,7 @@ module GRPC
method,
nil, # host use nil,
deadline)
- call.set_credentials credentials unless credentials.nil?
+ call.set_credentials! credentials unless credentials.nil?
ActiveCall.new(call, @queue, marshal, unmarshal, deadline, started: false)
end
end
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 80ff669cca..410e1add7d 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -160,10 +160,12 @@ module GRPC
route_prefix = service_name
Class.new(ClientStub) do
# @param host [String] the host the stub connects to
+ # @param creds [Core::ChannelCredentials|Symbol] The channel
+ # credentials to use, or :this_channel_is_insecure otherwise
# @param kw [KeywordArgs] the channel arguments, plus any optional
# args for configuring the client's channel
- def initialize(host, **kw)
- super(host, Core::CompletionQueue.new, **kw)
+ def initialize(host, creds, **kw)
+ super(host, Core::CompletionQueue.new, creds, **kw)
end
# Used define_method to add a method for each rpc_desc. Each method
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 9acf7a055a..956e0222df 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -29,5 +29,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '0.11.1'
+ VERSION = '0.12.0'
end
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index 6cc616e5cb..684ee80771 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -56,8 +56,6 @@ require 'test/proto/empty'
require 'test/proto/messages'
require 'test/proto/test_services'
-require 'signet/ssl_config'
-
AUTH_ENV = Google::Auth::CredentialsLoader::ENV_VAR
# RubyLogger defines a logger for gRPC based on the standard ruby logger.
@@ -114,8 +112,8 @@ end
def create_stub(opts)
address = "#{opts.host}:#{opts.port}"
if opts.secure
+ creds = ssl_creds(opts.use_test_ca)
stub_opts = {
- :creds => ssl_creds(opts.use_test_ca),
GRPC::Core::Channel::SSL_TARGET => opts.host_override
}
@@ -125,7 +123,7 @@ def create_stub(opts)
unless opts.oauth_scope.nil?
auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
- stub_opts[:creds] = stub_opts[:creds].compose call_creds
+ creds = creds.compose call_creds
end
end
@@ -135,20 +133,20 @@ def create_stub(opts)
# use a metadata update proc that just adds the auth token.
call_creds = GRPC::Core::CallCredentials.new(proc { |md| md.merge(kw) })
- stub_opts[:creds] = stub_opts[:creds].compose call_creds
+ creds = creds.compose call_creds
end
if opts.test_case == 'jwt_token_creds' # don't use a scope
auth_creds = Google::Auth.get_application_default
call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
- stub_opts[:creds] = stub_opts[:creds].compose call_creds
+ creds = creds.compose call_creds
end
GRPC.logger.info("... connecting securely to #{address}")
- Grpc::Testing::TestService::Stub.new(address, **stub_opts)
+ Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts)
else
GRPC.logger.info("... connecting insecurely to #{address}")
- Grpc::Testing::TestService::Stub.new(address)
+ Grpc::Testing::TestService::Stub.new(address, :this_channel_is_insecure)
end
end
@@ -266,16 +264,15 @@ class NamedTests
def per_rpc_creds
auth_creds = Google::Auth.get_application_default(@args.oauth_scope)
- kw = auth_creds.updater_proc.call({})
+ update_metadata = proc do |md|
+ kw = auth_creds.updater_proc.call({})
+ end
- # TODO(jtattermusch): downcase the metadata keys here to make sure
- # they are not rejected by C core. This is a hotfix that should
- # be addressed by introducing auto-downcasing logic.
- kw = Hash[ kw.each_pair.map { |k, v| [k.downcase, v] }]
+ call_creds = GRPC::Core::CallCredentials.new(update_metadata)
resp = perform_large_unary(fill_username: true,
fill_oauth_scope: true,
- **kw)
+ credentials: call_creds)
json_key = File.read(ENV[AUTH_ENV])
wanted_email = MultiJson.load(json_key)['client_email']
assert("#{__callee__}: bad username") { wanted_email == resp.username }
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index 6629570fba..ae3ce0748a 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -101,7 +101,7 @@ describe GRPC::Core::Call do
let(:fake_host) { 'localhost:10101' }
before(:each) do
- @ch = GRPC::Core::Channel.new(fake_host, nil)
+ @ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
end
describe '#status' do
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index b4d2b94a81..355f95c9d7 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -45,7 +45,10 @@ describe GRPC::Core::Channel do
shared_examples '#new' do
it 'take a host name without channel args' do
- expect { GRPC::Core::Channel.new('dummy_host', nil) }.not_to raise_error
+ blk = proc do
+ GRPC::Core::Channel.new('dummy_host', nil, :this_channel_is_insecure)
+ end
+ expect(&blk).not_to raise_error
end
it 'does not take a hash with bad keys as channel args' do
@@ -106,13 +109,15 @@ describe GRPC::Core::Channel do
it_behaves_like '#new'
def construct_with_args(a)
- proc { GRPC::Core::Channel.new('dummy_host', a) }
+ proc do
+ GRPC::Core::Channel.new('dummy_host', a, :this_channel_is_insecure)
+ end
end
end
describe '#create_call' do
it 'creates a call OK' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
deadline = Time.now + 5
@@ -123,7 +128,7 @@ describe GRPC::Core::Channel do
end
it 'raises an error if called on a closed channel' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
ch.close
deadline = Time.now + 5
@@ -136,13 +141,13 @@ describe GRPC::Core::Channel do
describe '#destroy' do
it 'destroys a channel ok' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
blk = proc { ch.destroy }
expect(&blk).to_not raise_error
end
it 'can be called more than once without error' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
blk = proc { ch.destroy }
blk.call
expect(&blk).to_not raise_error
@@ -157,13 +162,13 @@ describe GRPC::Core::Channel do
describe '#close' do
it 'closes a channel ok' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
blk = proc { ch.close }
expect(&blk).to_not raise_error
end
it 'can be called more than once without error' do
- ch = GRPC::Core::Channel.new(fake_host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
blk = proc { ch.close }
blk.call
expect(&blk).to_not raise_error
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 7cce2076c9..594fda1cd3 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -397,7 +397,7 @@ describe 'the http client/server' do
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
@server.start
- @ch = Channel.new("0.0.0.0:#{server_port}", nil)
+ @ch = Channel.new("0.0.0.0:#{server_port}", nil, :this_channel_is_insecure)
end
after(:example) do
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index b05e3284fe..c0181e21fb 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -48,7 +48,8 @@ describe GRPC::ActiveCall do
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(host, :this_port_is_insecure)
@server.start
- @ch = GRPC::Core::Channel.new("0.0.0.0:#{server_port}", nil)
+ @ch = GRPC::Core::Channel.new("0.0.0.0:#{server_port}", nil,
+ :this_channel_is_insecure)
end
after(:each) do
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 40550230dd..5e13c25fcf 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -70,7 +70,7 @@ describe 'ClientStub' do
it 'can be created from a host and args' do
opts = { a_channel_arg: 'an_arg' }
blk = proc do
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, :this_channel_is_insecure, **opts)
end
expect(&blk).not_to raise_error
end
@@ -78,7 +78,7 @@ describe 'ClientStub' do
it 'can be created with a default deadline' do
opts = { a_channel_arg: 'an_arg', deadline: 5 }
blk = proc do
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, :this_channel_is_insecure, **opts)
end
expect(&blk).not_to raise_error
end
@@ -86,7 +86,7 @@ describe 'ClientStub' do
it 'can be created with an channel override' do
opts = { a_channel_arg: 'an_arg', channel_override: @ch }
blk = proc do
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, :this_channel_is_insecure, **opts)
end
expect(&blk).not_to raise_error
end
@@ -94,15 +94,15 @@ describe 'ClientStub' do
it 'cannot be created with a bad channel override' do
blk = proc do
opts = { a_channel_arg: 'an_arg', channel_override: Object.new }
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, :this_channel_is_insecure, **opts)
end
expect(&blk).to raise_error
end
it 'cannot be created with bad credentials' do
blk = proc do
- opts = { a_channel_arg: 'an_arg', creds: Object.new }
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ opts = { a_channel_arg: 'an_arg' }
+ GRPC::ClientStub.new(fake_host, @cq, Object.new, **opts)
end
expect(&blk).to raise_error
end
@@ -112,10 +112,10 @@ describe 'ClientStub' do
blk = proc do
opts = {
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr',
- a_channel_arg: 'an_arg',
- creds: GRPC::Core::ChannelCredentials.new(certs[0], nil, nil)
+ a_channel_arg: 'an_arg'
}
- GRPC::ClientStub.new(fake_host, @cq, **opts)
+ creds = GRPC::Core::ChannelCredentials.new(certs[0], nil, nil)
+ GRPC::ClientStub.new(fake_host, @cq, creds, **opts)
end
expect(&blk).to_not raise_error
end
@@ -130,7 +130,8 @@ describe 'ClientStub' do
it 'should send a request to/receive a reply from a server' do
server_port = create_test_server
th = run_request_response(@sent_msg, @resp, @pass)
- stub = GRPC::ClientStub.new("localhost:#{server_port}", @cq)
+ stub = GRPC::ClientStub.new("localhost:#{server_port}", @cq,
+ :this_channel_is_insecure)
expect(get_response(stub)).to eq(@resp)
th.join
end
@@ -140,7 +141,7 @@ describe 'ClientStub' do
host = "localhost:#{server_port}"
th = run_request_response(@sent_msg, @resp, @pass,
k1: 'v1', k2: 'v2')
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
expect(get_response(stub)).to eq(@resp)
th.join
end
@@ -149,8 +150,10 @@ describe 'ClientStub' do
server_port = create_test_server
alt_host = "localhost:#{server_port}"
th = run_request_response(@sent_msg, @resp, @pass)
- ch = GRPC::Core::Channel.new(alt_host, nil)
- stub = GRPC::ClientStub.new('ignored-host', @cq, channel_override: ch)
+ ch = GRPC::Core::Channel.new(alt_host, nil, :this_channel_is_insecure)
+ stub = GRPC::ClientStub.new('ignored-host', @cq,
+ :this_channel_is_insecure,
+ channel_override: ch)
expect(get_response(stub)).to eq(@resp)
th.join
end
@@ -159,7 +162,7 @@ describe 'ClientStub' do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_request_response(@sent_msg, @resp, @fail)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
blk = proc { get_response(stub) }
expect(&blk).to raise_error(GRPC::BadStatus)
th.join
@@ -198,7 +201,7 @@ describe 'ClientStub' do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_client_streamer(@sent_msgs, @resp, @pass)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
expect(get_response(stub)).to eq(@resp)
th.join
end
@@ -208,7 +211,7 @@ describe 'ClientStub' do
host = "localhost:#{server_port}"
th = run_client_streamer(@sent_msgs, @resp, @pass,
k1: 'v1', k2: 'v2')
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
expect(get_response(stub)).to eq(@resp)
th.join
end
@@ -217,7 +220,7 @@ describe 'ClientStub' do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_client_streamer(@sent_msgs, @resp, @fail)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
blk = proc { get_response(stub) }
expect(&blk).to raise_error(GRPC::BadStatus)
th.join
@@ -256,7 +259,7 @@ describe 'ClientStub' do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_server_streamer(@sent_msg, @replys, @pass)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
expect(get_responses(stub).collect { |r| r }).to eq(@replys)
th.join
end
@@ -265,7 +268,7 @@ describe 'ClientStub' do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_server_streamer(@sent_msg, @replys, @fail)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
e = get_responses(stub)
expect { e.collect { |r| r } }.to raise_error(GRPC::BadStatus)
th.join
@@ -276,7 +279,7 @@ describe 'ClientStub' do
host = "localhost:#{server_port}"
th = run_server_streamer(@sent_msg, @replys, @fail,
k1: 'v1', k2: 'v2')
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
e = get_responses(stub)
expect { e.collect { |r| r } }.to raise_error(GRPC::BadStatus)
th.join
@@ -320,7 +323,7 @@ describe 'ClientStub' do
it 'supports sending all the requests first', bidi: true do
th = run_bidi_streamer_handle_inputs_first(@sent_msgs, @replys,
@pass)
- stub = GRPC::ClientStub.new(@host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq, :this_channel_is_insecure)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@replys)
th.join
@@ -328,7 +331,7 @@ describe 'ClientStub' do
it 'supports client-initiated ping pong', bidi: true do
th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, true)
- stub = GRPC::ClientStub.new(@host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq, :this_channel_is_insecure)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@sent_msgs)
th.join
@@ -336,7 +339,7 @@ describe 'ClientStub' do
it 'supports a server-initiated ping pong', bidi: true do
th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, false)
- stub = GRPC::ClientStub.new(@host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq, :this_channel_is_insecure)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@sent_msgs)
th.join
@@ -376,7 +379,7 @@ describe 'ClientStub' do
it 'should fail with DeadlineExceeded', bidi: true do
@server.start
- stub = GRPC::ClientStub.new(@host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq, :this_channel_is_insecure)
blk = proc do
e = stub.bidi_streamer(@method, @sent_msgs, noop, noop,
timeout: 0.001)
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index d95a021311..be6331d68b 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -141,7 +141,7 @@ describe GRPC::RpcServer do
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
@host = "localhost:#{server_port}"
- @ch = GRPC::Core::Channel.new(@host, nil)
+ @ch = GRPC::Core::Channel.new(@host, nil, :this_channel_is_insecure)
end
describe '#new' do
@@ -355,7 +355,8 @@ describe GRPC::RpcServer do
req = EchoMsg.new
blk = proc do
cq = GRPC::Core::CompletionQueue.new
- stub = GRPC::ClientStub.new(@host, cq, **client_opts)
+ stub = GRPC::ClientStub.new(@host, cq, :this_channel_is_insecure,
+ **client_opts)
stub.request_response('/unknown', req, marshal, unmarshal)
end
expect(&blk).to raise_error GRPC::BadStatus
@@ -369,7 +370,7 @@ describe GRPC::RpcServer do
@srv.wait_till_running
req = EchoMsg.new
n = 5 # arbitrary
- stub = EchoStub.new(@host, **client_opts)
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
n.times { expect(stub.an_rpc(req)).to be_a(EchoMsg) }
@srv.stop
t.join
@@ -381,7 +382,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = EchoStub.new(@host, **client_opts)
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
expect(stub.an_rpc(req, k1: 'v1', k2: 'v2')).to be_a(EchoMsg)
wanted_md = [{ 'k1' => 'v1', 'k2' => 'v2' }]
check_md(wanted_md, service.received_md)
@@ -395,7 +396,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = SlowStub.new(@host, **client_opts)
+ stub = SlowStub.new(@host, :this_channel_is_insecure, **client_opts)
timeout = service.delay + 1.0 # wait for long enough
resp = stub.an_rpc(req, timeout: timeout, k1: 'v1', k2: 'v2')
expect(resp).to be_a(EchoMsg)
@@ -411,7 +412,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = SlowStub.new(@host, **client_opts)
+ stub = SlowStub.new(@host, :this_channel_is_insecure, **client_opts)
op = stub.an_rpc(req, k1: 'v1', k2: 'v2', return_op: true)
Thread.new do # cancel the call
sleep 0.1
@@ -431,7 +432,7 @@ describe GRPC::RpcServer do
threads = [t]
n.times do
threads << Thread.new do
- stub = EchoStub.new(@host, **client_opts)
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
q << stub.an_rpc(req)
end
end
@@ -459,7 +460,7 @@ describe GRPC::RpcServer do
one_failed_as_unavailable = false
n.times do
threads << Thread.new do
- stub = SlowStub.new(@host, **client_opts)
+ stub = SlowStub.new(@host, :this_channel_is_insecure, **client_opts)
begin
stub.an_rpc(req)
rescue GRPC::BadStatus => e
@@ -499,7 +500,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = EchoStub.new(@host, **client_opts)
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
op = stub.an_rpc(req, k1: 'v1', k2: 'v2', return_op: true)
expect(op.metadata).to be nil
expect(op.execute).to be_a(EchoMsg)
@@ -537,7 +538,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = FailingStub.new(@host, **client_opts)
+ stub = FailingStub.new(@host, :this_channel_is_insecure, **client_opts)
blk = proc { stub.an_rpc(req) }
# confirm it raise the expected error
@@ -562,7 +563,7 @@ describe GRPC::RpcServer do
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
- stub = EchoStub.new(@host, **client_opts)
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
op = stub.an_rpc(req, k1: 'v1', k2: 'v2', return_op: true)
expect(op.metadata).to be nil
expect(op.execute).to be_a(EchoMsg)
diff --git a/src/ruby/spec/generic/service_spec.rb b/src/ruby/spec/generic/service_spec.rb
index 6cfc34db84..5e7b6c7aba 100644
--- a/src/ruby/spec/generic/service_spec.rb
+++ b/src/ruby/spec/generic/service_spec.rb
@@ -241,7 +241,7 @@ describe GenericService do
end
describe 'the generated instances' do
- it 'can be instanciated with just a hostname' do
+ it 'can be instanciated with just a hostname and credentials' do
s = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
@@ -250,7 +250,10 @@ describe GenericService do
rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
end
client_class = s.rpc_stub_class
- expect { client_class.new('fakehostname') }.not_to raise_error
+ blk = proc do
+ client_class.new('fakehostname', :this_channel_is_insecure)
+ end
+ expect(&blk).not_to raise_error
end
it 'has the methods defined in the service' do
@@ -262,7 +265,7 @@ describe GenericService do
rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
end
client_class = s.rpc_stub_class
- o = client_class.new('fakehostname')
+ o = client_class.new('fakehostname', :this_channel_is_insecure)
expect(o.methods).to include(:an_rpc)
expect(o.methods).to include(:a_bidi_streamer)
expect(o.methods).to include(:a_client_streamer)
diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb
index 322566b784..c1decd822a 100644
--- a/src/ruby/spec/pb/health/checker_spec.rb
+++ b/src/ruby/spec/pb/health/checker_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -47,13 +47,12 @@ describe 'Health protobuf code generation' do
end
it 'should have the same content as created by code generation' do
- root_dir = File.dirname(
- File.dirname(File.dirname(File.dirname(__FILE__))))
- pb_dir = File.join(root_dir, 'pb')
+ root_dir = File.join(File.dirname(__FILE__), '..', '..', '..', '..')
+ pb_dir = File.join(root_dir, 'proto')
# Get the current content
- service_path = File.join(pb_dir, 'grpc', 'health', 'v1alpha',
- 'health_services.rb')
+ service_path = File.join(root_dir, 'ruby', 'pb', 'grpc',
+ 'health', 'v1alpha', 'health_services.rb')
want = nil
File.open(service_path) { |f| want = f.read }
@@ -188,7 +187,7 @@ describe Grpc::Health::Checker do
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host, :this_port_is_insecure)
@host = "localhost:#{server_port}"
- @ch = GRPC::Core::Channel.new(@host, nil)
+ @ch = GRPC::Core::Channel.new(@host, nil, :this_channel_is_insecure)
@client_opts = { channel_override: @ch }
server_opts = {
server_override: @server,
@@ -208,7 +207,7 @@ describe Grpc::Health::Checker do
t = Thread.new { @srv.run }
@srv.wait_till_running
- stub = CheckerStub.new(@host, **@client_opts)
+ stub = CheckerStub.new(@host, :this_channel_is_insecure, **@client_opts)
got = stub.check(HCReq.new)
want = HCResp.new(status: ServingStatus::NOT_SERVING)
expect(got).to eq(want)
@@ -221,7 +220,7 @@ describe Grpc::Health::Checker do
t = Thread.new { @srv.run }
@srv.wait_till_running
blk = proc do
- stub = CheckerStub.new(@host, **@client_opts)
+ stub = CheckerStub.new(@host, :this_channel_is_insecure, **@client_opts)
stub.check(HCReq.new(host: 'unknown', service: 'unknown'))
end
expected_msg = /#{StatusCodes::NOT_FOUND}/