Home | History | Annotate | Download | only in Cronet
      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