Add a test of httpcli over ssl

pull/4344/head
Craig Tiller 9 years ago
parent 095a2377e4
commit cc0535d25e
  1. 34
      Makefile
  2. 14
      build.yaml
  3. 9
      src/core/httpcli/httpcli.c
  4. 2
      src/core/httpcli/httpcli.h
  5. 188
      test/core/httpcli/httpscli_test.c
  6. 14
      test/core/httpcli/test_server.py
  7. 6
      tools/run_tests/run_tests.py
  8. 14
      tools/run_tests/sources_and_headers.json
  9. 16
      tools/run_tests/tests.json

File diff suppressed because one or more lines are too long

@ -1325,6 +1325,20 @@ targets:
- mac
- linux
- posix
- name: httpscli_test
build: test
language: c
src:
- test/core/httpcli/httpscli_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: init_test
build: test
language: c

@ -53,6 +53,7 @@ typedef struct {
size_t next_address;
grpc_endpoint *ep;
char *host;
char *ssl_host_override;
gpr_timespec deadline;
int have_read_byte;
const grpc_httpcli_handshaker *handshaker;
@ -106,6 +107,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
}
gpr_slice_unref(req->request_text);
gpr_free(req->host);
gpr_free(req->ssl_host_override);
grpc_iomgr_unregister_object(&req->iomgr_obj);
gpr_slice_buffer_destroy(&req->incoming);
gpr_slice_buffer_destroy(&req->outgoing);
@ -180,8 +182,10 @@ static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
next_address(exec_ctx, req);
return;
}
req->handshaker->handshake(exec_ctx, req, req->ep, req->host,
on_handshake_done);
req->handshaker->handshake(
exec_ctx, req, req->ep,
req->ssl_host_override ? req->ssl_host_override : req->host,
on_handshake_done);
}
static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) {
@ -231,6 +235,7 @@ static void internal_request_begin(
gpr_slice_buffer_init(&req->outgoing);
grpc_iomgr_register_object(&req->iomgr_obj, name);
req->host = gpr_strdup(request->host);
req->ssl_host_override = gpr_strdup(request->ssl_host_override);
grpc_pollset_set_add_pollset(exec_ctx, &req->context->pollset_set,
req->pollset);

@ -74,6 +74,8 @@ extern const grpc_httpcli_handshaker grpc_httpcli_ssl;
typedef struct grpc_httpcli_request {
/* The host name to connect to */
char *host;
/* The host to verify in the SSL handshake (or NULL) */
char *ssl_host_override;
/* The path of the resource to fetch */
char *path;
/* Additional headers: count and key/values; the following are supplied

@ -0,0 +1,188 @@
/*
*
* 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 "src/core/httpcli/httpcli.h"
#include <string.h>
#include <grpc/grpc.h>
#include "src/core/iomgr/iomgr.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/subprocess.h>
#include <grpc/support/sync.h>
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
static int g_done = 0;
static grpc_httpcli_context g_context;
static grpc_pollset g_pollset;
static gpr_timespec n_seconds_time(int seconds) {
return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
}
static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
const grpc_httpcli_response *response) {
const char *expect =
"<html><head><title>Hello world!</title></head>"
"<body><p>This is a test</p></body></html>";
GPR_ASSERT(arg == (void *)42);
GPR_ASSERT(response);
GPR_ASSERT(response->status == 200);
GPR_ASSERT(response->body_length == strlen(expect));
GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
g_done = 1;
grpc_pollset_kick(&g_pollset, NULL);
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
}
static void test_get(int use_ssl, int port) {
grpc_httpcli_request req;
char *host;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
g_done = 0;
gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_get", use_ssl);
gpr_asprintf(&host, "localhost:%d", port);
gpr_log(GPR_INFO, "requesting from %s", host);
memset(&req, 0, sizeof(req));
req.host = host;
req.ssl_host_override = "foo.test.google.fr";
req.path = "/get";
req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
on_finish, (void *)42);
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
while (!g_done) {
grpc_pollset_worker worker;
grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
}
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
gpr_free(host);
}
static void test_post(int use_ssl, int port) {
grpc_httpcli_request req;
char *host;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
g_done = 0;
gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_post", (int)use_ssl);
gpr_asprintf(&host, "localhost:%d", port);
gpr_log(GPR_INFO, "posting to %s", host);
memset(&req, 0, sizeof(req));
req.host = host;
req.ssl_host_override = "foo.test.google.fr";
req.path = "/post";
req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
n_seconds_time(15), on_finish, (void *)42);
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
while (!g_done) {
grpc_pollset_worker worker;
grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
}
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
gpr_free(host);
}
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
grpc_pollset_destroy(p);
}
int main(int argc, char **argv) {
grpc_closure destroyed;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_subprocess *server;
char *me = argv[0];
char *lslash = strrchr(me, '/');
char *args[5];
char root[1024];
int port = grpc_pick_unused_port_or_die();
/* figure out where we are */
if (lslash) {
memcpy(root, me, (size_t)(lslash - me));
root[lslash - me] = 0;
} else {
strcpy(root, ".");
}
/* start the server */
gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
args[1] = "--port";
gpr_asprintf(&args[2], "%d", port);
args[3] = "--ssl";
server = gpr_subprocess_create(4, (const char **)args);
GPR_ASSERT(server);
gpr_free(args[0]);
gpr_free(args[2]);
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(5, GPR_TIMESPAN)));
grpc_test_init(argc, argv);
grpc_init();
grpc_httpcli_context_init(&g_context);
grpc_pollset_init(&g_pollset);
test_get(1, port);
test_post(1, port);
grpc_httpcli_context_destroy(&g_context);
grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
gpr_subprocess_destroy(server);
return 0;
}

@ -4,9 +4,18 @@
import argparse
import BaseHTTPServer
import os
import ssl
import sys
_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem'))
_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key'))
print _PEM
open(_PEM).close()
argp = argparse.ArgumentParser(description='Server for httpcli_test')
argp.add_argument('-p', '--port', default=10080, type=int)
argp.add_argument('-s', '--ssl', default=False, action='store_true')
args = argp.parse_args()
print 'server running on port %d' % args.port
@ -28,4 +37,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
if self.path == '/post' and content == 'hello':
self.good()
BaseHTTPServer.HTTPServer(('', args.port), Handler).serve_forever()
httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler)
if args.ssl:
httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True)
httpd.serve_forever()

@ -152,7 +152,10 @@ class CLanguage(object):
else:
binary = 'bins/%s/%s' % (config.build_config, target['name'])
if os.path.isfile(binary):
out.append(config.job_spec([binary], [binary]))
out.append(config.job_spec([binary], [binary],
environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
os.path.abspath(os.path.dirname(
sys.argv[0]) + '/../../etc')}))
elif args.regex == '.*' or platform_string() == 'windows':
print '\nWARNING: binary not found, skipping', binary
return sorted(out)
@ -192,6 +195,7 @@ class CLanguage(object):
def __str__(self):
return self.make_target
class NodeLanguage(object):
def test_specs(self, config, args):

@ -688,6 +688,20 @@
"test/core/httpcli/httpcli_test.c"
]
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "httpscli_test",
"src": [
"test/core/httpcli/httpscli_test.c"
]
},
{
"deps": [
"gpr",

@ -779,6 +779,22 @@
"posix"
]
},
{
"ci_platforms": [
"linux",
"mac",
"posix"
],
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "httpscli_test",
"platforms": [
"linux",
"mac",
"posix"
]
},
{
"ci_platforms": [
"linux",

Loading…
Cancel
Save