1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_C_H_ 6 #define COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_C_H_ 7 8 #if defined(WIN32) 9 #define GRPC_SUPPORT_EXPORT 10 #else 11 #define GRPC_SUPPORT_EXPORT __attribute__((visibility("default"))) 12 #endif 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 #include <stddef.h> 19 20 /* Engine API. */ 21 22 /* Opaque object representing a Bidirectional stream creating engine. Created 23 * and configured outside of this API to facilitate sharing with other 24 * components */ 25 typedef struct stream_engine { 26 void* obj; 27 void* annotation; 28 } stream_engine; 29 30 /* Bidirectional Stream API */ 31 32 /* Opaque object representing Bidirectional Stream. */ 33 typedef struct bidirectional_stream { 34 void* obj; 35 void* annotation; 36 } bidirectional_stream; 37 38 /* A single request or response header element. */ 39 typedef struct bidirectional_stream_header { 40 const char* key; 41 const char* value; 42 } bidirectional_stream_header; 43 44 /* Array of request or response headers or trailers. */ 45 typedef struct bidirectional_stream_header_array { 46 size_t count; 47 size_t capacity; 48 bidirectional_stream_header* headers; 49 } bidirectional_stream_header_array; 50 51 /* Set of callbacks used to receive callbacks from bidirectional stream. */ 52 typedef struct bidirectional_stream_callback { 53 /* Invoked when the stream is ready for reading and writing. 54 * Consumer may call bidirectional_stream_read() to start reading data. 55 * Consumer may call bidirectional_stream_write() to start writing 56 * data. 57 */ 58 void (*on_stream_ready)(bidirectional_stream* stream); 59 60 /* Invoked when initial response headers are received. 61 * Consumer must call bidirectional_stream_read() to start reading. 62 * Consumer may call bidirectional_stream_write() to start writing or 63 * close the stream. Contents of |headers| is valid for duration of the call. 64 */ 65 void (*on_response_headers_received)( 66 bidirectional_stream* stream, 67 const bidirectional_stream_header_array* headers, 68 const char* negotiated_protocol); 69 70 /* Invoked when data is read into the buffer passed to 71 * bidirectional_stream_read(). Only part of the buffer may be 72 * populated. To continue reading, call bidirectional_stream_read(). 73 * It may be invoked after on_response_trailers_received()}, if there was 74 * pending read data before trailers were received. 75 * 76 * If |bytes_read| is 0, it means the remote side has signaled that it will 77 * send no more data; future calls to bidirectional_stream_read() 78 * will result in the on_data_read() callback or on_succeded() callback if 79 * bidirectional_stream_write() was invoked with end_of_stream set to 80 * true. 81 */ 82 void (*on_read_completed)(bidirectional_stream* stream, 83 char* data, 84 int bytes_read); 85 86 /** 87 * Invoked when all data passed to bidirectional_stream_write() is 88 * sent. To continue writing, call bidirectional_stream_write(). 89 */ 90 void (*on_write_completed)(bidirectional_stream* stream, const char* data); 91 92 /* Invoked when trailers are received before closing the stream. Only invoked 93 * when server sends trailers, which it may not. May be invoked while there is 94 * read data remaining in local buffer. Contents of |trailers| is valid for 95 * duration of the call. 96 */ 97 void (*on_response_trailers_received)( 98 bidirectional_stream* stream, 99 const bidirectional_stream_header_array* trailers); 100 101 /** 102 * Invoked when there is no data to be read or written and the stream is 103 * closed successfully remotely and locally. Once invoked, no further callback 104 * methods will be invoked. 105 */ 106 void (*on_succeded)(bidirectional_stream* stream); 107 108 /** 109 * Invoked if the stream failed for any reason after 110 * bidirectional_stream_start(). HTTP/2 error codes are 111 * mapped to chrome net error codes. Once invoked, no further callback methods 112 * will be invoked. 113 */ 114 void (*on_failed)(bidirectional_stream* stream, int net_error); 115 116 /** 117 * Invoked if the stream was canceled via 118 * bidirectional_stream_cancel(). Once invoked, no further callback 119 * methods will be invoked. 120 */ 121 void (*on_canceled)(bidirectional_stream* stream); 122 } bidirectional_stream_callback; 123 124 /* Creates a new stream object that uses |engine| and |callback|. All stream 125 * tasks are performed asynchronously on the |engine| network thread. |callback| 126 * methods are invoked synchronously on the |engine| network thread, but must 127 * not run tasks on the current thread to prevent blocking networking operations 128 * and causing exceptions during shutdown. The |annotation| is stored in 129 * bidirectional stream for arbitrary use by application. 130 * 131 * Returned |bidirectional_stream*| is owned by the caller, and must be 132 * destroyed using |bidirectional_stream_destroy|. 133 * 134 * Both |calback| and |engine| must remain valid until stream is destroyed. 135 */ 136 GRPC_SUPPORT_EXPORT 137 bidirectional_stream* bidirectional_stream_create( 138 stream_engine* engine, 139 void* annotation, 140 bidirectional_stream_callback* callback); 141 142 /* TBD: The following methods return int. Should it be a custom type? */ 143 144 /* Destroys stream object. Destroy could be called from any thread, including 145 * network thread, but is posted, so |stream| is valid until calling task is 146 * complete. 147 */ 148 GRPC_SUPPORT_EXPORT 149 int bidirectional_stream_destroy(bidirectional_stream* stream); 150 151 /** 152 * Disables or enables auto flush. By default, data is flushed after 153 * every bidirectional_stream_write(). If the auto flush is disabled, 154 * the client should explicitly call bidirectional_stream_flush to flush 155 * the data. 156 */ 157 GRPC_SUPPORT_EXPORT void bidirectional_stream_disable_auto_flush( 158 bidirectional_stream* stream, 159 bool disable_auto_flush); 160 161 /** 162 * Delays sending request headers until bidirectional_stream_flush() 163 * is called. This flag is currently only respected when QUIC is negotiated. 164 * When true, QUIC will send request header frame along with data frame(s) 165 * as a single packet when possible. 166 */ 167 GRPC_SUPPORT_EXPORT 168 void bidirectional_stream_delay_request_headers_until_flush( 169 bidirectional_stream* stream, 170 bool delay_headers_until_flush); 171 172 /* Starts the stream by sending request to |url| using |method| and |headers|. 173 * If |end_of_stream| is true, then no data is expected to be written. The 174 * |method| is HTTP verb, with PUT having a special meaning to mark idempotent 175 * request, which could use QUIC 0-RTT. 176 */ 177 GRPC_SUPPORT_EXPORT 178 int bidirectional_stream_start(bidirectional_stream* stream, 179 const char* url, 180 int priority, 181 const char* method, 182 const bidirectional_stream_header_array* headers, 183 bool end_of_stream); 184 185 /* Reads response data into |buffer| of |capacity| length. Must only be called 186 * at most once in response to each invocation of the 187 * on_stream_ready()/on_response_headers_received() and on_read_completed() 188 * methods of the bidirectional_stream_callback. 189 * Each call will result in an invocation of the callback's 190 * on_read_completed() method if data is read, or its on_failed() method if 191 * there's an error. The callback's on_succeeded() method is also invoked if 192 * there is no more data to read and |end_of_stream| was previously sent. 193 */ 194 GRPC_SUPPORT_EXPORT 195 int bidirectional_stream_read(bidirectional_stream* stream, 196 char* buffer, 197 int capacity); 198 199 /* Writes request data from |buffer| of |buffer_length| length. If auto flush is 200 * disabled, data will be sent only after bidirectional_stream_flush() is 201 * called. 202 * Each call will result in an invocation the callback's on_write_completed() 203 * method if data is sent, or its on_failed() method if there's an error. 204 * The callback's on_succeeded() method is also invoked if |end_of_stream| is 205 * set and all response data has been read. 206 */ 207 GRPC_SUPPORT_EXPORT 208 int bidirectional_stream_write(bidirectional_stream* stream, 209 const char* buffer, 210 int buffer_length, 211 bool end_of_stream); 212 213 /** 214 * Flushes pending writes. This method should not be called before invocation of 215 * on_stream_ready() method of the bidirectional_stream_callback. 216 * For each previously called bidirectional_stream_write() 217 * a corresponding on_write_completed() callback will be invoked when the buffer 218 * is sent. 219 */ 220 GRPC_SUPPORT_EXPORT 221 void bidirectional_stream_flush(bidirectional_stream* stream); 222 223 /* Cancels the stream. Can be called at any time after 224 * bidirectional_stream_start(). The on_canceled() method of 225 * bidirectional_stream_callback will be invoked when cancelation 226 * is complete and no further callback methods will be invoked. If the 227 * stream has completed or has not started, calling 228 * bidirectional_stream_cancel() has no effect and on_canceled() will not 229 * be invoked. At most one callback method may be invoked after 230 * bidirectional_stream_cancel() has completed. 231 */ 232 GRPC_SUPPORT_EXPORT 233 void bidirectional_stream_cancel(bidirectional_stream* stream); 234 235 /* Returns true if the |stream| was successfully started and is now done 236 * (succeeded, canceled, or failed). 237 * Returns false if the |stream| stream is not yet started or is in progress. 238 */ 239 GRPC_SUPPORT_EXPORT 240 bool bidirectional_stream_is_done(bidirectional_stream* stream); 241 242 #ifdef __cplusplus 243 } 244 #endif 245 246 #endif // COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_H_ 247