1/*
2    This file is part of libmicrospdy
3    Copyright Copyright (C) 2012, 2013 Christian Grothoff
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file microspdy.h
21 * @brief public interface to libmicrospdy
22 * @author Andrey Uzunov
23 * @author Christian Grothoff
24 *
25 * All symbols defined in this header start with SPDY_.  libmisrospdy is a small
26 * SPDY daemon library. The application can start multiple daemons
27 * and they are independent.<p>
28 *
29 * The header file defines various constants used by the SPDY and the HTTP protocol.
30 * This does not mean that the lib actually interprets all of these
31 * values. Not everything is implemented. The provided constants are exported as a convenience
32 * for users of the library.  The lib does not verify that provided
33 * HTTP headers and if their values conform to the SPDY protocol,
34 * it only checks if the required headers for the SPDY requests and
35 * responses are provided.<p>
36 *
37 * The library uses just a single thread.<p>
38 *
39 * Before including "microspdy.h" you should add the necessary
40 * includes to define the types used in this file (which headers are needed may
41 * depend on your platform; for possible suggestions consult
42 * "platform.h" in the libmicrospdy distribution).<p>
43 *
44 * All of the functions returning SPDY_YES/SPDY_NO return
45 * SPDY_INPUT_ERROR when any of the parameters are invalid, e.g.
46 * required parameter is NULL.<p>
47 *
48 * The library does not check if anything at the application layer --
49 * requests and responses -- is correct. For example, it
50 * is up to the user to check if a client is sending HTTP body but the
51 * method is GET.<p>
52 *
53 * The SPDY flow control is just partially implemented: the receiving
54 * window is updated, and the client is notified, to prevent a client
55 * from stop sending POST body data, for example.
56 */
57#ifndef SPDY_MICROSPDY_H
58#define SPDY_MICROSPDY_H
59
60#include <zlib.h>
61#include <stdbool.h>
62
63/* While we generally would like users to use a configure-driven
64   build process which detects which headers are present and
65   hence works on any platform, we use "standard" includes here
66   to build out-of-the-box for beginning users on common systems.
67
68   Once you have a proper build system and go for more exotic
69   platforms, you should define MHD_PLATFORM_H in some header that
70   you always include *before* "microhttpd.h".  Then the following
71   "standard" includes won't be used (which might be a good
72   idea, especially on platforms where they do not exist). */
73#ifndef MHD_PLATFORM_H
74#include <unistd.h>
75#include <stdarg.h>
76#include <stdint.h>
77#ifdef __MINGW32__
78#include <ws2tcpip.h>
79#else
80#include <sys/time.h>
81#include <sys/types.h>
82#include <sys/socket.h>
83#endif
84#endif
85
86#ifndef _MHD_EXTERN
87#define _MHD_EXTERN extern
88#endif
89
90/**
91 * return code for "YES".
92 */
93#define SPDY_YES 1
94
95/**
96 * return code for "NO".
97 */
98#define SPDY_NO 0
99
100/**
101 * return code for error when input parameters are wrong. To be returned
102 * only by functions which return int. The others will return NULL on
103 * input error.
104 */
105#define SPDY_INPUT_ERROR -1
106
107/**
108 * SPDY version supported by the lib.
109 */
110#define SPDY_VERSION 3
111
112/**
113 * The maximum allowed size (without 8 byte headers) of
114 * SPDY frames (value length) is 8192. The lib will accept and
115 * send frames with length at most this value here.
116 */
117#define SPDY_MAX_SUPPORTED_FRAME_SIZE 8192
118
119/**
120 * HTTP response codes.
121 */
122#define SPDY_HTTP_CONTINUE 100
123#define SPDY_HTTP_SWITCHING_PROTOCOLS 101
124#define SPDY_HTTP_PROCESSING 102
125
126#define SPDY_HTTP_OK 200
127#define SPDY_HTTP_CREATED 201
128#define SPDY_HTTP_ACCEPTED 202
129#define SPDY_HTTP_NON_AUTHORITATIVE_INFORMATION 203
130#define SPDY_HTTP_NO_CONTENT 204
131#define SPDY_HTTP_RESET_CONTENT 205
132#define SPDY_HTTP_PARTIAL_CONTENT 206
133#define SPDY_HTTP_MULTI_STATUS 207
134
135#define SPDY_HTTP_MULTIPLE_CHOICES 300
136#define SPDY_HTTP_MOVED_PERMANENTLY 301
137#define SPDY_HTTP_FOUND 302
138#define SPDY_HTTP_SEE_OTHER 303
139#define SPDY_HTTP_NOT_MODIFIED 304
140#define SPDY_HTTP_USE_PROXY 305
141#define SPDY_HTTP_SWITCH_PROXY 306
142#define SPDY_HTTP_TEMPORARY_REDIRECT 307
143
144#define SPDY_HTTP_BAD_REQUEST 400
145#define SPDY_HTTP_UNAUTHORIZED 401
146#define SPDY_HTTP_PAYMENT_REQUIRED 402
147#define SPDY_HTTP_FORBIDDEN 403
148#define SPDY_HTTP_NOT_FOUND 404
149#define SPDY_HTTP_METHOD_NOT_ALLOWED 405
150#define SPDY_HTTP_METHOD_NOT_ACCEPTABLE 406
151#define SPDY_HTTP_PROXY_AUTHENTICATION_REQUIRED 407
152#define SPDY_HTTP_REQUEST_TIMEOUT 408
153#define SPDY_HTTP_CONFLICT 409
154#define SPDY_HTTP_GONE 410
155#define SPDY_HTTP_LENGTH_REQUIRED 411
156#define SPDY_HTTP_PRECONDITION_FAILED 412
157#define SPDY_HTTP_REQUEST_ENTITY_TOO_LARGE 413
158#define SPDY_HTTP_REQUEST_URI_TOO_LONG 414
159#define SPDY_HTTP_UNSUPPORTED_MEDIA_TYPE 415
160#define SPDY_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE 416
161#define SPDY_HTTP_EXPECTATION_FAILED 417
162#define SPDY_HTTP_UNPROCESSABLE_ENTITY 422
163#define SPDY_HTTP_LOCKED 423
164#define SPDY_HTTP_FAILED_DEPENDENCY 424
165#define SPDY_HTTP_UNORDERED_COLLECTION 425
166#define SPDY_HTTP_UPGRADE_REQUIRED 426
167#define SPDY_HTTP_NO_RESPONSE 444
168#define SPDY_HTTP_RETRY_WITH 449
169#define SPDY_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450
170#define SPDY_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS 451
171
172#define SPDY_HTTP_INTERNAL_SERVER_ERROR 500
173#define SPDY_HTTP_NOT_IMPLEMENTED 501
174#define SPDY_HTTP_BAD_GATEWAY 502
175#define SPDY_HTTP_SERVICE_UNAVAILABLE 503
176#define SPDY_HTTP_GATEWAY_TIMEOUT 504
177#define SPDY_HTTP_HTTP_VERSION_NOT_SUPPORTED 505
178#define SPDY_HTTP_VARIANT_ALSO_NEGOTIATES 506
179#define SPDY_HTTP_INSUFFICIENT_STORAGE 507
180#define SPDY_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509
181#define SPDY_HTTP_NOT_EXTENDED 510
182
183/**
184 * HTTP headers are used in SPDY, but all of them MUST be lowercase.
185 * Some are not valid in SPDY and MUST not be used
186 */
187#define SPDY_HTTP_HEADER_ACCEPT "accept"
188#define SPDY_HTTP_HEADER_ACCEPT_CHARSET "accept-charset"
189#define SPDY_HTTP_HEADER_ACCEPT_ENCODING "accept-encoding"
190#define SPDY_HTTP_HEADER_ACCEPT_LANGUAGE "accept-language"
191#define SPDY_HTTP_HEADER_ACCEPT_RANGES "accept-ranges"
192#define SPDY_HTTP_HEADER_AGE "age"
193#define SPDY_HTTP_HEADER_ALLOW "allow"
194#define SPDY_HTTP_HEADER_AUTHORIZATION "authorization"
195#define SPDY_HTTP_HEADER_CACHE_CONTROL "cache-control"
196/* Connection header is forbidden in SPDY */
197#define SPDY_HTTP_HEADER_CONNECTION "connection"
198#define SPDY_HTTP_HEADER_CONTENT_ENCODING "content-encoding"
199#define SPDY_HTTP_HEADER_CONTENT_LANGUAGE "content-language"
200#define SPDY_HTTP_HEADER_CONTENT_LENGTH "content-length"
201#define SPDY_HTTP_HEADER_CONTENT_LOCATION "content-location"
202#define SPDY_HTTP_HEADER_CONTENT_MD5 "content-md5"
203#define SPDY_HTTP_HEADER_CONTENT_RANGE "content-range"
204#define SPDY_HTTP_HEADER_CONTENT_TYPE "content-type"
205#define SPDY_HTTP_HEADER_COOKIE "cookie"
206#define SPDY_HTTP_HEADER_DATE "date"
207#define SPDY_HTTP_HEADER_ETAG "etag"
208#define SPDY_HTTP_HEADER_EXPECT "expect"
209#define SPDY_HTTP_HEADER_EXPIRES "expires"
210#define SPDY_HTTP_HEADER_FROM "from"
211/* Host header is forbidden in SPDY */
212#define SPDY_HTTP_HEADER_HOST "host"
213#define SPDY_HTTP_HEADER_IF_MATCH "if-match"
214#define SPDY_HTTP_HEADER_IF_MODIFIED_SINCE "if-modified-since"
215#define SPDY_HTTP_HEADER_IF_NONE_MATCH "if-none-match"
216#define SPDY_HTTP_HEADER_IF_RANGE "if-range"
217#define SPDY_HTTP_HEADER_IF_UNMODIFIED_SINCE "if-unmodified-since"
218/* Keep-Alive header is forbidden in SPDY */
219#define SPDY_HTTP_HEADER_KEEP_ALIVE "keep-alive"
220#define SPDY_HTTP_HEADER_LAST_MODIFIED "last-modified"
221#define SPDY_HTTP_HEADER_LOCATION "location"
222#define SPDY_HTTP_HEADER_MAX_FORWARDS "max-forwards"
223#define SPDY_HTTP_HEADER_PRAGMA "pragma"
224#define SPDY_HTTP_HEADER_PROXY_AUTHENTICATE "proxy-authenticate"
225#define SPDY_HTTP_HEADER_PROXY_AUTHORIZATION "proxy-authorization"
226/* Proxy-Connection header is forbidden in SPDY */
227#define SPDY_HTTP_HEADER_PROXY_CONNECTION "proxy-connection"
228#define SPDY_HTTP_HEADER_RANGE "range"
229#define SPDY_HTTP_HEADER_REFERER "referer"
230#define SPDY_HTTP_HEADER_RETRY_AFTER "retry-after"
231#define SPDY_HTTP_HEADER_SERVER "server"
232#define SPDY_HTTP_HEADER_SET_COOKIE "set-cookie"
233#define SPDY_HTTP_HEADER_SET_COOKIE2 "set-cookie2"
234#define SPDY_HTTP_HEADER_TE "te"
235#define SPDY_HTTP_HEADER_TRAILER "trailer"
236/* Transfer-Encoding header is forbidden in SPDY */
237#define SPDY_HTTP_HEADER_TRANSFER_ENCODING "transfer-encoding"
238#define SPDY_HTTP_HEADER_UPGRADE "upgrade"
239#define SPDY_HTTP_HEADER_USER_AGENT "user-agent"
240#define SPDY_HTTP_HEADER_VARY "vary"
241#define SPDY_HTTP_HEADER_VIA "via"
242#define SPDY_HTTP_HEADER_WARNING "warning"
243#define SPDY_HTTP_HEADER_WWW_AUTHENTICATE "www-authenticate"
244
245/**
246 * HTTP versions (a value must be provided in SPDY requests/responses).
247 */
248#define SPDY_HTTP_VERSION_1_0 "HTTP/1.0"
249#define SPDY_HTTP_VERSION_1_1 "HTTP/1.1"
250
251/**
252 * HTTP methods
253 */
254#define SPDY_HTTP_METHOD_CONNECT "CONNECT"
255#define SPDY_HTTP_METHOD_DELETE "DELETE"
256#define SPDY_HTTP_METHOD_GET "GET"
257#define SPDY_HTTP_METHOD_HEAD "HEAD"
258#define SPDY_HTTP_METHOD_OPTIONS "OPTIONS"
259#define SPDY_HTTP_METHOD_POST "POST"
260#define SPDY_HTTP_METHOD_PUT "PUT"
261#define SPDY_HTTP_METHOD_TRACE "TRACE"
262
263/**
264 * HTTP POST encodings, see also
265 * http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
266 */
267#define SPDY_HTTP_POST_ENCODING_FORM_URLENCODED "application/x-www-form-urlencoded"
268#define SPDY_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data"
269
270
271/**
272 * Handle for the daemon (listening on a socket).
273 */
274struct SPDY_Daemon;
275
276
277/**
278 * Handle for a SPDY session/connection.
279 */
280struct SPDY_Session;
281
282
283/**
284 * Handle for a SPDY request sent by a client. The structure has pointer
285 * to the session's handler
286 */
287struct SPDY_Request;
288
289
290/**
291 * Handle for a response containing HTTP headers and data to be sent.
292 * The structure has pointer to the session's handler
293 * for this response.
294 */
295struct SPDY_Response;
296
297
298/**
299 * Collection of tuples of an HTTP header and values used in requests
300 * and responses.
301 */
302struct SPDY_NameValue;
303
304
305/**
306 * Collection of tuples of a SPDY setting ID, value
307 * and flags used to control the sessions.
308 */
309struct SPDY_Settings;
310
311
312/**
313 * SPDY IO sybsystem flags used by SPDY_init() and SPDY_deinit().<p>
314 *
315 * The values are used internally as flags, that is why they must be
316 * powers of 2.
317 */
318enum SPDY_IO_SUBSYSTEM
319{
320
321  /**
322   * No subsystem. For internal use.
323   */
324  SPDY_IO_SUBSYSTEM_NONE = 0,
325
326  /**
327   * Default TLS implementation provided by openSSL/libssl.
328   */
329  SPDY_IO_SUBSYSTEM_OPENSSL = 1,
330
331  /**
332   * No TLS is used.
333   */
334  SPDY_IO_SUBSYSTEM_RAW = 2
335};
336
337
338/**
339 * SPDY daemon options. Passed in the varargs portion of
340 * SPDY_start_daemon to customize the daemon. Each option must
341 * be followed by a value of a specific type.<p>
342 *
343 * The values are used internally as flags, that is why they must be
344 * powers of 2.
345 */
346enum SPDY_DAEMON_OPTION
347{
348
349  /**
350   * No more options / last option.  This is used
351   * to terminate the VARARGs list.
352   */
353  SPDY_DAEMON_OPTION_END = 0,
354
355  /**
356   * Set a custom timeout for all connections.  Must be followed by
357   * a number of seconds, given as an 'unsigned int'.  Use
358   * zero for no timeout.
359   */
360  SPDY_DAEMON_OPTION_SESSION_TIMEOUT = 1,
361
362  /**
363   * Bind daemon to the supplied sockaddr. This option must be
364   * followed by a 'struct sockaddr *'.  The 'struct sockaddr*'
365   * should point to a 'struct sockaddr_in6' or to a
366   * 'struct sockaddr_in'.
367   */
368  SPDY_DAEMON_OPTION_SOCK_ADDR = 2,
369
370  /**
371   * Flags for the daemon. Must be followed by a SPDY_DAEMON_FLAG value
372   * which is the result of bitwise OR of desired flags.
373   */
374  SPDY_DAEMON_OPTION_FLAGS = 4,
375
376  /**
377   * IO subsystem type used by daemon and all its sessions. If not set,
378   * TLS provided by openssl is used. Must be followed by a
379   * SPDY_IO_SUBSYSTEM value.
380   */
381  SPDY_DAEMON_OPTION_IO_SUBSYSTEM = 8,
382
383  /**
384   * Maximum number of frames to be written to the socket at once. The
385   * library tries to send max_num_frames in a single call to SPDY_run
386   * for a single session. This means no requests can be received nor
387   * other sessions can send data as long the current one has enough
388   * frames to send and there is no error on writing. Thus, a big value
389   * will affect the performance. Small value gives fairnes for sessions.
390   * Must be followed by a positive integer (uin32_t). If not set, the
391   * default value 10 will be used.
392   */
393  SPDY_DAEMON_OPTION_MAX_NUM_FRAMES = 16
394};
395
396
397/**
398 * Flags for starting SPDY daemon. They are used to set some settings
399 * for the daemon, which do not require values.
400 */
401enum SPDY_DAEMON_FLAG
402{
403  /**
404   * No flags selected.
405   */
406  SPDY_DAEMON_FLAG_NO = 0,
407
408  /**
409   * The server will bind only on IPv6 addresses. If the flag is set and
410   * the daemon is provided with IPv4 address or IPv6 is not supported,
411   * starting daemon will fail.
412   */
413  SPDY_DAEMON_FLAG_ONLY_IPV6 = 1,
414
415  /**
416   * All sessions' sockets will be set with TCP_NODELAY if the flag is
417   * used. Option considered only by SPDY_IO_SUBSYSTEM_RAW.
418   */
419  SPDY_DAEMON_FLAG_NO_DELAY = 2
420};
421
422
423/**
424 * SPDY settings IDs sent by both client and server in SPDY SETTINGS frame.
425 * They affect the whole SPDY session. Defined in SPDY Protocol - Draft 3.
426 */
427enum SPDY_SETTINGS
428{
429
430  /**
431   * Allows the sender to send its expected upload bandwidth on this
432   * channel. This number is an estimate. The value should be the
433   * integral number of kilobytes per second that the sender predicts
434   * as an expected maximum upload channel capacity.
435   */
436  SPDY_SETTINGS_UPLOAD_BANDWIDTH = 1,
437
438  /**
439   * Allows the sender to send its expected download bandwidth on this
440   * channel. This number is an estimate. The value should be the
441   * integral number of kilobytes per second that the sender predicts as
442   * an expected maximum download channel capacity.
443   */
444  SPDY_SETTINGS_DOWNLOAD_BANDWIDTH = 2,
445
446  /**
447   * Allows the sender to send its expected round-trip-time on this
448   * channel. The round trip time is defined as the minimum amount of
449   * time to send a control frame from this client to the remote and
450   * receive a response. The value is represented in milliseconds.
451   */
452  SPDY_SETTINGS_ROUND_TRIP_TIME = 3,
453
454  /**
455   * Allows the sender to inform the remote endpoint the maximum number
456   * of concurrent streams which it will allow. By default there is no
457   * limit. For implementors it is recommended that this value be no
458   * smaller than 100.
459   */
460  SPDY_SETTINGS_MAX_CONCURRENT_STREAMS = 4,
461
462  /**
463   * Allows the sender to inform the remote endpoint of the current TCP
464   * CWND value.
465   */
466  SPDY_SETTINGS_CURRENT_CWND = 5,
467
468  /**
469   * Allows the sender to inform the remote endpoint the retransmission
470   * rate (bytes retransmitted / total bytes transmitted).
471   */
472  SPDY_SETTINGS_DOWNLOAD_RETRANS_RATE = 6,
473
474  /**
475   * Allows the sender to inform the remote endpoint the initial window
476   * size (in bytes) for new streams.
477   */
478  SPDY_SETTINGS_INITIAL_WINDOW_SIZE = 7,
479
480  /**
481   * Allows the server to inform the client if the new size of the
482   * client certificate vector.
483   */
484  SPDY_SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8
485};
486
487
488/**
489 * Flags for each individual SPDY setting in the SPDY SETTINGS frame.
490 * They affect only one setting to which they are set.
491 * Defined in SPDY Protocol - Draft 3.
492 */
493enum SPDY_FLAG_SETTINGS
494{
495
496  /**
497   * When set, the sender of this SETTINGS frame is requesting that the
498   * recipient persist the ID/Value and return it in future SETTINGS
499   * frames sent from the sender to this recipient. Because persistence
500   * is only implemented on the client, this flag is only sent by the
501   * server.
502   */
503  SPDY_FLAG_SETTINGS_PERSIST_VALUE = 1,
504
505  /**
506   * When set, the sender is notifying the recipient that this ID/Value
507   * pair was previously sent to the sender by the recipient with the
508   * #SPDY_FLAG_SETTINGS_PERSIST_VALUE, and the sender is returning it.
509   * Because persistence is only implemented on the client, this flag is
510   * only sent by the client.
511   */
512  SPDY_FLAG_SETTINGS_PERSISTED = 2
513};
514
515
516/**
517 * Flag associated with a whole SPDY SETTINGS frame. Affect all the
518 * settings in the frame. Defined in SPDY Protocol - Draft 3.
519 */
520enum SPDY_FLAG_SETTINGS_FRAME
521{
522
523  /**
524   * When set, the client should clear any previously persisted SETTINGS
525   * ID/Value pairs. If this frame contains ID/Value pairs with the
526   * #SPDY_FLAG_SETTINGS_PERSIST_VALUE set, then the client will first
527   * clear its existing, persisted settings, and then persist the values
528   * with the flag set which are contained within this frame. Because
529   * persistence is only implemented on the client, this flag can only
530   * be used when the sender is the server.
531   */
532  SPDY_FLAG_SETTINGS_CLEAR_SETTINGS = 1
533};
534
535
536/**
537 * SPDY settings function options. Passed in the varargs portion of
538 * SPDY_SettingsReceivedCallback and SPDY_send_settings to customize
539 * more the settings handling. Each option must
540 * be followed by a value of a specific type.<p>
541 *
542 * The values are used internally as flags, that is why they must be
543 * powers of 2.
544 */
545enum SPDY_SETTINGS_OPTION
546{
547
548  /**
549   * No more options / last option.  This is used
550   * to terminate the VARARGs list.
551   */
552  SPDY_SETTINGS_OPTION_END = 0
553};
554
555
556/**
557 * Used as a parameter for SPDY_ResponseResultCallback and shows if the
558 * response was actually written to the TLS socket or discarded by the
559 * lib for any reason (and respectively the reason).
560 */
561enum SPDY_RESPONSE_RESULT
562{
563
564  /**
565   * The lib has written the full response to the TLS socket.
566   */
567  SPDY_RESPONSE_RESULT_SUCCESS = 0,
568
569  /**
570   * The session is being closed, so the data is being discarded
571   */
572  SPDY_RESPONSE_RESULT_SESSION_CLOSED = 1,
573
574  /**
575   * The stream for this response has been closed. May happen when the
576   * sender had sent first SYN_STREAM and after that RST_STREAM.
577   */
578  SPDY_RESPONSE_RESULT_STREAM_CLOSED = 2
579};
580
581
582/**
583 * Callback for serious error condition. The default action is to print
584 * an error message and abort().
585 *
586 * @param cls user specified value
587 * @param file where the error occured
588 * @param line where the error occured
589 * @param reason error details message, may be NULL
590 */
591typedef void
592(*SPDY_PanicCallback) (void * cls,
593                       const char *file,
594                       unsigned int line,
595                       const char *reason);
596
597
598/**
599 * Callback for new SPDY session established by a client. Called
600 * immediately after the TCP connection was established.
601 *
602 * @param cls client-defined closure
603 * @param session handler for the new SPDY session
604 */
605typedef void
606(*SPDY_NewSessionCallback) (void * cls,
607                            struct SPDY_Session * session);
608
609
610/**
611 * Callback for closed session. Called after the TCP connection was
612 * closed. In this callback function the user has the last
613 * chance to access the SPDY_Session structure. After that the latter
614 * will be cleaned!
615 *
616 * @param cls client-defined closure
617 * @param session handler for the closed SPDY session
618 * @param by_client #SPDY_YES if the session close was initiated by the
619 * 					client;
620 * 		    #SPDY_NO if closed by the server
621 */
622typedef void
623(*SPDY_SessionClosedCallback) (void *cls,
624                               struct SPDY_Session *session,
625                               int by_client);
626
627
628/**
629 * Iterator over name-value pairs.
630 *
631 * @param cls client-defined closure
632 * @param name of the pair
633 * @param value of the pair
634 * @return #SPDY_YES to continue iterating,
635 *         #SPDY_NO to abort the iteration
636 */
637typedef int
638(*SPDY_NameValueIterator) (void *cls,
639                           const char *name,
640                           const char * const * value,
641                           int num_values);
642
643
644/**
645 * Callback for received SPDY request. The functions is called whenever
646 * a reqest comes, but will also be called if more headers/trailers are
647 * received.
648 *
649 * @param cls client-defined closure
650 * @param request handler. The request object is required for
651 * 			sending responses.
652 * @param priority of the SPDY stream which the request was
653 * 			sent over
654 * @param method HTTP method
655 * @param path HTTP path
656 * @param version HTTP version just like in HTTP request/response:
657 * 			"HTTP/1.0" or "HTTP/1.1" currently
658 * @param host called host as in HTTP
659 * @param scheme used ("http" or "https"). In SPDY 3 it is only "https".
660 * @param headers other HTTP headers from the request
661 * @param more a flag saying if more data related to the request is
662 *        expected to be received. HTTP body may arrive (e.g. POST data);
663 *        then SPDY_NewDataCallback will be called for the connection.
664 *        It is also possible that more headers/trailers arrive;
665 *        then the same callback will be invoked. The user should detect
666 *        that it is not the first invocation of the function for that
667 *        request.
668 */
669typedef void
670(*SPDY_NewRequestCallback) (void *cls,
671                            struct SPDY_Request *request,
672                            uint8_t priority,
673                            const char *method,
674                            const char *path,
675                            const char *version,
676                            const char *host,
677                            const char *scheme,
678                            struct SPDY_NameValue *headers,
679                            bool more);
680
681
682/**
683 * Callback for received new data chunk (HTTP body) from a given
684 * request (e.g. POST data).
685 *
686 * @param cls client-defined closure
687 * @param request handler
688 * @param buf data chunk from the POST data
689 * @param size the size of the data chunk 'buf' in bytes. Note that it
690 *             may be 0.
691 * @param more false if this is the last chunk from the data. Note:
692 *             true does not mean that more data will come, exceptional
693 *             situation is possible
694 * @return #SPDY_YES to continue calling the function,
695 *         #SPDY_NO to stop calling the function for this request
696 */
697typedef int
698(*SPDY_NewDataCallback) (void *cls,
699                         struct SPDY_Request *request,
700                         const void *buf,
701                         size_t size,
702                         bool more);
703// How about passing POST encoding information
704// here as well?
705//TODO
706
707
708/**
709 * Callback to be used with SPDY_build_response_with_callback. The
710 * callback will be called when the lib wants to write to the TLS socket.
711 * The application should provide the data to be sent.
712 *
713 * @param cls client-defined closure
714 * @param max maximum number of bytes that are allowed to be written
715 * 			to the buffer.
716 * @param more true if more data will be sent (i.e. the function must
717 * 				be calleed again),
718 *             false if this is the last chunk, the lib will close
719 * 				the stream
720 * @return number of bytes written to buffer. On error the call MUST
721 * 			return value less than 0 to indicate the library.
722 */
723typedef ssize_t
724(*SPDY_ResponseCallback) (void *cls,
725                          void *buffer,
726                          size_t max,
727                          bool *more);
728
729
730/**
731 * Callback to be called when the last bytes from the response was sent
732 * to the client or when the response was discarded from the lib. This
733 * callback is a very good place to discard the request and the response
734 * objects, if they will not be reused (e.g., sending the same response
735 * again). If the stream is closed it is safe to discard the request
736 * object.
737 *
738 * @param cls client-defined closure
739 * @param response handler to the response that was just sent
740 * @param request handler to the request for which the response was sent
741 * @param status shows if actually the response was sent or it was
742 * 			discarded by the lib for any reason (e.g., closing session,
743 * 			closing stream, stopping daemon, etc.). It is possible that
744 * 			status indicates an error but parts of the response headers
745 * 			and/or body (in one
746 * 			or several frames) were already sent to the client.
747 * @param streamopened indicates if the the stream for this request/
748 * 			response pair is still opened. If yes, the server may want
749 * 			to use SPDY push to send something additional to the client
750 * 			and/or close the stream.
751 */
752typedef void
753(*SPDY_ResponseResultCallback) (void * cls,
754                                struct SPDY_Response *response,
755                                struct SPDY_Request *request,
756                                enum SPDY_RESPONSE_RESULT status,
757                                bool streamopened);
758
759
760/**
761 * Callback to notify when SPDY ping response is received.
762 *
763 * @param session handler for which the ping request was sent
764 * @param rtt the timespan between sending ping request and receiving it
765 * 			from the library
766 */
767typedef void
768(*SPDY_PingCallback) (void * cls,
769                      struct SPDY_Session *session,
770                      struct timeval *rtt);
771
772
773/**
774 * Iterator over settings ID/Value/Flags tuples.
775 *
776 * @param cls client-defined closure
777 * @param id SPDY settings ID
778 * @param value value for this setting
779 * @param flags flags for this tuple; use
780 * 			`enum SPDY_FLAG_SETTINGS`
781 * @return #SPDY_YES to continue iterating,
782 *         #SPDY_NO to abort the iteration
783 */
784typedef int
785(*SPDY_SettingsIterator) (void *cls,
786                          enum SPDY_SETTINGS id,
787                          int32_t value,
788                          uint8_t flags);
789
790
791/**
792 * Callback to notify when SPDY SETTINGS are received from the client.
793 *
794 * @param session handler for which settings are received
795 * @param settings ID/value/flags tuples of the settings
796 * @param flags for the whole settings frame; use
797 * 			enum SPDY_FLAG_SETTINGS_FRAME
798 * @param ... list of options (type-value pairs,
799 *        terminated with #SPDY_SETTINGS_OPTION_END).
800 */
801typedef void
802(*SPDY_SettingsReceivedCallback) (struct SPDY_Session *session,
803                                  struct SPDY_Settings *settings,
804                                  uint8_t flags,
805                                  ...);
806
807
808/* Global functions for the library */
809
810
811/**
812 * Init function for the whole library. It MUST be called before any
813 * other function of the library to initialize things like TLS context
814 * and possibly other stuff needed by the lib. Currently the call
815 * always returns #SPDY_YES.
816 *
817 * @param io_subsystem the IO subsystem that will
818 *        be initialized. Several can be used with bitwise OR. If no
819 *        parameter is set, the default openssl subsystem will be used.
820 * @return #SPDY_YES if the library was correctly initialized and its
821 * 			functions can be used now;
822 * 			#SPDY_NO on error
823 */
824_MHD_EXTERN int
825(SPDY_init) (enum SPDY_IO_SUBSYSTEM io_subsystem, ...);
826#define SPDY_init() SPDY_init (SPDY_IO_SUBSYSTEM_OPENSSL)
827
828
829/**
830 * Deinit function for the whole lib. It can be called after finishing
831 * using the library. It frees and cleans up resources allocated in
832 * SPDY_init. Currently the function does not do anything.
833 */
834_MHD_EXTERN void
835SPDY_deinit (void);
836
837
838/**
839 * Sets the global error handler to a different implementation. "cb"
840 * will only be called in the case of typically fatal, serious
841 * internal consistency issues.  These issues should only arise in the
842 * case of serious memory corruption or similar problems with the
843 * architecture as well as failed assertions.  While "cb" is allowed to
844 * return and the lib will then try to continue, this is never safe.
845 *
846 * The default implementation that is used if no panic function is set
847 * simply prints an error message and calls "abort".  Alternative
848 * implementations might call "exit" or other similar functions.
849 *
850 * @param cb new error handler
851 * @param cls passed to error handler
852 */
853_MHD_EXTERN void
854SPDY_set_panic_func (SPDY_PanicCallback cb,
855                     void *cls);
856
857
858/* Daemon functions */
859
860
861/**
862 * Start a SPDY webserver on the given port.
863 *
864 * @param port to bind to. The value is ignored if address structure
865 * 			is passed as daemon option
866 * @param certfile path to the certificate that will be used by server
867 * @param keyfile path to the keyfile for the certificate
868 * @param nscb callback called when a new SPDY session is
869 * 			established	by a client
870 * @param sccb callback called when a session is closed
871 * @param nrcb callback called when a client sends request
872 * @param npdcb callback called when HTTP body (POST data) is received
873 * 			after request
874 * @param cls common extra argument to all of the callbacks
875 * @param ... list of options (type-value pairs,
876 *        terminated with #SPDY_DAEMON_OPTION_END).
877 * @return NULL on error, handle to daemon on success
878 */
879_MHD_EXTERN struct SPDY_Daemon *
880SPDY_start_daemon (uint16_t port,
881                   const char *certfile,
882                   const char *keyfile,
883                   SPDY_NewSessionCallback nscb,
884                   SPDY_SessionClosedCallback sccb,
885                   SPDY_NewRequestCallback nrcb,
886                   SPDY_NewDataCallback npdcb,
887                   void *cls,
888                   ...);
889
890
891/**
892 * Shutdown the daemon. First all sessions are closed. It is NOT safe
893 * to call this function in user callbacks.
894 *
895 * @param daemon to stop
896 */
897_MHD_EXTERN void
898SPDY_stop_daemon (struct SPDY_Daemon *daemon);
899
900
901/**
902 * Obtain the select sets for this daemon. Only those are retrieved,
903 * which some processing should be done for, i.e. not all sockets are
904 * added to write_fd_set.<p>
905 *
906 * It is possible that there is
907 * nothing to be read from a socket but there is data either in the
908 * TLS subsystem's read buffers or in libmicrospdy's read buffers, which
909 * waits for being processed. In such case the file descriptor will be
910 * added to write_fd_set. Since it is very likely for the socket to be
911 * ready for writing, the select used in the application's event loop
912 * will return with success, SPDY_run will be called, the data will be
913 * processed and maybe something will be written to the socket. Without
914 * this behaviour, considering a proper event loop, data may stay in the
915 * buffers, but run is never called.
916 *
917 * @param daemon to get sets from
918 * @param read_fd_set read set
919 * @param write_fd_set write set
920 * @param except_fd_set except set
921 * @return largest FD added to any of the sets
922 */
923_MHD_EXTERN int
924SPDY_get_fdset (struct SPDY_Daemon *daemon,
925                fd_set *read_fd_set,
926                fd_set *write_fd_set,
927                fd_set *except_fd_set);
928
929
930/**
931 * Obtain timeout value for select for this daemon. The returned value
932 * is how long select
933 * should at most block, not the timeout value set for connections.
934 *
935 * @param daemon to query for timeout
936 * @param timeout will be set to the timeout value (in milliseconds)
937 * @return #SPDY_YES on success
938 *         #SPDY_NO if no connections exist that
939 * 			would necessiate the use of a timeout right now
940 */
941_MHD_EXTERN int
942SPDY_get_timeout (struct SPDY_Daemon *daemon,
943                  unsigned long long *timeout);
944
945
946/**
947 * Run webserver operations. This method must be called in
948 * the client event loop.
949 *
950 * @param daemon to run
951 */
952_MHD_EXTERN void
953SPDY_run (struct SPDY_Daemon *daemon);
954
955
956/* SPDY Session handling functions */
957
958
959/**
960 * Closes a SPDY session. SPDY clients and servers are expected to keep
961 * sessions opened as long as possible. However, the server may want to
962 * close some connections, e.g. if there are too many, to free some
963 * resources. The function can also be used to close a specific session
964 * if the client is not desired.
965 *
966 * @param session handler to be closed
967 */
968_MHD_EXTERN void
969SPDY_close_session (struct SPDY_Session * session);
970
971
972/**
973 * Associate a void pointer with a session. The data accessible by the
974 * pointer can later be used wherever the session handler is available.
975 *
976 * @param session handler
977 * @param cls any data pointed by a pointer to be accessible later
978 */
979_MHD_EXTERN void
980SPDY_set_cls_to_session (struct SPDY_Session *session,
981                         void *cls);
982
983
984/**
985 * Retrieves the pointer associated with SPDY_set_cls_to_session().
986 *
987 * @param session handler to get its cls
988 * @return same pointer added by SPDY_set_cls_to_session() or
989 * 			NULL when nothing was associated
990 */
991_MHD_EXTERN void *
992SPDY_get_cls_from_session (struct SPDY_Session *session);
993
994
995/**
996 * Retrieves the remote address of a given session.
997 *
998 * @param session handler to get its remote address
999 * @param addr out parameter; pointing to remote address
1000 * @return length of the address structure
1001 */
1002_MHD_EXTERN socklen_t
1003SPDY_get_remote_addr (struct SPDY_Session *session,
1004                      struct sockaddr **addr);
1005
1006
1007/* SPDY name/value data structure handling functions */
1008
1009
1010/**
1011 * Create a new NameValue structure. It is needed for putting inside the
1012 * HTTP headers and their values for a response. The user should later
1013 * destroy alone the structure.
1014 *
1015 * @return handler to the new empty structure or NULL on error
1016 */
1017_MHD_EXTERN struct SPDY_NameValue *
1018SPDY_name_value_create (void);
1019
1020
1021/**
1022 * Add name/value pair to a NameValue structure. SPDY_NO will be returned
1023 * if the name/value pair is already in the structure. It is legal to
1024 * add different values for the same name.
1025 *
1026 * @param container structure to which the new pair is added
1027 * @param name for the value. Null-terminated string.
1028 * @param value the value itself. Null-terminated string.
1029 * @return #SPDY_NO on error or #SPDY_YES on success
1030 */
1031_MHD_EXTERN int
1032SPDY_name_value_add (struct SPDY_NameValue *container,
1033                     const char *name,
1034                     const char *value);
1035
1036
1037/**
1038 * Lookup value for a name in a name/value structure.
1039 *
1040 * @param container structure in which to lookup
1041 * @param name the name to look for
1042 * @param num_values length of the returned array with values
1043 * @return NULL if no such item was found, or an array containing the
1044 * 			values
1045 */
1046_MHD_EXTERN const char * const *
1047SPDY_name_value_lookup (struct SPDY_NameValue *container,
1048                        const char *name,
1049                        int *num_values);
1050
1051
1052/**
1053 * Iterate over name/value structure.
1054 *
1055 * @param container structure which to iterate over
1056 * @param iterator callback to call on each name/value pair;
1057 *        maybe NULL (then just count headers)
1058 * @param iterator_cls extra argument to @a iterator
1059 * @return number of entries iterated over
1060 */
1061_MHD_EXTERN int
1062SPDY_name_value_iterate (struct SPDY_NameValue *container,
1063                         SPDY_NameValueIterator iterator,
1064                         void *iterator_cls);
1065
1066
1067/**
1068 * Destroy a NameValue structure. Use this function to destroy only
1069 * objects which, after passed to, will not be destroied by other
1070 * functions.
1071 *
1072 */
1073_MHD_EXTERN void
1074SPDY_name_value_destroy (struct SPDY_NameValue *container);
1075
1076
1077/* SPDY request handling functions */
1078
1079
1080/**
1081 * Gets the session responsible for the given
1082 * request.
1083 *
1084 * @param request for which the session is wanted
1085 * @return session handler for the request
1086 */
1087_MHD_EXTERN struct SPDY_Session *
1088SPDY_get_session_for_request (const struct SPDY_Request *request);
1089
1090
1091/**
1092 * Associate a void pointer with a request. The data accessible by the
1093 * pointer can later be used wherever the request handler is available.
1094 *
1095 * @param request with which to associate a pointer
1096 * @param cls any data pointed by a pointer to be accessible later
1097 */
1098_MHD_EXTERN void
1099SPDY_set_cls_to_request (struct SPDY_Request *request,
1100                         void *cls);
1101
1102
1103/**
1104 * Retrieves the pointer associated with the request by
1105 * SPDY_set_cls_to_request().
1106 *
1107 * @param request to get its cls
1108 * @return same pointer added by SPDY_set_cls_to_request() or
1109 * 			NULL when nothing was associated
1110 */
1111_MHD_EXTERN void *
1112SPDY_get_cls_from_request (struct SPDY_Request *request);
1113
1114
1115/* SPDY response handling functions */
1116
1117
1118/**
1119 * Create response object containing all needed headers and data. The
1120 * response object is not bound to a request, so it can be used multiple
1121 * times with SPDY_queue_response() and schould be
1122 * destroied by calling the SPDY_destroy_response().<p>
1123 *
1124 * Currently the library does not provide compression of the body data.
1125 * It is up to the user to pass already compressed data and the
1126 * appropriate headers to this function when desired.
1127 *
1128 * @param status HTTP status code for the response (e.g. 404)
1129 * @param statustext HTTP status message for the response, which will
1130 * 			be appended to the status code (e.g. "OK"). Can be NULL
1131 * @param version HTTP version for the response (e.g. "http/1.1")
1132 * @param headers name/value structure containing additional HTTP headers.
1133 *                Can be NULL. Can be used multiple times, it is up to
1134 *                the user to destoy the object when not needed anymore.
1135 * @param data the body of the response. The lib will make a copy of it,
1136 *             so it is up to the user to take care of the memory
1137 *             pointed by data
1138 * @param size length of @a data. It can be 0, then the lib will send only
1139 * 				headers
1140 * @return NULL on error, handle to response object on success
1141 */
1142_MHD_EXTERN struct SPDY_Response *
1143SPDY_build_response (int status,
1144                     const char *statustext,
1145                     const char *version,
1146                     struct SPDY_NameValue *headers,
1147                     const void *data,
1148                     size_t size);
1149
1150
1151/**
1152 * Create response object containing all needed headers. The data will
1153 * be provided later when the lib calls the callback function (just
1154 * before writing it to the TLS socket). The
1155 * response object is not bound to a request, so it can be used multiple
1156 * times with SPDY_queue_response() and schould be
1157 * destroied by calling the SPDY_destroy_response().<p>
1158 *
1159 * Currently the library does not provide compression of the body data.
1160 * It is up to the user to pass already compressed data and the
1161 * appropriate headers to this function and the callback when desired.
1162 *
1163 * @param status HTTP status code for the response (e.g. 404)
1164 * @param statustext HTTP status message for the response, which will
1165 * 			be appended to the status code (e.g. "OK"). Can be NULL
1166 * @param version HTTP version for the response (e.g. "http/1.1")
1167 * @param headers name/value structure containing additional HTTP headers.
1168 *                Can be NULL. Can be used multiple times, it is up to
1169 *                the user to destoy the object when not needed anymore.
1170 * @param rcb callback to use to obtain response data
1171 * @param rcb_cls extra argument to @a rcb
1172 * @param block_size preferred block size for querying rcb (advisory only,
1173 *                   the lib will call rcb specifying the block size); clients
1174 *                   should pick a value that is appropriate for IO and
1175 *                   memory performance requirements. The function will
1176 *                   fail if the value is bigger than the maximum
1177 *                   supported value (SPDY_MAX_SUPPORTED_FRAME_SIZE).
1178 *                   Can be 0, then the lib will use
1179 *                   #SPDY_MAX_SUPPORTED_FRAME_SIZE instead.
1180 * @return NULL on error, handle to response object on success
1181 */
1182_MHD_EXTERN struct SPDY_Response *
1183SPDY_build_response_with_callback(int status,
1184                                  const char *statustext,
1185                                  const char *version,
1186                                  struct SPDY_NameValue *headers,
1187                                  SPDY_ResponseCallback rcb,
1188                                  void *rcb_cls,
1189                                  uint32_t block_size);
1190
1191
1192/**
1193 * Queue response object to be sent to the client. A successfully queued
1194 * response may never be sent, e.g. when the stream gets closed. The
1195 * data will be added to the output queue. The call will fail, if the
1196 * output for this session
1197 * is closed (i.e. the session is closed, half or full) or the output
1198 * channel for the stream, on which the request was received, is closed
1199 * (i.e. the stream is closed, half or full).
1200 *
1201 * @param request object identifying the request to which the
1202 * 			response is returned
1203 * @param response object containg headers and data to be sent
1204 * @param closestream TRUE if the server does NOT intend to PUSH
1205 * 			something more associated to this request/response later,
1206 * 			FALSE otherwise
1207 * @param consider_priority if FALSE, the response will be added to the
1208 * 			end of the queue. If TRUE, the response will be added after
1209 * 			the last previously added response with priority of the
1210 * 			request grater or equal to that of the current one. This
1211 * 			means that the function should be called with TRUE each time
1212 * 			if one wants to be sure that the output queue behaves like
1213 * 			a priority queue
1214 * @param rrcb callback called when all the data was sent (last frame
1215 * 			from response) or when that frame was discarded (e.g. the
1216 * 			stream has been closed meanwhile)
1217 * @param rrcb_cls extra argument to @a rrcb
1218 * @return #SPDY_NO on error or #SPDY_YES on success
1219 */
1220_MHD_EXTERN int
1221SPDY_queue_response (struct SPDY_Request *request,
1222                     struct SPDY_Response *response,
1223                     bool closestream,
1224                     bool consider_priority,
1225                     SPDY_ResponseResultCallback rrcb,
1226                     void *rrcb_cls);
1227
1228
1229/**
1230 * Destroy a response structure. It should be called for all objects
1231 * returned by SPDY_build_response*() functions to free the memory
1232 * associated with the prepared response. It is safe to call this
1233 * function not before being sure that the response will not be used by
1234 * the lib anymore, this means after SPDY_ResponseResultCallback
1235 * callbacks were called for all calls to SPDY_queue_response() passing
1236 * this response.
1237 *
1238 * @param response to destroy
1239 */
1240_MHD_EXTERN void
1241SPDY_destroy_response (struct SPDY_Response *response);
1242
1243
1244/* SPDY settings ID/value data structure handling functions */
1245
1246
1247/**
1248 * Create a new SettingsIDValue structure. It is needed for putting
1249 * inside tuples of SPDY option, flags and value for sending to the
1250 * client.
1251 *
1252 * @return hendler to the new empty structure or NULL on error
1253 */
1254_MHD_EXTERN const struct SPDY_Settings *
1255SPDY_settings_create (void);
1256
1257
1258/**
1259 * Add or update a tuple to a SettingsIDValue structure.
1260 *
1261 * @param container structure to which the new tuple is added
1262 * @param id SPDY settings ID that will be sent. If this ID already in
1263 *           container, the tupple for it will be updated (value and/or
1264 *           flags). If it is not in the container, a new tupple will be
1265 *           added.
1266 * @param flags SPDY settings flags applied only to this setting
1267 * @param value of the setting
1268 * @return #SPDY_NO on error
1269 * 			or #SPDY_YES if a new setting was added
1270 */
1271_MHD_EXTERN int
1272SPDY_settings_add (struct SPDY_Settings *container,
1273                   enum SPDY_SETTINGS id,
1274                   enum SPDY_FLAG_SETTINGS flags,
1275                   int32_t value);
1276
1277
1278/**
1279 * Lookup value and flags for an ID in a settings ID/value structure.
1280 *
1281 * @param container structure in which to lookup
1282 * @param id SPDY settings ID to search for
1283 * @param flags out param for SPDY settings flags for this setting;
1284 * 			check it against the flags in enum SPDY_FLAG_SETTINGS
1285 * @param value out param for the value of this setting
1286 * @return #SPDY_NO if the setting is not into the structure
1287 * 			or #SPDY_YES if it is into it
1288 */
1289_MHD_EXTERN int
1290SPDY_settings_lookup (const struct SPDY_Settings *container,
1291                      enum SPDY_SETTINGS id,
1292                      enum SPDY_FLAG_SETTINGS *flags,
1293                      int32_t *value);
1294
1295
1296/**
1297 * Iterate over settings ID/value structure.
1298 *
1299 * @param container structure which to iterate over
1300 * @param iterator callback to call on each ID/value pair;
1301 *        maybe NULL (then just count number of settings)
1302 * @param iterator_cls extra argument to iterator
1303 * @return number of entries iterated over
1304 */
1305_MHD_EXTERN int
1306SPDY_settings_iterate (const struct SPDY_Settings *container,
1307                       SPDY_SettingsIterator iterator,
1308                       void *iterator_cls);
1309
1310
1311/**
1312 * Destroy a settings ID/value structure. Use this function to destroy
1313 * only objects which, after passed to, will not be destroied by other
1314 * functions.
1315 *
1316 * @param container structure which to detroy
1317 */
1318_MHD_EXTERN void
1319SPDY_settings_destroy (struct SPDY_Settings * container);
1320
1321
1322/* SPDY SETTINGS handling functions */
1323
1324
1325/**
1326 * Send SPDY SETTINGS to the client. The call will return fail if there
1327 * in invald setting into the settings container (e.g. invalid setting
1328 * ID).
1329 *
1330 * @param session SPDY_Session handler for which settings are being sent
1331 * @param settings ID/value pairs of the settings to be sent.
1332 * 			Can be used multiple times, it is up to the user to destoy
1333 * 			the object when not needed anymore.
1334 * @param flags for the whole settings frame. They are valid for all tuples
1335 * @param ... list of options (type-value pairs,
1336 *        terminated with #SPDY_SETTINGS_OPTION_END).
1337 * @return SPDY_NO on error or SPDY_YES on
1338 * 			success
1339 */
1340_MHD_EXTERN int
1341SPDY_send_settings (struct SPDY_Session *session,
1342                    struct SPDY_Settings *settings,
1343                    enum SPDY_FLAG_SETTINGS_FRAME flags,
1344                    ...);
1345
1346
1347/* SPDY misc functions */
1348
1349
1350/**
1351 * Destroy a request structure. It should be called for all objects
1352 * received as a parameter in SPDY_NewRequestCallback to free the memory
1353 * associated with the request. It is safe to call this
1354 * function not before being sure that the request will not be used by
1355 * the lib anymore, this means after the stream, on which this request
1356 * had been sent, was closed and all SPDY_ResponseResultCallback
1357 * callbacks were called for all calls to SPDY_queue_response() passing
1358 * this request object.
1359 *
1360 * @param request to destroy
1361 */
1362_MHD_EXTERN void
1363SPDY_destroy_request (struct SPDY_Request * request);
1364
1365
1366/**
1367 * Send SPDY ping to the client
1368 *
1369 * @param session handler for which the ping request is sent
1370 * @param rttcb callback called when ping response to the request is
1371 * 			received
1372 * @param rttcb_cls extra argument to @a rttcb
1373 * @return #SPDY_NO on error or #SPDY_YES on success
1374 */
1375_MHD_EXTERN int
1376SPDY_send_ping (struct SPDY_Session *session,
1377                SPDY_PingCallback rttcb,
1378                void *rttcb_cls);
1379
1380#endif
1381