blob: 2b71ca60f62367552d15b89dbc3c2f8a3c130a03 [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
Mark D. Roth4623e1c2016-07-18 14:09:18 -070058// Callback invoked for reading HTTP CONNECT response.
59static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
60 grpc_error* error) {
61 http_connect_handshaker* h = arg;
62// FIXME: process response; on failure, figure out how to abort
63
64 // Invoke handshake-done callback.
65 h->cb(exec_ctx, h->endpoint, h->args, h->user_data);
66}
67
68// Callback invoked when finished writing HTTP CONNECT request.
69static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
70 grpc_error* error) {
71 http_connect_handshaker* h = arg;
72 // Read HTTP CONNECT response.
73 gpr_slice_buffer_init(&h->response_buffer);
74 grpc_closure_init(&h->response_read_closure, on_read_done, h);
75 grpc_endpoint_read(exec_ctx, h->endpoint, &h->response_buffer,
76 &h->response_read_closure);
77}
78
Mark D. Roth9136bb12016-07-21 09:52:12 -070079//
80// Public handshaker methods
81//
82
83static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
84 grpc_handshaker* handshaker) {
85 gpr_free(handshaker);
86}
87
88static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
89 grpc_handshaker* handshaker) {
90}
91
92static void http_connect_handshaker_do_handshake(
93 grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker,
94 grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline,
95 grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb,
96 void* user_data) {
Mark D. Roth4623e1c2016-07-18 14:09:18 -070097 http_connect_handshaker* h = (http_connect_handshaker*)handshaker;
98 // Save state in the handshaker object.
99 h->endpoint = endpoint;
100 h->args = args;
101 h->cb = cb;
102 h->user_data = user_data;
103 // Send HTTP CONNECT request.
104 gpr_slice_buffer_init(&h->request_buffer);
105 gpr_slice_buffer_add(&h->request_buffer, "HTTP CONNECT ");
106// FIXME: get server name from somewhere...
107 gpr_slice_buffer_add(&h->request_buffer, WHEE);
108// FIXME: add headers as needed?
109 gpr_slice_buffer_add(&h->request_buffer, "\n\n");
110 grpc_closure_init(&h->request_done_closure, on_write_done, h);
111 grpc_endpoint_write(exec_ctx, endpoint, &h->request_buffer,
112 &h->request_done_closure);
113}
114
115static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = {
116 http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
117 http_connect_handshaker_do_handshake};
118
119grpc_handshaker* grpc_http_connect_handshaker_create() {
120 http_connect_handshaker* handshaker =
121 gpr_malloc(sizeof(http_connect_handshaker));
122 memset(handshaker, 0, sizeof(*handshaker));
123 grpc_handshaker_init(http_connect_handshaker_vtable, &handshaker->base);
124 return (grpc_handshaker*)handshaker;
125}