• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
274 struct SPDY_Daemon;
275 
276 
277 /**
278  * Handle for a SPDY session/connection.
279  */
280 struct 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  */
287 struct 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  */
295 struct SPDY_Response;
296 
297 
298 /**
299  * Collection of tuples of an HTTP header and values used in requests
300  * and responses.
301  */
302 struct SPDY_NameValue;
303 
304 
305 /**
306  * Collection of tuples of a SPDY setting ID, value
307  * and flags used to control the sessions.
308  */
309 struct 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  */
318 enum 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  */
346 enum 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  */
401 enum 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  */
427 enum 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  */
493 enum 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  */
520 enum 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  */
545 enum 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  */
561 enum 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  */
591 typedef 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  */
605 typedef 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  */
622 typedef 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  */
637 typedef 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  */
669 typedef 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  */
697 typedef 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  */
723 typedef 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  */
752 typedef 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  */
767 typedef 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  */
784 typedef 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  */
801 typedef 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
835 SPDY_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
854 SPDY_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 *
880 SPDY_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
898 SPDY_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
924 SPDY_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
942 SPDY_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
953 SPDY_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
969 SPDY_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
980 SPDY_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 *
992 SPDY_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
1003 SPDY_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 *
1018 SPDY_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
1032 SPDY_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 *
1047 SPDY_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
1062 SPDY_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
1074 SPDY_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 *
1088 SPDY_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
1099 SPDY_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 *
1112 SPDY_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 *
1143 SPDY_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 *
1183 SPDY_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
1221 SPDY_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
1241 SPDY_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 *
1255 SPDY_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
1272 SPDY_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
1290 SPDY_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
1306 SPDY_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
1319 SPDY_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
1341 SPDY_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
1363 SPDY_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
1376 SPDY_send_ping (struct SPDY_Session *session,
1377                 SPDY_PingCallback rttcb,
1378                 void *rttcb_cls);
1379 
1380 #endif
1381