blob: 3590805beb07b3007b9e59d988dc1d14c235e3d8 [file] [log] [blame]
Mark D. Roth4623e1c2016-07-18 14:09:18 -07001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <string.h>
35
36#include <grpc/impl/codegen/alloc.h>
37#include <grpc/impl/codegen/log.h>
38
39#include "src/core/ext/client_config/http_connect_handshaker.h"
40
41typedef struct http_connect_handshaker {
42 // Base class. Must be first.
43 grpc_handshaker base;
44
45 // State saved while performing the handshake.
46 grpc_endpoint* endpoint;
47 grpc_channel_args* args;
48 grpc_handshaker_done_cb cb;
49 void* user_data;
50
51 // Objects for processing the HTTP CONNECT request and response.
52 grpc_slice_buffer request_buffer;
53 grpc_closure request_done_closure;
54 grpc_slice_buffer response_buffer;
55 grpc_closure response_read_closure;
56} http_connect_handshaker;
57
58static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
59 grpc_handshaker* handshaker) {
60}
61
62static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
63 grpc_handshaker* handshaker) {
64}
65
66// Callback invoked for reading HTTP CONNECT response.
67static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
68 grpc_error* error) {
69 http_connect_handshaker* h = arg;
70// FIXME: process response; on failure, figure out how to abort
71
72 // Invoke handshake-done callback.
73 h->cb(exec_ctx, h->endpoint, h->args, h->user_data);
74}
75
76// Callback invoked when finished writing HTTP CONNECT request.
77static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
78 grpc_error* error) {
79 http_connect_handshaker* h = arg;
80 // Read HTTP CONNECT response.
81 gpr_slice_buffer_init(&h->response_buffer);
82 grpc_closure_init(&h->response_read_closure, on_read_done, h);
83 grpc_endpoint_read(exec_ctx, h->endpoint, &h->response_buffer,
84 &h->response_read_closure);
85}
86
87static void http_connect_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
88 grpc_handshaker* handshaker,
89 grpc_endpoint* endpoint,
90 grpc_channel_args* args,
91 gpr_timespec deadline,
92 grpc_handshaker_done_cb cb,
93 void* user_data) {
94 http_connect_handshaker* h = (http_connect_handshaker*)handshaker;
95 // Save state in the handshaker object.
96 h->endpoint = endpoint;
97 h->args = args;
98 h->cb = cb;
99 h->user_data = user_data;
100 // Send HTTP CONNECT request.
101 gpr_slice_buffer_init(&h->request_buffer);
102 gpr_slice_buffer_add(&h->request_buffer, "HTTP CONNECT ");
103// FIXME: get server name from somewhere...
104 gpr_slice_buffer_add(&h->request_buffer, WHEE);
105// FIXME: add headers as needed?
106 gpr_slice_buffer_add(&h->request_buffer, "\n\n");
107 grpc_closure_init(&h->request_done_closure, on_write_done, h);
108 grpc_endpoint_write(exec_ctx, endpoint, &h->request_buffer,
109 &h->request_done_closure);
110}
111
112static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = {
113 http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
114 http_connect_handshaker_do_handshake};
115
116grpc_handshaker* grpc_http_connect_handshaker_create() {
117 http_connect_handshaker* handshaker =
118 gpr_malloc(sizeof(http_connect_handshaker));
119 memset(handshaker, 0, sizeof(*handshaker));
120 grpc_handshaker_init(http_connect_handshaker_vtable, &handshaker->base);
121 return (grpc_handshaker*)handshaker;
122}