spdylay.h 31.1 KB
Newer Older
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Spdylay - SPDY Library
 *
 * Copyright (c) 2012 Tatsuhiro Tsujikawa
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#ifndef SPDYLAY_H
#define SPDYLAY_H

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
28 29 30 31
#ifdef  __cplusplus
extern "C" {
#endif

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
32
#include <stdlib.h>
33
#include <stdint.h>
Jim Morrison's avatar
Jim Morrison committed
34
#include <sys/types.h>
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
35

36 37
#include <spdylay/spdylayver.h>

38 39 40
struct spdylay_session;
typedef struct spdylay_session spdylay_session;

41
/* SPDY protocol version 2 */
42 43 44
#define SPDYLAY_PROTO_SPDY2 2
/* SPDY protocol version 3 */
#define SPDYLAY_PROTO_SPDY3 3
45

46
typedef enum {
47
  /* Invalid argument passed. */
48
  SPDYLAY_ERR_INVALID_ARGUMENT = -501,
49
  /* Zlib error. */
50
  SPDYLAY_ERR_ZLIB = -502,
51
  /* The specified protocol version is not supported. */
52
  SPDYLAY_ERR_UNSUPPORTED_VERSION = -503,
53 54 55
  /* Used as a return value from spdylay_send_callback and
     spdylay_recv_callback to indicate that the operation would
     block. */
56
  SPDYLAY_ERR_WOULDBLOCK = -504,
57
  /* General protocol error */
58
  SPDYLAY_ERR_PROTO = -505,
59
  /* The frame is invalid. */
60
  SPDYLAY_ERR_INVALID_FRAME = -506,
61
  /* The peer performed a shutdown on the connection. */
62
  SPDYLAY_ERR_EOF = -507,
63 64 65
  /* Used as a return value from spdylay_data_source_read_callback to
     indicate that data transfer is postponed. See
     spdylay_data_source_read_callback for details. */
66
  SPDYLAY_ERR_DEFERRED = -508,
67 68
  /* Stream ID has reached maximum value. Therefore no stream ID is
     available. */
69
  SPDYLAY_ERR_STREAM_ID_NOT_AVAILABLE = -509,
70 71 72 73
  /* The stream is already closed or it does not exist. */
  SPDYLAY_ERR_STREAM_CLOSED = -510,
  /* RST_STREAM has been queued in outbound queue. The stream is in
     closing state. */
74
  SPDYLAY_ERR_STREAM_CLOSING = -511,
75 76
  /* The transmission is not allowed for this stream (e.g., a frame
     with FIN flag set has already sent) */
77
  SPDYLAY_ERR_STREAM_SHUT_WR = -512,
78
  /* The stream ID is invalid. */
79
  SPDYLAY_ERR_INVALID_STREAM_ID = -513,
80 81
  /* The state of the stream is not valid (e.g., SYN_REPLY cannot be
     sent to the stream where SYN_REPLY has been already sent). */
82
  SPDYLAY_ERR_INVALID_STREAM_STATE = -514,
83
  /* Another DATA frame has already been deferred. */
84
  SPDYLAY_ERR_DEFERRED_DATA_EXIST = -515,
85 86
  /* SYN_STREAM is not allowed. (e.g., GOAWAY has been sent and/or
     received. */
87
  SPDYLAY_ERR_SYN_STREAM_NOT_ALLOWED = -516,
88
  /* GOAWAY has been already sent. */
89
  SPDYLAY_ERR_GOAWAY_ALREADY_SENT = -517,
90 91 92 93
  /* The errors < SPDYLAY_ERR_FATAL mean that the library is under
     unexpected condition that it cannot process any further data
     reliably (e.g., out of memory). */
  SPDYLAY_ERR_FATAL = -900,
94
  /* Out of memory. */
95
  SPDYLAY_ERR_NOMEM = -901,
96
  /* The user callback function failed. */
97
  SPDYLAY_ERR_CALLBACK_FAILURE = -902,
98 99 100 101 102 103
} spdylay_error;

typedef enum {
  SPDYLAY_MSG_MORE
} spdylay_io_flag;

104 105 106 107 108 109 110 111
typedef enum {
  SPDYLAY_SYN_STREAM = 1,
  SPDYLAY_SYN_REPLY = 2,
  SPDYLAY_RST_STREAM = 3,
  SPDYLAY_SETTINGS = 4,
  SPDYLAY_NOOP = 5,
  SPDYLAY_PING = 6,
  SPDYLAY_GOAWAY = 7,
112
  SPDYLAY_HEADERS = 8,
113 114
  /* Since SPDY/3 */
  SPDYLAY_WINDOW_UPDATE = 9,
115
  SPDYLAY_DATA = 100,
116 117 118
} spdylay_frame_type;

typedef enum {
119 120 121 122 123 124 125 126 127
  SPDYLAY_CTRL_FLAG_NONE = 0,
  SPDYLAY_CTRL_FLAG_FIN = 0x1,
  SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL = 0x2
} spdylay_ctrl_flag;

typedef enum {
  SPDYLAY_DATA_FLAG_NONE = 0,
  SPDYLAY_DATA_FLAG_FIN = 0x1
} spdylay_data_flag;
128

129 130
typedef enum {
  SPDYLAY_FLAG_SETTINGS_NONE = 0,
131
  SPDYLAY_FLAG_SETTINGS_CLEAR_SETTINGS = 1
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
} spdylay_settings_flag;

typedef enum {
  SPDYLAY_ID_FLAG_SETTINGS_NONE = 0,
  SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE = 1,
  SPDYLAY_ID_FLAG_SETTINGS_PERSISTED = 2
} spdylay_settings_id_flag;

typedef enum {
  SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH = 1,
  SPDYLAY_SETTINGS_DOWNLOAD_BANDWIDTH = 2,
  SPDYLAY_SETTINGS_ROUND_TRIP_TIME = 3,
  SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS = 4,
  SPDYLAY_SETTINGS_CURRENT_CWND = 5,
  SPDYLAY_SETTINGS_DOWNLOAD_RETRANS_RATE = 6,
147 148 149
  SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE = 7,
  /* This first appeared in SPDY/3 */
  SPDYLAY_SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8
150 151
} spdylay_settings_id;

152
/* Maximum ID of spdylay_settings_id. */
153
#define SPDYLAY_SETTINGS_MAX 8
154 155

/* Default maximum concurrent streams */
156
#define SPDYLAY_INITIAL_MAX_CONCURRENT_STREAMS 100
157

158
/* Status code for RST_STREAM */
159
typedef enum {
160 161
  /* SPDYLAY_OK is not valid status code for RST_STREAM. It is defined
     just for spdylay library use. */
162
  SPDYLAY_OK = 0,
163 164 165 166 167 168
  SPDYLAY_PROTOCOL_ERROR = 1,
  SPDYLAY_INVALID_STREAM = 2,
  SPDYLAY_REFUSED_STREAM = 3,
  SPDYLAY_UNSUPPORTED_VERSION = 4,
  SPDYLAY_CANCEL = 5,
  SPDYLAY_INTERNAL_ERROR = 6,
169 170 171 172 173 174
  SPDYLAY_FLOW_CONTROL_ERROR = 7,
  /* Following status codes were introduced in SPDY/3 */
  SPDYLAY_STREAM_IN_USE = 8,
  SPDYLAY_STREAM_ALREADY_CLOSED = 9,
  SPDYLAY_INVALID_CREDENTIALS = 10,
  FRAME_TOO_LARGE = 11
175 176
} spdylay_status_code;

177 178 179 180 181 182 183
/* Status code for GOAWAY, introduced in SPDY/3 */
typedef enum {
  SPDYLAY_GOAWAY_OK = 0,
  SPDYLAY_GOAWAY_PROTOCOL_ERROR = 1,
  SPDYLAY_GOAWAY_INTERNAL_ERROR = 11
} spdylay_goaway_status_code;

184 185
#define SPDYLAY_SPDY2_PRI_LOWEST 3
#define SPDYLAY_SPDY3_PRI_LOWEST 7
186

187 188 189 190 191 192 193 194 195 196 197
typedef struct {
  uint16_t version;
  uint16_t type;
  uint8_t flags;
  int32_t length;
} spdylay_ctrl_hd;

typedef struct {
  spdylay_ctrl_hd hd;
  int32_t stream_id;
  int32_t assoc_stream_id;
198 199
  /* 0 (Highest) to SPDYLAY_SPDY2_PRI_LOWEST or
     SPDYLAY_SPDY3_PRI_LOWEST (loweset), depending on the protocol
200
     version. */
201
  uint8_t pri;
202
  /* Since SPDY/3 */
203
  uint8_t slot;
204 205 206 207 208 209 210 211 212
  char **nv;
} spdylay_syn_stream;

typedef struct {
  spdylay_ctrl_hd hd;
  int32_t stream_id;
  char **nv;
} spdylay_syn_reply;

213 214 215 216 217 218
typedef struct {
  spdylay_ctrl_hd hd;
  int32_t stream_id;
  char **nv;
} spdylay_headers;

219 220 221 222 223 224
typedef struct {
  spdylay_ctrl_hd hd;
  int32_t stream_id;
  uint32_t status_code;
} spdylay_rst_stream;

225 226 227 228 229 230 231 232 233 234 235 236 237
typedef struct {
  int32_t settings_id;
  uint8_t flags;
  uint32_t value;
} spdylay_settings_entry;

typedef struct {
  spdylay_ctrl_hd hd;
  /* Number of entries in |iv| */
  size_t niv;
  spdylay_settings_entry *iv;
} spdylay_settings;

238 239 240 241 242
typedef struct {
  spdylay_ctrl_hd hd;
  uint32_t unique_id;
} spdylay_ping;

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
243 244 245
typedef struct {
  spdylay_ctrl_hd hd;
  int32_t last_good_stream_id;
246
  /* Since SPDY/3 */
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
247 248 249
  uint32_t status_code;
} spdylay_goaway;

250 251 252 253 254 255 256
/* WINDOW_UPDATE is introduced since SPDY/3 */
typedef struct {
  spdylay_ctrl_hd hd;
  int32_t stream_id;
  int32_t delta_window_size;
} spdylay_window_update;

257 258 259 260 261
typedef union {
  int fd;
  void *ptr;
} spdylay_data_source;

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
262 263
/*
 * Callback function invoked when the library wants to read data from
264 265 266 267 268 269 270 271 272 273 274 275
 * |source|. The read data is sent in the stream |stream_id|. The
 * implementation of this function must read at most |length| bytes of
 * data from |source| (or possibly other places) and store them in
 * |buf| and return number of data stored in |buf|. If EOF is reached,
 * set |*eof| to 1.  If the application wants to postpone DATA frames,
 * (e.g., asynchronous I/O, or reading data blocks for long time), it
 * is achieved by returning SPDYLAY_ERR_DEFERRED without reading any
 * data in this invocation.  The library removes DATA frame from
 * outgoing queue temporarily.  To move back deferred DATA frame to
 * outgoing queue, call spdylay_session_resume_data().  In case of
 * error, return SPDYLAY_ERR_CALLBACK_FAILURE, which leads to session
 * failure.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
276
 */
277
typedef ssize_t (*spdylay_data_source_read_callback)
278 279
(spdylay_session *session, int32_t stream_id,
 uint8_t *buf, size_t length, int *eof,
280 281 282 283 284 285 286 287 288 289
 spdylay_data_source *source, void *user_data);

typedef struct {
  spdylay_data_source source;
  spdylay_data_source_read_callback read_callback;
} spdylay_data_provider;

typedef struct {
  int32_t stream_id;
  uint8_t flags;
290 291
  /* Initially eof is 0. It becomes 1 if all data are read. */
  uint8_t eof;
292 293 294
  spdylay_data_provider data_prd;
} spdylay_data;

295 296 297 298
typedef union {
  spdylay_syn_stream syn_stream;
  spdylay_syn_reply syn_reply;
  spdylay_rst_stream rst_stream;
299
  spdylay_settings settings;
300
  spdylay_ping ping;
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
301
  spdylay_goaway goaway;
302
  spdylay_headers headers;
303 304
  /* Since SPDY/3 */
  spdylay_window_update window_update;
305
  spdylay_data data;
306 307
} spdylay_frame;

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
308 309 310 311 312 313 314 315
/*
 * Callback function invoked when |session| want to send data to
 * remote peer. The implementation of this function must send at most
 * |length| bytes of data stored in |data|. It must return the number
 * of bytes sent if it succeeds.  If it cannot send any single byte
 * without blocking, it must return SPDYLAY_ERR_WOULDBLOCK. For other
 * errors, it must return SPDYLAY_ERR_CALLBACK_FAILURE.
 */
316
typedef ssize_t (*spdylay_send_callback)
317 318
(spdylay_session *session,
 const uint8_t *data, size_t length, int flags, void *user_data);
319

320
/*
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
321
 * Callback function invoked when |session| want to receive data from
322 323
 * remote peer. The implementation of this function must read at most
 * |length| bytes of data and store it in |buf|. It must return the
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
324 325 326 327 328
 * number of bytes written in |buf| if it succeeds. If it cannot read
 * any single byte without blocking, it must return
 * SPDYLAY_ERR_WOULDBLOCK. If it gets EOF before it reads any single
 * byte, it must return SPDYLAY_ERR_EOF. For other errors, it must
 * return SPDYLAY_ERR_CALLBACK_FAILURE.
329
 */
330
typedef ssize_t (*spdylay_recv_callback)
331 332
(spdylay_session *session,
 uint8_t *buf, size_t length, int flags, void *user_data);
333

334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
/*
 * Callback function invoked by spdylay_session_recv() when a control
 * frame is arrived.
 */
typedef void (*spdylay_on_ctrl_recv_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
 void *user_data);

/*
 * Callback function invoked by spdylay_session_recv() when an invalid
 * control frame is arrived, which typically the case where RST_STREAM
 * will be sent
 */
typedef void (*spdylay_on_invalid_ctrl_recv_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
 void *user_data);

351 352 353 354
/*
 * Callback function invoked when data chunk of DATA frame is
 * received. |stream_id| is the stream ID of this DATA frame belongs
 * to. |flags| is the flags of DATA frame which this data chunk is
355 356 357
 * contained. flags & SPDYLAY_DATA_FLAG_FIN does not necessarily mean
 * this chunk of data is the last one in the stream. You should use
 * spdylay_on_data_recv_callback to know all data frames are received.
358 359
 */
typedef void (*spdylay_on_data_chunk_recv_callback)
360
(spdylay_session *session, uint8_t flags, int32_t stream_id,
361 362 363 364 365 366 367
 const uint8_t *data, size_t len, void *user_data);

/*
 * Callback function invoked when DATA frame is received. The actual
 * data it contains are received by spdylay_on_data_recv_callback.
 */
typedef void (*spdylay_on_data_recv_callback)
368
(spdylay_session *session, uint8_t flags, int32_t stream_id, int32_t length,
369 370
 void *user_data);

371 372 373 374 375 376 377 378
/*
 * Callback function invoked after frame |frame| of type |type| is
 * sent.
 */
typedef void (*spdylay_on_ctrl_send_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
 void *user_data);

379 380 381 382 383 384 385 386 387
/*
 * Callback function invoked after the control frame |frame| of type
 * |type| is not sent because of the error. The error is indicated by
 * the |error|, which is one of the values defined in spdylay_error.
 */
typedef void (*spdylay_on_ctrl_not_send_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
 int error, void *user_data);

388 389 390 391 392 393 394
/*
 * Callback function invoked after DATA frame is sent.
 */
typedef void (*spdylay_on_data_send_callback)
(spdylay_session *session, uint8_t flags, int32_t stream_id, int32_t length,
 void *user_data);

395 396 397
/*
 * Callback function invoked before frame |frame| of type |type| is
 * sent. This may be useful, for example, to know the stream ID of
398 399
 * SYN_STREAM frame (see also spdylay_session_get_stream_user_data),
 * which is not assigned when it was queued.
400 401 402 403 404
 */
typedef void (*spdylay_before_ctrl_send_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
 void *user_data);

405 406
/*
 * Callback function invoked when stream |stream_id| is closed. The
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
407 408
 * reason of closure is indicated by |status_code|. stream_user_data
 * is still available in this function.
409 410 411 412 413
 */
typedef void (*spdylay_on_stream_close_callback)
(spdylay_session *session, int32_t stream_id, spdylay_status_code status_code,
 void *user_data);

414 415 416 417 418 419 420 421 422
/*
 * Callback function invoked when request from remote peer is
 * received.  In other words, frame with FIN flag set is received.  In
 * HTTP, this means HTTP request, including request body, is fully
 * received.
 */
typedef void (*spdylay_on_request_recv_callback)
(spdylay_session *session, int32_t stream_id, void *user_data);

423 424 425
typedef struct {
  spdylay_send_callback send_callback;
  spdylay_recv_callback recv_callback;
426 427
  spdylay_on_ctrl_recv_callback on_ctrl_recv_callback;
  spdylay_on_invalid_ctrl_recv_callback on_invalid_ctrl_recv_callback;
428 429
  spdylay_on_data_chunk_recv_callback on_data_chunk_recv_callback;
  spdylay_on_data_recv_callback on_data_recv_callback;
430
  spdylay_before_ctrl_send_callback before_ctrl_send_callback;
431
  spdylay_on_ctrl_send_callback on_ctrl_send_callback;
432
  spdylay_on_ctrl_not_send_callback on_ctrl_not_send_callback;
433
  spdylay_on_data_send_callback on_data_send_callback;
434
  spdylay_on_stream_close_callback on_stream_close_callback;
435
  spdylay_on_request_recv_callback on_request_recv_callback;
436 437
} spdylay_session_callbacks;

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
438
/*
439 440 441 442 443
 * Initializes |*session_ptr| for client use, using the protocol
 * version |version|. The all members of |callbacks| are copied to
 * |*session_ptr|. Therefore |*session_ptr| does not store
 * |callbacks|. |user_data| is an arbitrary user supplied data, which
 * will be passed to the callback functions.
444 445 446 447 448 449
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
450 451 452 453
 * SPDYLAY_ERR_ZLIB
 *     The z_stream initialization failed.
 * SPDYLAY_ERR_UNSUPPORTED_VERSION
 *     The version is not supported.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
454
 */
455
int spdylay_session_client_new(spdylay_session **session_ptr,
456
                               uint16_t version,
457
                               const spdylay_session_callbacks *callbacks,
458 459 460
                               void *user_data);

/*
461 462 463 464 465
 * Initializes |*session_ptr| for server use, using the protocol
 * version |version|. The all members of |callbacks| are copied to
 * |*session_ptr|. Therefore |*session_ptr| does not store
 * |callbacks|. |user_data| is an arbitrary user supplied data, which
 * will be passed to the callback functions.
466 467 468 469 470 471
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
472 473 474 475
 * SPDYLAY_ERR_ZLIB
 *     The z_stream initialization failed.
 * SPDYLAY_ERR_UNSUPPORTED_VERSION
 *     The version is not supported.
476 477
 */
int spdylay_session_server_new(spdylay_session **session_ptr,
478
                               uint16_t version,
479
                               const spdylay_session_callbacks *callbacks,
480
                               void *user_data);
481

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
482 483 484
/*
 * Frees any resources allocated for |session|.
 */
485
void spdylay_session_del(spdylay_session *session);
486

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
487
/*
488 489
 * Sends pending frames to the remote peer.
 *
490 491 492 493 494 495 496 497 498 499
 * This function retrieves the highest prioritized frame from the
 * outbound queue and sends it to the remote peer. It does this as
 * many as possible until the user callback send_callback returns
 * SPDYLAY_ERR_WOULDBLOCK or the outbound queue becomes empty.  This
 * function calls several callback functions which are passed when
 * initializing the |session|. Here is the simple time chart which
 * tells when each callback is invoked:
 *
 * 1. Get the next frame to send from outbound queue.
 * 2. Prepare transmission of the frame.
500 501 502 503 504 505
 * 3. If the control frame cannot be sent because some preconditions
 *    are not met (e.g., SYN_STREAM cannot be sent after GOAWAY),
 *    on_ctrl_not_send_callback is invoked. Skip following steps.
 * 4. If the frame is SYN_STREAM, the stream is opened here.
 * 5. before_ctrl_send_callback is invoked.
 * 6. send_callback is invoked one or more times (while the frame is
506
 *    completely sent).
507 508 509
 * 7. If the frame is a control frame, on_ctrl_send_callback is invoked.
 * 8. If the frame is a DATA frame, on_data_send_callback is invoked.
 * 9. If the transmission of the frame triggers closure of the stream,
510 511
 *    the stream is closed and on_stream_close_callback is invoked.
 *
512 513 514 515 516 517 518
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 * SPDYLAY_ERR_CALLBACK_FAILURE
 *     The callback function failed.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
519
 */
520 521
int spdylay_session_send(spdylay_session *session);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
522
/*
523 524
 * Receives frames from the remote peer.
 *
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
 * This function receives as many frames as possible until the user
 * callback recv_callback returns SPDYLAY_ERR_WOULDBLOCK. This
 * function calls several callback functions which are passed when
 * initializing the |session|. Here is the simple time chart which
 * tells when each callback is invoked:
 *
 * 1. recv_callback is invoked one or more times to receive frame header.
 * 2. If the frame is DATA frame:
 *   2.1. recv_callback is invoked to receive DATA payload. For each
 *        chunk of data, on_data_chunk_recv_callback is invoked.
 *   2.2. If one DATA frame is completely received, on_data_recv_callback
 *        is invoked.
 *        If the frame is the final frame of the request,
 *        on_request_recv_callback is invoked.
 *        If the reception of the frame triggers the closure of the stream,
 *        on_stream_close_callback is invoked.
 * 3. If the frame is the control frame:
 *   3.1. recv_callback is invoked one or more times to receive whole frame.
 *   3.2. If the received frame is valid, on_ctrl_recv_callback is invoked.
 *        If the frame is the final frame of the request,
 *        on_request_recv_callback is invoked.
 *        If the reception of the frame triggers the closure of the stream,
 *        on_stream_close_callback is invoked.
 *   3.3. If the received frame is unpacked but is interpreted as invalid,
 *        on_invalid_ctrl_recv_callback is invoked.
 *
551 552 553 554 555 556 557 558 559
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_EOF
 *     The remote peer did shutdown on the connection.
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 * SPDYLAY_ERR_CALLBACK_FAILURE
 *     The callback function failed.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
560
 */
561 562
int spdylay_session_recv(spdylay_session *session);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
563 564 565 566 567 568 569 570 571 572 573 574 575 576
/*
 * Put back previously deferred DATA frame in the stream |stream_id|
 * to outbound queue.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_INVALID_ARGUMENT
 *     The stream does not exist or no deferred data exist.
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 */
int spdylay_session_resume_data(spdylay_session *session, int32_t stream_id);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
577
/*
578 579
 * Returns nonzero value if |session| want to receive data from the
 * remote peer.
580
 *
581
 * If both spdylay_session_want_read() and
582 583
 * spdylay_session_want_write() return 0, the application should drop
 * the connection.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
584
 */
585 586
int spdylay_session_want_read(spdylay_session *session);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
587
/*
588
 * Returns nonzero value if |session| want to send data to the remote
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
589
 * peer, or 0.
590
 *
591
 * If both spdylay_session_want_read() and
592 593
 * spdylay_session_want_write() return 0, the application should drop
 * the connection.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
594
 */
595 596
int spdylay_session_want_write(spdylay_session *session);

597 598 599 600 601 602 603 604 605 606 607 608
/*
 * Returns stream_user_data for the stream |stream_id|. The
 * stream_user_data is provided by spdylay_submit_request().  If the
 * stream is initiated by the remote endpoint, stream_user_data is
 * always NULL. If the stream is initiated by the local endpoint and
 * NULL is given in spdylay_submit_request(), then this function
 * returns NULL. If the stream does not exist, this function returns
 * NULL.
 */
void* spdylay_session_get_stream_user_data(spdylay_session *session,
                                           int32_t stream_id);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
609
/*
610
 * Submits SYN_STREAM frame and optionally one or more DATA
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
611
 * frames.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
612
 *
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
613 614 615 616
 * |pri| is priority of this request. 0 is the highest priority.  If
 * the |session| is initialized with the version SPDYLAY_PROTO_SPDY2,
 * the lowest priority is 3.  If the |session| is initialized with the
 * version SPDYLAY_PROTO_SPDY3, the lowest priority is 7.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
617
 *
618
 * The |nv| must include following name/value pairs:
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632
 *
 * ":method"
 *     HTTP method (e.g., "GET", "POST", "HEAD", etc)
 * ":scheme"
 *     URI scheme (e.g., "https")
 * ":path"
 *     Absolute path and parameters of this request (e.g., "/foo",
 *     "/foo;bar;haz?h=j&y=123")
 * ":version"
 *     HTTP version (e.g., "HTTP/1.1")
 * ":host"
 *     The hostport portion of the URI for this request (e.g.,
 *     "example.org:443"). This is the same as the HTTP "Host" header
 *     field.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
633
 *
634 635 636 637
 * If the |session| is initialized with the version
 * SPDYLAY_PROTO_SPDY2, the above names are translated to "method",
 * "scheme", "url", "version" and "host" respectively.
 *
638 639
 * This function creates copies of all name/value pairs in |nv|.  It
 * also lower-cases all names in |nv|.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
640
 *
641
 * If |data_prd| is not NULL, it provides data which will be sent in
642
 * subsequent DATA frames. In this case, a method that allows request
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
643 644 645
 * message bodies
 * (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9) must
 * be specified with "method" key in |nv| (e.g. POST). If |data_prd|
646 647
 * is NULL, SYN_STREAM have FLAG_FIN. The |stream_user_data| is data
 * associated to the stream opened by this request and can be an
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
648
 * arbitrary pointer, which can be retrieved by
649 650 651 652 653 654 655 656 657 658 659 660
 * spdylay_session_get_stream_user_data().
 *
 * Since the library reorders the frames and tries to send the highest
 * prioritized one first and the SPDY specification requires the
 * stream ID must be strictly increasing, the stream ID of this
 * request cannot be known until it is about to sent.  To know the
 * stream ID of the request, the application can use
 * before_ctrl_send_callback. This callback is called just before the
 * frame is sent. For SYN_STREAM frame, the argument frame has stream
 * ID assigned. Also since the stream is already opened,
 * spdylay_session_get_stream_user_data() can be used to get
 * |stream_user_data| to identify which SYN_STREAM we are processing.
661
 *
662 663 664
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
665
 * SPDYLAY_ERR_INVALID_ARGUMENT
666 667 668
 *     |pri| is invalid.
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
669
 */
670
int spdylay_submit_request(spdylay_session *session, uint8_t pri,
671
                           const char **nv,
672
                           const spdylay_data_provider *data_prd,
673
                           void *stream_user_data);
674

675
/*
676
 * Submits SYN_REPLY frame and optionally one or more DATA frames
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
677 678
 * against stream |stream_id|.
 *
679
 * The |nv| must include following name/value pairs:
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
680
 *
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
681 682 683 684
 * ":status"
 *     HTTP status code (e.g., "200" or "200 OK")
 * ":version"
 *     HTTP response version (e.g., "HTTP/1.1")
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
685
 *
686 687 688 689
 * If the |session| is initialized with the version
 * SPDYLAY_PROTO_SPDY2, the above names are translated to "status" and
 * "version" respectively.
 *
690 691 692 693
 * This function creates copies of all name/value pairs in |nv|.  It
 * also lower-cases all names in |nv|.
 *
 * If |data_prd| is not NULL, it provides data which will be sent in
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
694 695 696
 * subsequent DATA frames. If |data_prd| is NULL, SYN_REPLY will have
 * FLAG_FIN.
 *
697 698 699 700 701
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
702
 */
703 704
int spdylay_submit_response(spdylay_session *session,
                            int32_t stream_id, const char **nv,
705
                            const spdylay_data_provider *data_prd);
706

707 708 709 710
/*
 * Submits SYN_STREAM frame. The |flags| is bitwise OR of the
 * following values:
 *
711 712
 * SPDYLAY_CTRL_FLAG_FIN
 * SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL
713
 *
714 715
 * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag
 * set.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
716
 *
717 718 719 720 721 722 723 724 725 726 727 728 729 730
 * The |assoc_stream_id| is used for server-push. If |session| is
 * initialized for client use, |assoc_stream_id| is ignored. The |pri|
 * is the priority of this frame and it must be between 0 and 3,
 * inclusive. 0 is the highest. The |nv| is the name/value pairs in
 * this frame. The |stream_user_data| is a pointer to an arbitrary
 * data which is associated to the stream this frame will open.
 *
 * This function is low-level in a sense that the application code can
 * specify flags and assoc-stream-ID directly. For usual HTTP request,
 * spdylay_submit_request() is useful.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
731
 * SPDYLAY_ERR_INVALID_ARGUMENT
732 733 734 735 736
 *     |pri| is invalid.
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 */
int spdylay_submit_syn_stream(spdylay_session *session, uint8_t flags,
737
                              int32_t assoc_stream_id, uint8_t pri,
738 739
                              const char **nv, void *stream_user_data);

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
/*
 * Submits SYN_REPLY frame. The |flags| is bitwise OR of the following
 * values:
 *
 * SPDYLAY_CTRL_FLAG_FIN
 *
 * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag
 * set.
 *
 * The stream this frame belongs to is given in |stream_id|. The |nv|
 * is the name/value pairs in this frame.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 */
int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
                             int32_t stream_id, const char **nv);

761 762 763 764
/*
 * Submits HEADERS frame. The |flags| is bitwise OR of the following
 * values:
 *
765
 * SPDYLAY_CTRL_FLAG_FIN
766
 *
767 768
 * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag
 * set.
769 770 771 772 773 774 775 776 777 778 779 780 781
 *
 * The stream this frame belongs to is given in |stream_id|. The |nv|
 * is the name/value pairs in this frame.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 */
int spdylay_submit_headers(spdylay_session *session, uint8_t flags,
                           int32_t stream_id, const char **nv);

782 783 784 785
/*
 * Submits 1 or more DATA frames to the stream |stream_id|.  The data
 * to be sent are provided by |data_prd|.  Depending on the length of
 * data, 1 or more DATA frames will be sent.  If |flags| contains
786
 * SPDYLAY_DATA_FLAG_FIN, the last DATA frame has FLAG_FIN set.
787
 *
788 789 790 791 792
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
793 794
 */
int spdylay_submit_data(spdylay_session *session, int32_t stream_id,
795
                        uint8_t flags, const spdylay_data_provider *data_prd);
796

797
/*
798
 * Submits RST_STREAM frame to cancel/reject stream |stream_id| with
799 800 801 802 803 804 805
 * status code |status_code|.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
806
 */
807 808
int spdylay_submit_rst_stream(spdylay_session *session, int32_t stream_id,
                              uint32_t status_code);
809

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
810
/*
811 812 813 814 815 816 817
 * Submits PING frame.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
818
 */
819 820
int spdylay_submit_ping(spdylay_session *session);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
821
/*
822 823
 * Submits GOAWAY frame. The status code |status_code| is ignored if
 * the protocol version is SPDYLAY_PROTO_SPDY2.
824 825 826 827 828 829
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
830
 */
831
int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code);
832

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
/*
 * Stores local settings and submits SETTINGS frame. The |iv| is the
 * pointer to the array of spdylay_settings_entry. The |niv| indicates
 * the number of spdylay_settings_entry. The |flags| is bitwise-OR of
 * one or more values from spdylay_settings_flag.
 *
 * This function returns 0 if it succeeds, or one of the following
 * negative error codes:
 *
 * SPDYLAY_ERR_INVALID_ARGUMENT
 *     The |iv| contains duplicate settings ID or invalid value.
 * SPDYLAY_ERR_NOMEM
 *     Out of memory.
 */
int spdylay_submit_settings(spdylay_session *session, uint8_t flags,
                            const spdylay_settings_entry *iv, size_t niv);

850
/*
851 852 853 854 855 856 857 858 859 860 861 862 863
 * A helper function for dealing with NPN in client side.
 * |in| contains server's protocol in preferable order.
 * The format of |in| is length-prefixed and not null-terminated.
 * For example, "spdy/2" are "http/1.1" stored in |in| like this:
 *
 *  in[0] = 6
 *  in[1..6] = "spdy/2"
 *  in[7] = 8
 *  in[8..15] = "http/1.1"
 *  inlen = 16
 *
 * The selection algorithm is as follows:
 *
864 865 866 867 868
 * 1. If server's list contains SPDY versions the spdylay library
 *    supports, this function selects one of them and returns its SPDY
 *    protocol version which can be used directly with
 *    spdylay_session_client_new() and spdylay_session_server_new()
 *    . The following steps are not taken.
869 870 871 872
 *
 * 2. If server's list contains "http/1.1", this function selects
 *    "http/1.1" and returns 0. The following step is not taken.
 *
873 874 875
 * 3. This function selects nothing and returns -1. (So called
 *    non-overlap case). In this case, |out| and |outlen| are left
 *    untouched.
876 877 878 879 880
 *
 * When spdylay supports updated version of SPDY in the future, this
 * function may select updated protocol and application code which
 * relies on spdylay for SPDY stuff needs not be modified.
 *
881 882 883
 * Selecting "spdy/2" means that "spdy/2" is written into |*out| and
 * length of "spdy/2" (which is 6) is assigned to |*outlen|.
 *
884 885 886
 * See http://technotes.googlecode.com/git/nextprotoneg.html for more
 * details about NPN.
 *
887
 * To use this method you should do something like:
888
 *
889 890 891 892 893
 * static int select_next_proto_cb(SSL* ssl,
 *                                 unsigned char **out, unsigned char *outlen,
 *                                 const unsigned char *in, unsigned int inlen,
 *                                 void *arg)
 * {
894 895 896 897
 *   int version;
 *   version = spdylay_select_next_protocol(out, outlen, in, inlen);
 *   if(version > 0) {
 *     ((MyType*)arg)->spdy_version = version;
898 899 900 901 902 903 904 905 906
 *   }
 *   return SSL_TLSEXT_ERR_OK;
 * }
 * ...
 * SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj);
 */
int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen,
                                 const unsigned char *in, unsigned int inlen);

907 908 909 910 911 912 913 914 915 916
/*
 * Returns spdy version which spdylay library supports from given
 * protocol name. The |proto| is the pointer to the protocol name and
 * |protolen| is its length. Currently, "spdy/2" and "spdy/3" are
 * supported.
 *
 * This function returns nonzero spdy version if it succeeds, or 0.
 */
uint16_t spdylay_npn_get_version(const unsigned char *proto, size_t protolen);

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
917 918 919 920
#ifdef __cplusplus
}
#endif

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
921
#endif /* SPDYLAY_H */