From 07b02404c3a7d724decd12a7097b59e87b125044 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 14 Mar 2012 00:32:52 +0900 Subject: [PATCH] Added API reference generator script. Formatted the public APIs with Sphinx syntax. --- Makefile.am | 2 +- configure.ac | 2 + doc/.gitignore | 3 + doc/Makefile.am | 158 ++++ doc/README.rst | 160 ++++ doc/apiref-header.rst | 9 + doc/{conf.py => conf.py.in} | 32 +- doc/index.rst | 19 +- doc/mkapiref.py | 205 +++++ lib/includes/spdylay/spdylay.h | 1200 ++++++++++++++++++++------ lib/includes/spdylay/spdylayver.h.in | 5 +- 11 files changed, 1502 insertions(+), 293 deletions(-) create mode 100644 doc/.gitignore create mode 100644 doc/Makefile.am create mode 100644 doc/README.rst create mode 100644 doc/apiref-header.rst rename doc/{conf.py => conf.py.in} (83%) create mode 100755 doc/mkapiref.py diff --git a/Makefile.am b/Makefile.am index f4c4ecd..ed56474 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,6 +20,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -SUBDIRS = lib examples tests +SUBDIRS = lib examples tests doc ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index 9858e87..dc07f40 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,8 @@ AC_CONFIG_FILES([ lib/includes/spdylay/spdylayver.h tests/Makefile examples/Makefile + doc/Makefile + doc/conf.py ]) AC_OUTPUT diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..65f5f83 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,3 @@ +apiref.rst +conf.py +manual diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..6397ed7 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,158 @@ +# Spdylay - SPDY Library + +# Copyright (c) 2012 Tatsuhiro Tsujikawa + +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = manual + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +apiref.rst: $(top_builddir)/lib/includes/spdylay/spdylayver.h \ + $(top_builddir)/lib/includes/spdylay/spdylay.h + $(builddir)/mkapiref.py --header apiref-header.rst $^ > $@ + +clean: + -rm apiref.rst + -rm -rf $(BUILDDIR)/* + +html: apiref.rst + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Spdylay.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Spdylay.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Spdylay" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Spdylay" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/README.rst b/doc/README.rst new file mode 100644 index 0000000..a5647ff --- /dev/null +++ b/doc/README.rst @@ -0,0 +1,160 @@ +Spdylay Documentation +===================== + +The documentation of Spdylay is generated using Sphinx. This +directory contains the source files to be processed by Sphinx. The +source file for API reference is generated using a script called +``mkapiref.py`` from the Spdylay C source code. + +Generating API reference +------------------------ + +As described earlier, we use ``mkapiref.py`` to generate rst formatted +text of API reference from C source code. The ``mkapiref.py`` is not +so flexible and it requires that C source code is formatted in rather +strict rules. + +To generate API reference, just run ``make html``. It runs +``mkapiref.py`` and then run Sphinx to build the entire document. + +The ``mkapiref.py`` reads C source code and searches the comment block +starts with ``/**``. In other words, it only processes the comment +block starting ``/**``. The comment block must end with ``*/``. The +``mkapiref.py`` requires that which type of the object this comment +block refers to. To specify the type of the object, the next line +must contain the so-caled action keyword. Currently, the following +action keywords are supported: ``@function``, ``@functypedef``, +``@enum``, ``@struct`` and ``@union``. The following sections +describes each action keyword. + +@function +######### + +``@function`` is used to refer to the function. The comment block is +used for the document for the function. After the script sees the end +of the comment block, it consumes the lines as the function +declaration until the line which ends with ``;`` is encountered. + +In Sphinx doc, usually the function argument is formatted like +``*this*``. But in C, ``*`` is used for dereferencing a pointer and +we must escape ``*`` with a back slash. To avoid this, we format the +argument like ``|this|``. The ``mkapiref.py`` translates it with +``*this*``, as escaping ``*`` inside ``|`` and ``|`` as necessary. +Note that this shadows the substitution feature of Sphinx. + +The example follows:: + + /** + * @function + * + * Submits PING frame to the |session|. + */ + int spdylay_submit_ping(spdylay_session *session); + + +@functypedef +############ + +``@functypedef`` is used to refer to the typedef of the function +pointer. The formatting rule is pretty much the same with +``@function``, but this outputs ``type`` domain, rather than +``function`` domain. + +The example follows:: + + /** + * @functypedef + * + * Callback function invoked when |session| wants to send data to + * remote peer. + */ + typedef ssize_t (*spdylay_send_callback) + (spdylay_session *session, + const uint8_t *data, size_t length, int flags, void *user_data); + +@enum +##### + +``@enum`` is used to refer to the enum. Currently, only enum typedefs +are supported. The comment block is used for the document for the +enum type itself. To document each values, put comment block starting +with the line ``/**`` and ending with the ``*/`` just before the enum +value. When the line starts with ``}`` is encountered, the +``mkapiref.py`` extracts strings next to ``}`` as the name of enum. + +At the time of this writing, Sphinx does not support enum type. So we +use ``type`` domain for enum it self and ``macro`` domain for each +value. To refer to the enum value, use ``:enum:`` pseudo role. The +``mkapiref.py`` replaces it with ``:macro:``. By doing this, when +Sphinx will support enum officially, we can replace ``:enum:`` with +the official role easily. + +The example follows:: + + /** + * @enum + * Error codes used in the Spdylay library. + */ + typedef enum { + /** + * Invalid argument passed. + */ + SPDYLAY_ERR_INVALID_ARGUMENT = -501, + /** + * Zlib error. + */ + SPDYLAY_ERR_ZLIB = -502, + } spdylay_error; + +@struct +####### + +``@struct`` is used to refer to the struct. Currently, only struct +typedefs are supported. The comment block is used for the document for +the struct type itself.To document each member, put comment block +starting with the line ``/**`` and ending with the ``*/`` just before +the member. When the line starts with ``}`` is encountered, the +``mkapiref.py`` extracts strings next to ``}`` as the name of struct. +The block-less typedef is also supported. In this case, typedef +declaration must be all in one line and the ``mkapiref.py`` uses last +word as the name of struct. + +Some examples follow:: + + /** + * @struct + * The control frame header. + */ + typedef struct { + /** + * SPDY protocol version. + */ + uint16_t version; + /** + * The type of this control frame. + */ + uint16_t type; + /** + * The control frame flags. + */ + uint8_t flags; + /** + * The length field of this control frame. + */ + int32_t length; + } spdylay_ctrl_hd; + + /** + * @struct + * + * The primary structure to hold the resources needed for a SPDY + * session. The details of this structure is hidden from the public + * API. + */ + typedef struct spdylay_session spdylay_session; + +@union +====== + +``@union`` is used to refer to the union. Currently, ``@union`` is an +alias of ``@struct``. diff --git a/doc/apiref-header.rst b/doc/apiref-header.rst new file mode 100644 index 0000000..cdd836f --- /dev/null +++ b/doc/apiref-header.rst @@ -0,0 +1,9 @@ +API Reference +============= + +Includes +-------- + +To use the public APIs, include ``spdylay/spdylay.h``:: + + #include diff --git a/doc/conf.py b/doc/conf.py.in similarity index 83% rename from doc/conf.py rename to doc/conf.py.in index aca51b6..81d83a1 100644 --- a/doc/conf.py +++ b/doc/conf.py.in @@ -1,4 +1,27 @@ # -*- coding: utf-8 -*- +# Spdylay - SPDY Library + +# Copyright (c) 2012 Tatsuhiro Tsujikawa + +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + # # Spdylay documentation build configuration file, created by # sphinx-quickstart on Sun Mar 11 22:57:49 2012. @@ -48,9 +71,9 @@ copyright = u'2012, Tatsuhiro Tsujikawa' # built documents. # # The short X.Y version. -version = '0.1.0' +version = '@PACKAGE_VERSION@' # The full version, including alpha/beta/rc tags. -release = '0.1.0' +release = '@PACKAGE_VERSION@' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -64,7 +87,7 @@ release = '0.1.0' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ['manual', 'README.rst', '*-header.rst'] # The reST default role (used for this markup: `text`) to use for all documents. default_role = 'c:func' @@ -81,6 +104,9 @@ primary_domain = 'c' # output. They are ignored by default. #show_authors = False +# The default language to highlight source code in. The default is 'python'. +highlight_language = 'c' + # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' diff --git a/doc/index.rst b/doc/index.rst index 4308764..f29e4ec 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -6,15 +6,20 @@ Welcome to Spdylay's documentation! =================================== +This is an experimental implementation of Google's SPDY protocol +version 2 and 3 in C. + +This library provides SPDY framing layer implementation. It does not +perform any I/O operations. When the library needs them, it calls the +callback functions provided by the application. It also does not +include any event polling mechanism, so the application can freely +choose the way of handling events. This library code does not depend +on any particular SSL library (except for example programs which +depend on OpenSSL 1.0.1 or later). + Contents: .. toctree:: :maxdepth: 2 -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - + apiref diff --git a/doc/mkapiref.py b/doc/mkapiref.py new file mode 100755 index 0000000..a0c9553 --- /dev/null +++ b/doc/mkapiref.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# Spdylay - SPDY Library + +# Copyright (c) 2012 Tatsuhiro Tsujikawa + +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Generates API reference from C source code. +import re, sys, argparse + +class FunctionDoc: + def __init__(self, name, content, domain): + self.name = name + self.content = content + self.domain = domain + + def write(self, out): + print '''.. {}:: {}'''.format(self.domain, self.name) + print '' + for line in self.content: + print ' {}'.format(line) + +class StructDoc: + def __init__(self, name, content, members, member_domain): + self.name = name + self.content = content + self.members = members + self.member_domain = member_domain + + def write(self, out): + if self.name: + print '''.. type:: {}'''.format(self.name) + print '' + for line in self.content: + print ' {}'.format(line) + print '' + for name, content in self.members: + print ''' .. {}:: {}'''.format(self.member_domain, name) + print '' + for line in content: + print ''' {}'''.format(line) + print '' + +class MacroDoc: + def __init__(self, name, content): + self.name = name + self.content = content + + def write(self, out): + print '''.. macro:: {}'''.format(self.name) + print '' + for line in self.content: + print ' {}'.format(line) + +def make_api_ref(infiles): + macros = [] + enums = [] + types = [] + functions = [] + for infile in infiles: + while True: + line = infile.readline() + if not line: + break + elif line == '/**\n': + line = infile.readline() + doctype = line.split()[1] + if doctype == '@function': + functions.append(process_function('function', infile)) + elif doctype == '@functypedef': + types.append(process_function('type', infile)) + elif doctype == '@struct' or doctype == '@union': + types.append(process_struct(infile)) + elif doctype == '@enum': + enums.append(process_enum(infile)) + elif doctype == '@macro': + macros.append(process_macro(infile)) + alldocs = [('Macros', macros), + ('Enums', enums), + ('Types (structs, unions and typedefs)', types), + ('Functions', functions)] + for title, docs in alldocs: + if not docs: + continue + print title + print '-'*len(title) + for doc in docs: + doc.write(sys.stdout) + print '' + print '' + +def process_macro(infile): + content = read_content(infile) + line = infile.readline() + macro_name = line.split()[1] + return MacroDoc(macro_name, content) + +def process_enum(infile): + members = [] + enum_name = None + content = read_content(infile) + while True: + line = infile.readline() + if not line: + break + elif re.match(r'\s*/\*\*\n', line): + member_content = read_content(infile) + line = infile.readline() + member_name = line.split()[0] + members.append((member_name, member_content)) + elif line.startswith('}'): + enum_name = line.rstrip().split()[1] + enum_name = re.sub(r';$', '', enum_name) + break + return StructDoc(enum_name, content, members, 'macro') + +def process_struct(infile): + members = [] + struct_name = None + content = read_content(infile) + while True: + line = infile.readline() + if not line: + break + elif re.match(r'\s*/\*\*\n', line): + member_content = read_content(infile) + line = infile.readline() + member_name = line.rstrip().rstrip(';') + members.append((member_name, member_content)) + elif line.startswith('}') or\ + (line.startswith('typedef ') and line.endswith(';\n')): + if line.startswith('}'): + index = 1 + else: + index = 3 + struct_name = line.rstrip().split()[index] + struct_name = re.sub(r';$', '', struct_name) + break + return StructDoc(struct_name, content, members, 'member') + +def process_function(domain, infile): + content = read_content(infile) + func_proto = [] + while True: + line = infile.readline() + if not line: + break + elif line == '\n': + break + else: + func_proto.append(line) + func_proto = ''.join(func_proto) + func_proto = re.sub(r';\n$', '', func_proto) + func_proto = re.sub(r'\s+', ' ', func_proto) + return FunctionDoc(func_proto, content, domain) + +def read_content(infile): + content = [] + while True: + line = infile.readline() + if not line: + break + if re.match(r'\s*\*/\n', line): + break + else: + content.append(transform_content(line.rstrip())) + return content + +def arg_repl(matchobj): + return '*{}*'.format(matchobj.group(1).replace('*', '\\*')) + +def transform_content(content): + content = re.sub(r'^\s+\* ?', '', content) + content = re.sub(r'\|([^\s|]+)\|', arg_repl, content) + content = re.sub(r':enum:', ':macro:', content) + return content + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Generate API reference") + parser.add_argument('--header', type=argparse.FileType('rb', 0), + help='header inserted at the top of the page') + parser.add_argument('files', nargs='+', type=argparse.FileType('rb', 0), + help='source file') + args = parser.parse_args() + if args.header: + print args.header.read() + for infile in args.files: + make_api_ref(args.files) diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h index f68c11d..e0e60f4 100644 --- a/lib/includes/spdylay/spdylay.h +++ b/lib/includes/spdylay/spdylay.h @@ -36,64 +36,126 @@ extern "C" { #include struct spdylay_session; +/** + * @struct + * + * The primary structure to hold the resources needed for a SPDY + * session. The details of this structure is hidden from the public + * API. + */ typedef struct spdylay_session spdylay_session; -/* SPDY protocol version 2 */ +/** + * @macro + * + * SPDY protocol version 2 + */ #define SPDYLAY_PROTO_SPDY2 2 -/* SPDY protocol version 3 */ +/** + * @macro + * + * SPDY protocol version 3 + */ #define SPDYLAY_PROTO_SPDY3 3 +/** + * @enum + * + * Error codes used in the Spdylay library. The following values are + * defined: + */ typedef enum { - /* Invalid argument passed. */ + /** + * Invalid argument passed. + */ SPDYLAY_ERR_INVALID_ARGUMENT = -501, - /* Zlib error. */ + /** + * Zlib error. + */ SPDYLAY_ERR_ZLIB = -502, - /* The specified protocol version is not supported. */ + /** + * The specified protocol version is not supported. + */ SPDYLAY_ERR_UNSUPPORTED_VERSION = -503, - /* Used as a return value from spdylay_send_callback and - spdylay_recv_callback to indicate that the operation would - block. */ + /** + * Used as a return value from :type:`spdylay_send_callback` and + * :type:`spdylay_recv_callback` to indicate that the operation + * would block. + */ SPDYLAY_ERR_WOULDBLOCK = -504, - /* General protocol error */ + /** + * General protocol error + */ SPDYLAY_ERR_PROTO = -505, - /* The frame is invalid. */ + /** + * The frame is invalid. + */ SPDYLAY_ERR_INVALID_FRAME = -506, - /* The peer performed a shutdown on the connection. */ + /** + * The peer performed a shutdown on the connection. + */ SPDYLAY_ERR_EOF = -507, - /* Used as a return value from spdylay_data_source_read_callback to - indicate that data transfer is postponed. See - spdylay_data_source_read_callback for details. */ + /** + * Used as a return value from + * :func:`spdylay_data_source_read_callback` to indicate that data + * transfer is postponed. See + * :func:`spdylay_data_source_read_callback` for details. + */ SPDYLAY_ERR_DEFERRED = -508, - /* Stream ID has reached maximum value. Therefore no stream ID is - available. */ + /** + * Stream ID has reached maximum value. Therefore no stream ID is + * available. + */ SPDYLAY_ERR_STREAM_ID_NOT_AVAILABLE = -509, - /* The stream is already closed or it does not exist. */ + /** + * The stream is already closed; or the stream ID is invalid. + */ SPDYLAY_ERR_STREAM_CLOSED = -510, - /* RST_STREAM has been queued in outbound queue. The stream is in - closing state. */ + /** + * RST_STREAM has been queued in outbound queue. The stream is in + * closing state. + */ SPDYLAY_ERR_STREAM_CLOSING = -511, - /* The transmission is not allowed for this stream (e.g., a frame - with FIN flag set has already sent) */ + /** + * The transmission is not allowed for this stream (e.g., a frame + * with FIN flag set has already sent). + */ SPDYLAY_ERR_STREAM_SHUT_WR = -512, - /* The stream ID is invalid. */ + /** + * The stream ID is invalid. + */ SPDYLAY_ERR_INVALID_STREAM_ID = -513, - /* The state of the stream is not valid (e.g., SYN_REPLY cannot be - sent to the stream where SYN_REPLY has been already sent). */ + /** + * The state of the stream is not valid (e.g., SYN_REPLY cannot be + * sent to the stream where SYN_REPLY has been already sent). + */ SPDYLAY_ERR_INVALID_STREAM_STATE = -514, - /* Another DATA frame has already been deferred. */ + /** + * Another DATA frame has already been deferred. + */ SPDYLAY_ERR_DEFERRED_DATA_EXIST = -515, - /* SYN_STREAM is not allowed. (e.g., GOAWAY has been sent and/or - received. */ + /** + * SYN_STREAM is not allowed. (e.g., GOAWAY has been sent and/or + * received. + */ SPDYLAY_ERR_SYN_STREAM_NOT_ALLOWED = -516, - /* GOAWAY has been already sent. */ + /** + * GOAWAY has been already sent. + */ SPDYLAY_ERR_GOAWAY_ALREADY_SENT = -517, - /* The errors < SPDYLAY_ERR_FATAL mean that the library is under - unexpected condition that it cannot process any further data - reliably (e.g., out of memory). */ + /** + * The errors < :enum:`SPDYLAY_ERR_FATAL` mean that the library is + * under unexpected condition that it cannot process any further + * data reliably (e.g., out of memory). + */ SPDYLAY_ERR_FATAL = -900, - /* Out of memory. */ + /** + * Out of memory. This is a fatal error. + */ SPDYLAY_ERR_NOMEM = -901, - /* The user callback function failed. */ + /** + * The user callback function failed. This is a fatal error. + */ SPDYLAY_ERR_CALLBACK_FAILURE = -902, } spdylay_error; @@ -101,165 +163,504 @@ typedef enum { SPDYLAY_MSG_MORE } spdylay_io_flag; +/** + * @enum + * The frame types in SPDY protocol. + */ typedef enum { + /** + * The SYN_STREAM control frame. + */ SPDYLAY_SYN_STREAM = 1, + /** + * The SYN_REPLY control frame. + */ SPDYLAY_SYN_REPLY = 2, + /** + * The RST_STREAM control frame. + */ SPDYLAY_RST_STREAM = 3, + /** + * The SETTINGS control frame. + */ SPDYLAY_SETTINGS = 4, + /** + * The NOOP control frame. This is deprecated in SPDY/3. + */ SPDYLAY_NOOP = 5, + /** + * The PING control frame. + */ SPDYLAY_PING = 6, + /** + * The GOAWAY control frame. + */ SPDYLAY_GOAWAY = 7, + /** + * The HEADERS control frame. + */ SPDYLAY_HEADERS = 8, - /* Since SPDY/3 */ + /** + * The WINDOW_UPDATE control frame. This was first appeard in + * SPDY/3. + */ SPDYLAY_WINDOW_UPDATE = 9, + /** + * The DATA frame. + */ SPDYLAY_DATA = 100, } spdylay_frame_type; +/** + * @enum + * + * The flags for a control frame. + */ typedef enum { + /** + * No flag set. + */ SPDYLAY_CTRL_FLAG_NONE = 0, + /** + * FLAG_FIN flag. + */ SPDYLAY_CTRL_FLAG_FIN = 0x1, + /** + * FLAG_UNIDIRECTIONAL flag. + */ SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL = 0x2 } spdylay_ctrl_flag; +/** + * @enum + * The flags for a DATA frame. + */ typedef enum { + /** + * No flag set. + */ SPDYLAY_DATA_FLAG_NONE = 0, + /** + * FLAG_FIN flag. + */ SPDYLAY_DATA_FLAG_FIN = 0x1 } spdylay_data_flag; +/** + * @enum + * The flags for the SETTINGS control frame. + */ typedef enum { + /** + * No flag set. + */ SPDYLAY_FLAG_SETTINGS_NONE = 0, + /** + * SETTINGS_CLEAR_SETTINGS flag. + */ SPDYLAY_FLAG_SETTINGS_CLEAR_SETTINGS = 1 } spdylay_settings_flag; +/** + * @enum + * The flags for SETTINGS ID/value pair. + */ typedef enum { + /** + * No flag set. + */ SPDYLAY_ID_FLAG_SETTINGS_NONE = 0, + /** + * FLAG_SETTINGS_PERSIST_VALUE flag. + */ SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE = 1, + /** + * FLAG_SETTINGS_PERSISTED flag. + */ SPDYLAY_ID_FLAG_SETTINGS_PERSISTED = 2 } spdylay_settings_id_flag; +/** + * @enum + * The SETTINGS ID. + */ typedef enum { + /** + * SETTINGS_UPLOAD_BANDWIDTH + */ SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH = 1, + /** + * SETTINGS_DOWNLOAD_BANDWIDTH + */ SPDYLAY_SETTINGS_DOWNLOAD_BANDWIDTH = 2, + /** + * SETTINGS_ROUND_TRIP_TIME + */ SPDYLAY_SETTINGS_ROUND_TRIP_TIME = 3, + /** + * SETTINGS_MAX_CONCURRENT_STREAMS + */ SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS = 4, + /** + * SETTINGS_CURRENT_CWND + */ SPDYLAY_SETTINGS_CURRENT_CWND = 5, + /** + * SETTINGS_DOWNLOAD_RETRANS_RATE + */ SPDYLAY_SETTINGS_DOWNLOAD_RETRANS_RATE = 6, + /** + * SETTINGS_INITIAL_WINDOW_SIZE + */ SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE = 7, - /* This first appeared in SPDY/3 */ + /** + * SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE. This was first appeared + * in SPDY/3. + */ SPDYLAY_SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8 } spdylay_settings_id; -/* Maximum ID of spdylay_settings_id. */ +/** + * @macro + * Maximum ID of :type:`spdylay_settings_id`. + */ #define SPDYLAY_SETTINGS_MAX 8 -/* Default maximum concurrent streams */ +/** + * @macro + * Default maximum concurrent streams. + */ #define SPDYLAY_INITIAL_MAX_CONCURRENT_STREAMS 100 -/* Status code for RST_STREAM */ +/** + * @enum + * The status codes for RST_STREAM control frame. + */ typedef enum { - /* SPDYLAY_OK is not valid status code for RST_STREAM. It is defined - just for spdylay library use. */ + /** + * SPDYLAY_OK is not valid status code for RST_STREAM. It is defined + * just for spdylay library use. + */ SPDYLAY_OK = 0, + /** + * PROTOCOL_ERROR + */ SPDYLAY_PROTOCOL_ERROR = 1, + /** + * INVALID_STREAM + */ SPDYLAY_INVALID_STREAM = 2, + /** + * REFUSED_STREAM + */ SPDYLAY_REFUSED_STREAM = 3, + /** + * UNSUPPORTED_VERSION + */ SPDYLAY_UNSUPPORTED_VERSION = 4, + /** + * CANCEL + */ SPDYLAY_CANCEL = 5, + /** + * INTERNAL_ERROR + */ SPDYLAY_INTERNAL_ERROR = 6, + /** + * FLOW_CONTROL_ERROR + */ SPDYLAY_FLOW_CONTROL_ERROR = 7, /* Following status codes were introduced in SPDY/3 */ + /** + * STREAM_IN_USE + */ SPDYLAY_STREAM_IN_USE = 8, + /** + * STREAM_ALREADY_CLOSED + */ SPDYLAY_STREAM_ALREADY_CLOSED = 9, + /** + * SPDYLAY_INVALID_CREDENTIALS + */ SPDYLAY_INVALID_CREDENTIALS = 10, + /** + * FRAME_TOO_LARGE + */ FRAME_TOO_LARGE = 11 } spdylay_status_code; -/* Status code for GOAWAY, introduced in SPDY/3 */ +/** + * @enum + * The status codes for GOAWAY, introduced in SPDY/3 + */ typedef enum { + /** + * OK. This indicates a normal session teardown. + */ SPDYLAY_GOAWAY_OK = 0, + /** + * PROTOCOL_ERROR + */ SPDYLAY_GOAWAY_PROTOCOL_ERROR = 1, + /** + * INTERNAL_ERROR + */ SPDYLAY_GOAWAY_INTERNAL_ERROR = 11 } spdylay_goaway_status_code; +/** + * @macro + * Lowest priority value in SPDY/2. + */ #define SPDYLAY_SPDY2_PRI_LOWEST 3 +/** + * @macro + * Lowest priority value in SPDY/3. + */ #define SPDYLAY_SPDY3_PRI_LOWEST 7 +/** + * @struct + * The control frame header. + */ typedef struct { + /** + * SPDY protocol version. + */ uint16_t version; + /** + * The type of this control frame. + */ uint16_t type; + /** + * The control frame flags. + */ uint8_t flags; + /** + * The length field of this control frame. + */ int32_t length; } spdylay_ctrl_hd; +/** + * @struct + * The SYN_STREAM control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The stream ID. + */ int32_t stream_id; + /** + * The associated-to-stream ID. 0 if this frame has no + * associated-to-stream. + */ int32_t assoc_stream_id; - /* 0 (Highest) to SPDYLAY_SPDY2_PRI_LOWEST or - SPDYLAY_SPDY3_PRI_LOWEST (lowest), depending on the protocol - version. */ + /** + * The priority of this frame. 0 (Highest) to + * :macro:`SPDYLAY_SPDY2_PRI_LOWEST` or + * :macro:`SPDYLAY_SPDY3_PRI_LOWEST` (lowest), depending on the + * protocol version. + */ uint8_t pri; - /* Since SPDY/3 */ + /** + * The index in server's CREDENTIAL vector of the client certificate. + * This was introduced in SPDY/3. + */ uint8_t slot; + /** + * The name/value pairs. For i > 0, ``nv[2*i]`` contains a pointer + * to the name string and ``nv[2*i+1]`` contains a pointer to the + * value string. The one beyond last value must be ``NULL``. That + * is, if the |nv| contains N name/value pairs, ``nv[2*N]`` must be + * ``NULL``. + */ char **nv; } spdylay_syn_stream; +/** + * @struct + * The SYN_REPLY control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The stream ID. + */ int32_t stream_id; + /** + * The name/value pairs. For i > 0, ``nv[2*i]`` contains a pointer + * to the name string and ``nv[2*i+1]`` contains a pointer to the + * value string. The one beyond last value must be ``NULL``. That + * is, if the |nv| contains N name/value pairs, ``nv[2*N]`` must be + * ``NULL``. + */ char **nv; } spdylay_syn_reply; +/** + * @struct + * The HEADERS control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The stream ID. + */ int32_t stream_id; + /** + * The name/value pairs. For i > 0, ``nv[2*i]`` contains a pointer + * to the name string and ``nv[2*i+1]`` contains a pointer to the + * value string. The one beyond last value must be ``NULL``. That + * is, if the |nv| contains N name/value pairs, ``nv[2*N]`` must be + * ``NULL``. + */ char **nv; } spdylay_headers; +/** + * @struct + * The RST_STREAM control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The stream ID. + */ int32_t stream_id; + /** + * The status code. See :type:`spdylay_status_code`. + */ uint32_t status_code; } spdylay_rst_stream; +/** + * @struct + * The SETTINGS ID/Value pair. It has the following members: + */ typedef struct { + /** + * The SETTINGS ID. See :type:`spdylay_settings_id`. + */ int32_t settings_id; + /** + * The flags. See :type:`spdylay_settings_id_flag`. + */ uint8_t flags; + /** + * The value of this entry. + */ uint32_t value; } spdylay_settings_entry; +/** + * @struct + * The SETTINGS control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; - /* Number of entries in |iv| */ + /** + * The number of SETTINGS ID/Value pairs in |iv|. + */ size_t niv; + /** + * The pointer to the array of SETTINGS ID/Value pair. + */ spdylay_settings_entry *iv; } spdylay_settings; +/** + * @struct + * The PING control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The unique ID. + */ uint32_t unique_id; } spdylay_ping; +/** + * @struct + * The GOAWAY control frame. It has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The last-good-stream ID. + */ int32_t last_good_stream_id; - /* Since SPDY/3 */ + /** + * The status code. It was introduced in SPDY/3. See + * :type:`spdylay_goaway_status_code`. + */ uint32_t status_code; } spdylay_goaway; -/* WINDOW_UPDATE is introduced since SPDY/3 */ +/** + * @struct + * + * The WINDOW_UPDATE control frame. It was introduced in SPDY/3. It + * has the following members: + */ typedef struct { + /** + * The control frame header. + */ spdylay_ctrl_hd hd; + /** + * The stream ID. + */ int32_t stream_id; + /** + * The delta-window-size. + */ int32_t delta_window_size; } spdylay_window_update; +/** + * @union + * + * This union represents the some kind of data source passed to + * :type:`spdylay_data_source_read_callback`. + */ typedef union { + /** + * The integer field, suitable for a file descriptor. + */ int fd; + /** + * The pointer to an arbitrary object. + */ void *ptr; } spdylay_data_source; -/* +/** + * @functypedef + * * Callback function invoked when the library wants to read data from * |source|. The read data is sent in the stream |stream_id|. The * implementation of this function must read at most |length| bytes of @@ -267,175 +668,316 @@ typedef union { * |buf| and return number of data stored in |buf|. If EOF is reached, * set |*eof| to 1. If the application wants to postpone DATA frames, * (e.g., asynchronous I/O, or reading data blocks for long time), it - * is achieved by returning SPDYLAY_ERR_DEFERRED without reading any - * data in this invocation. The library removes DATA frame from - * outgoing queue temporarily. To move back deferred DATA frame to - * outgoing queue, call spdylay_session_resume_data(). In case of - * error, return SPDYLAY_ERR_CALLBACK_FAILURE, which leads to session - * failure. + * is achieved by returning :enum:`SPDYLAY_ERR_DEFERRED` without + * reading any data in this invocation. The library removes DATA + * frame from the outgoing queue temporarily. To move back deferred + * DATA frame to outgoing queue, call `spdylay_session_resume_data()`. + * In case of error, return :enum:`SPDYLAY_ERR_CALLBACK_FAILURE`, + * which leads to session failure. */ typedef ssize_t (*spdylay_data_source_read_callback) (spdylay_session *session, int32_t stream_id, uint8_t *buf, size_t length, int *eof, spdylay_data_source *source, void *user_data); +/** + * @struct + * + * This struct represents the data source and the way to read a chunk + * of data from it. + */ typedef struct { + /** + * The data source. + */ spdylay_data_source source; + /** + * The callback function to read a chunk of data from |source|. + */ spdylay_data_source_read_callback read_callback; } spdylay_data_provider; +/** + * @struct + * The DATA frame. It has the following members: + */ typedef struct { + /** + * The stream ID. + */ int32_t stream_id; + /** + * The DATA frame flags. See :type:`spdylay_data_flag`. + */ uint8_t flags; - /* Initially eof is 0. It becomes 1 if all data are read. */ + /** + * The flag to indicate whether EOF was reached or not. Initially + * |eof| is 0. It becomes 1 after all data were read. + */ uint8_t eof; + /** + * The data to be sent for this DATA frame. + */ spdylay_data_provider data_prd; } spdylay_data; +/** + * @union + * + * This union includes all control frames and DATA frame to pass them + * to various function calls as spdylay_frame type. + */ typedef union { + /** + * The SYN_STREAM control frame. + */ spdylay_syn_stream syn_stream; + /** + * The SYN_REPLY control frame. + */ spdylay_syn_reply syn_reply; + /** + * The RST_STREAM control frame. + */ spdylay_rst_stream rst_stream; + /** + * The SETTINGS control frame. + */ spdylay_settings settings; + /** + * The PING control frame. + */ spdylay_ping ping; + /** + * The GOAWAY control frame. + */ spdylay_goaway goaway; + /** + * The HEADERS control frame. + */ spdylay_headers headers; - /* Since SPDY/3 */ + /** + * The WINDOW_UPDATE control frame. + */ spdylay_window_update window_update; + /** + * The DATA frame. + */ spdylay_data data; } spdylay_frame; -/* - * Callback function invoked when |session| want to send data to +/** + * @functypedef + * + * Callback function invoked when |session| wants to send data to the * remote peer. The implementation of this function must send at most * |length| bytes of data stored in |data|. It must return the number * of bytes sent if it succeeds. If it cannot send any single byte - * without blocking, it must return SPDYLAY_ERR_WOULDBLOCK. For other - * errors, it must return SPDYLAY_ERR_CALLBACK_FAILURE. + * without blocking, it must return + * :enum:`SPDYLAY_ERR_WOULDBLOCK`. For other errors, it must return + * :enum:`SPDYLAY_ERR_CALLBACK_FAILURE`. */ typedef ssize_t (*spdylay_send_callback) (spdylay_session *session, const uint8_t *data, size_t length, int flags, void *user_data); -/* - * Callback function invoked when |session| want to receive data from - * remote peer. The implementation of this function must read at most - * |length| bytes of data and store it in |buf|. It must return the - * number of bytes written in |buf| if it succeeds. If it cannot read - * any single byte without blocking, it must return - * SPDYLAY_ERR_WOULDBLOCK. If it gets EOF before it reads any single - * byte, it must return SPDYLAY_ERR_EOF. For other errors, it must - * return SPDYLAY_ERR_CALLBACK_FAILURE. +/** + * @functypedef + * + * Callback function invoked when |session| wants to receive data from + * the remote peer. The implementation of this function must read at + * most |length| bytes of data and store it in |buf|. It must return + * the number of bytes written in |buf| if it succeeds. If it cannot + * read any single byte without blocking, it must return + * :enum:`SPDYLAY_ERR_WOULDBLOCK`. If it gets EOF before it reads any + * single byte, it must return :enum:`SPDYLAY_ERR_EOF`. For other + * errors, it must return :enum:`SPDYLAY_ERR_CALLBACK_FAILURE`. */ typedef ssize_t (*spdylay_recv_callback) (spdylay_session *session, uint8_t *buf, size_t length, int flags, void *user_data); -/* - * Callback function invoked by spdylay_session_recv() when a control - * frame is arrived. +/** + * @functypedef + * + * Callback function invoked by `spdylay_session_recv()` when a + * control frame is arrived. */ typedef void (*spdylay_on_ctrl_recv_callback) (spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, void *user_data); -/* - * Callback function invoked by spdylay_session_recv() when an invalid - * control frame is arrived, which typically the case where RST_STREAM - * will be sent +/** + * @functypedef + * + * Callback function invoked by `spdylay_session_recv()` when an + * invalid control frame is arrived. When this callback function is + * invoked, either RST_STREAM or GOAWAY will be sent. */ typedef void (*spdylay_on_invalid_ctrl_recv_callback) (spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, void *user_data); -/* - * Callback function invoked when data chunk of DATA frame is - * received. |stream_id| is the stream ID of this DATA frame belongs - * to. |flags| is the flags of DATA frame which this data chunk is - * contained. flags & SPDYLAY_DATA_FLAG_FIN does not necessarily mean - * this chunk of data is the last one in the stream. You should use - * spdylay_on_data_recv_callback to know all data frames are received. +/** + * @functypedef + * + * Callback function invoked when a chunk of data in DATA frame is + * received. The |stream_id| is the stream ID of this DATA frame + * belongs to. The |flags| is the flags of DATA frame which this data + * chunk is contained. ``(flags & SPDYLAY_DATA_FLAG_FIN) != 0`` does + * not necessarily mean this chunk of data is the last one in the + * stream. You should use :type:`spdylay_on_data_recv_callback` to + * know all data frames are received. */ typedef void (*spdylay_on_data_chunk_recv_callback) (spdylay_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data); -/* +/** + * @functypedef + * * Callback function invoked when DATA frame is received. The actual - * data it contains are received by spdylay_on_data_recv_callback. + * data it contains are received by + * :type:`spdylay_on_data_chunk_recv_callback`. */ typedef void (*spdylay_on_data_recv_callback) (spdylay_session *session, uint8_t flags, int32_t stream_id, int32_t length, void *user_data); -/* - * Callback function invoked after frame |frame| of type |type| is - * sent. +/** + * @functypedef + * + * Callback function invoked before the control frame |frame| of type + * |type| is sent. This may be useful, for example, to know the stream + * ID of SYN_STREAM frame (see also + * `spdylay_session_get_stream_user_data()`), which is not assigned + * when it was queued. + */ +typedef void (*spdylay_before_ctrl_send_callback) +(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, + void *user_data); + +/** + * @functypedef + * + * Callback function invoked after the control frame |frame| of type + * |type| is sent. */ typedef void (*spdylay_on_ctrl_send_callback) (spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, void *user_data); -/* +/** + * @functypedef + * * Callback function invoked after the control frame |frame| of type * |type| is not sent because of the error. The error is indicated by - * the |error|, which is one of the values defined in spdylay_error. + * the |error|, which is one of the values defined in + * :type:`spdylay_error`. */ typedef void (*spdylay_on_ctrl_not_send_callback) (spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, int error, void *user_data); -/* +/** + * @functypedef + * * Callback function invoked after DATA frame is sent. */ typedef void (*spdylay_on_data_send_callback) (spdylay_session *session, uint8_t flags, int32_t stream_id, int32_t length, void *user_data); -/* - * Callback function invoked before frame |frame| of type |type| is - * sent. This may be useful, for example, to know the stream ID of - * SYN_STREAM frame (see also spdylay_session_get_stream_user_data), - * which is not assigned when it was queued. - */ -typedef void (*spdylay_before_ctrl_send_callback) -(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame, - void *user_data); - -/* - * Callback function invoked when stream |stream_id| is closed. The - * reason of closure is indicated by |status_code|. stream_user_data - * is still available in this function. +/** + * @functypedef + * + * Callback function invoked when the stream |stream_id| is + * closed. The reason of closure is indicated by the + * |status_code|. The stream_user_data, which was specified in + * `spdylay_submit_request()` or `spdylay_submit_syn_stream()`, is + * still available in this function. */ typedef void (*spdylay_on_stream_close_callback) (spdylay_session *session, int32_t stream_id, spdylay_status_code status_code, void *user_data); -/* - * Callback function invoked when request from remote peer is - * received. In other words, frame with FIN flag set is received. In - * HTTP, this means HTTP request, including request body, is fully +/** + * @functypedef + * + * Callback function invoked when request from the remote peer is + * received. In other words, the frame with FIN flag set is received. + * In HTTP, this means HTTP request, including request body, is fully * received. */ typedef void (*spdylay_on_request_recv_callback) (spdylay_session *session, int32_t stream_id, void *user_data); +/** + * @struct + * + * Callback functions. + */ typedef struct { + /** + * Callback function invoked when |session| wants to send data to + * the remote peer. + */ spdylay_send_callback send_callback; + /** + * Callback function invoked when |session| wants to receive data + * from the remote peer. + */ spdylay_recv_callback recv_callback; + /** + * Callback function invoked by `spdylay_session_recv()` when a + * control frame is arrived. + */ spdylay_on_ctrl_recv_callback on_ctrl_recv_callback; + /** + * Callback function invoked by `spdylay_session_recv()` when an + * invalid control frame is arrived. + */ spdylay_on_invalid_ctrl_recv_callback on_invalid_ctrl_recv_callback; + /** + * Callback function invoked when a chunk of data in DATA frame is + * received. + */ spdylay_on_data_chunk_recv_callback on_data_chunk_recv_callback; + /** + * Callback function invoked when DATA frame is received. + */ spdylay_on_data_recv_callback on_data_recv_callback; + /** + * Callback function invoked before the control frame is sent. + */ spdylay_before_ctrl_send_callback before_ctrl_send_callback; + /** + * Callback function invoked after the control frame is sent. + */ spdylay_on_ctrl_send_callback on_ctrl_send_callback; + /** + * The callback function invoked when a control frame is not sent + * because of an error. + */ spdylay_on_ctrl_not_send_callback on_ctrl_not_send_callback; + /** + * Callback function invoked after DATA frame is sent. + */ spdylay_on_data_send_callback on_data_send_callback; + /** + * Callback function invoked when the stream is closed. + */ spdylay_on_stream_close_callback on_stream_close_callback; + /** + * Callback function invoked when request from the remote peer is + * received. + */ spdylay_on_request_recv_callback on_request_recv_callback; } spdylay_session_callbacks; -/* +/** + * @function + * * Initializes |*session_ptr| for client use, using the protocol * version |version|. The all members of |callbacks| are copied to * |*session_ptr|. Therefore |*session_ptr| does not store @@ -445,11 +987,11 @@ typedef struct { * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. - * SPDYLAY_ERR_ZLIB + * :enum:`SPDYLAY_ERR_ZLIB` * The z_stream initialization failed. - * SPDYLAY_ERR_UNSUPPORTED_VERSION + * :enum:`SPDYLAY_ERR_UNSUPPORTED_VERSION` * The version is not supported. */ int spdylay_session_client_new(spdylay_session **session_ptr, @@ -457,7 +999,9 @@ int spdylay_session_client_new(spdylay_session **session_ptr, const spdylay_session_callbacks *callbacks, void *user_data); -/* +/** + * @function + * * Initializes |*session_ptr| for server use, using the protocol * version |version|. The all members of |callbacks| are copied to * |*session_ptr|. Therefore |*session_ptr| does not store @@ -467,11 +1011,11 @@ int spdylay_session_client_new(spdylay_session **session_ptr, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. - * SPDYLAY_ERR_ZLIB + * :enum:`SPDYLAY_ERR_ZLIB` * The z_stream initialization failed. - * SPDYLAY_ERR_UNSUPPORTED_VERSION + * :enum:`SPDYLAY_ERR_UNSUPPORTED_VERSION` * The version is not supported. */ int spdylay_session_server_new(spdylay_session **session_ptr, @@ -479,141 +1023,190 @@ int spdylay_session_server_new(spdylay_session **session_ptr, const spdylay_session_callbacks *callbacks, void *user_data); -/* - * Frees any resources allocated for |session|. +/** + * @function + * + * Frees any resources allocated for |session|. If |session| is + * ``NULL``, this function does nothing. */ void spdylay_session_del(spdylay_session *session); -/* +/** + * @function + * * Sends pending frames to the remote peer. * * This function retrieves the highest prioritized frame from the * outbound queue and sends it to the remote peer. It does this as - * many as possible until the user callback send_callback returns - * SPDYLAY_ERR_WOULDBLOCK or the outbound queue becomes empty. This - * function calls several callback functions which are passed when - * initializing the |session|. Here is the simple time chart which - * tells when each callback is invoked: + * many as possible until the user callback + * :member:`spdylay_session_callbacks.send_callback` returns + * :enum:`SPDYLAY_ERR_WOULDBLOCK` or the outbound queue becomes empty. + * This function calls several callback functions which are passed + * when initializing the |session|. Here is the simple time chart + * which tells when each callback is invoked: * * 1. Get the next frame to send from outbound queue. * 2. Prepare transmission of the frame. * 3. If the control frame cannot be sent because some preconditions * are not met (e.g., SYN_STREAM cannot be sent after GOAWAY), - * on_ctrl_not_send_callback is invoked. Skip following steps. + * :member:`spdylay_session_callbacks.on_ctrl_not_send_callback` is + * invoked. Skip following steps. * 4. If the frame is SYN_STREAM, the stream is opened here. - * 5. before_ctrl_send_callback is invoked. - * 6. send_callback is invoked one or more times (while the frame is - * completely sent). - * 7. If the frame is a control frame, on_ctrl_send_callback is invoked. - * 8. If the frame is a DATA frame, on_data_send_callback is invoked. + * 5. :member:`spdylay_session_callbacks.before_ctrl_send_callback` is + * invoked. + * 6. :member:`spdylay_session_callbacks.send_callback` is invoked one + * or more times (while the frame is completely sent). + * 7. If the frame is a control frame, + * :member:`spdylay_session_callbacks.on_ctrl_send_callback` is + * invoked. + * 8. If the frame is a DATA frame, + * :member:`spdylay_session_callbacks.on_data_send_callback` is + * invoked. * 9. If the transmission of the frame triggers closure of the stream, - * the stream is closed and on_stream_close_callback is invoked. + * the stream is closed and + * :member:`spdylay_session_callbacks.on_stream_close_callback` is + * invoked. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. - * SPDYLAY_ERR_CALLBACK_FAILURE + * :enum:`SPDYLAY_ERR_CALLBACK_FAILURE` * The callback function failed. */ int spdylay_session_send(spdylay_session *session); -/* +/** + * @function + * * Receives frames from the remote peer. * * This function receives as many frames as possible until the user - * callback recv_callback returns SPDYLAY_ERR_WOULDBLOCK. This - * function calls several callback functions which are passed when - * initializing the |session|. Here is the simple time chart which - * tells when each callback is invoked: + * callback :member:`spdylay_session_callbacks.recv_callback` returns + * :enum:`SPDYLAY_ERR_WOULDBLOCK`. This function calls several + * callback functions which are passed when initializing the + * |session|. Here is the simple time chart which tells when each + * callback is invoked: * - * 1. recv_callback is invoked one or more times to receive frame header. + * 1. :member:`spdylay_session_callbacks.recv_callback` is invoked one + * or more times to receive frame header. * 2. If the frame is DATA frame: - * 2.1. recv_callback is invoked to receive DATA payload. For each - * chunk of data, on_data_chunk_recv_callback is invoked. - * 2.2. If one DATA frame is completely received, on_data_recv_callback + * + * 2.1. :member:`spdylay_session_callbacks.recv_callback` is invoked + * to receive DATA payload. For each chunk of data, + * :member:`spdylay_session_callbacks.on_data_chunk_recv_callback` * is invoked. - * If the frame is the final frame of the request, - * on_request_recv_callback is invoked. - * If the reception of the frame triggers the closure of the stream, - * on_stream_close_callback is invoked. + * 2.2. If one DATA frame is completely received, + * :member:`spdylay_session_callbacks.on_data_recv_callback` is + * invoked. If the frame is the final frame of the request, + * :member:`spdylay_session_callbacks.on_request_recv_callback` + * is invoked. If the reception of the frame triggers the + * closure of the stream, + * :member:`spdylay_session_callbacks.on_stream_close_callback` + * is invoked. + * * 3. If the frame is the control frame: - * 3.1. recv_callback is invoked one or more times to receive whole frame. - * 3.2. If the received frame is valid, on_ctrl_recv_callback is invoked. - * If the frame is the final frame of the request, - * on_request_recv_callback is invoked. - * If the reception of the frame triggers the closure of the stream, - * on_stream_close_callback is invoked. - * 3.3. If the received frame is unpacked but is interpreted as invalid, - * on_invalid_ctrl_recv_callback is invoked. + * + * 3.1. :member:`spdylay_session_callbacks.recv_callback` is invoked + * one or more times to receive whole frame. + * 3.2. If the received frame is valid, + * :member:`spdylay_session_callbacks.on_ctrl_recv_callback` is + * invoked. If the frame is the final frame of the request, + * :member:`spdylay_session_callbacks.on_request_recv_callback` + * is invoked. If the reception of the frame triggers the + * closure of the stream, + * :member:`spdylay_session_callbacks.on_stream_close_callback` + * is invoked. + * 3.3. If the received frame is unpacked but is interpreted as + * invalid, + * :member:`spdylay_session_callbacks.on_invalid_ctrl_recv_callback` + * is invoked. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_EOF + * :enum:`SPDYLAY_ERR_EOF` * The remote peer did shutdown on the connection. - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. - * SPDYLAY_ERR_CALLBACK_FAILURE + * :enum:`SPDYLAY_ERR_CALLBACK_FAILURE` * The callback function failed. */ int spdylay_session_recv(spdylay_session *session); -/* - * Put back previously deferred DATA frame in the stream |stream_id| - * to outbound queue. +/** + * @function + * + * Puts back previously deferred DATA frame in the stream |stream_id| + * to the outbound queue. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_INVALID_ARGUMENT + * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * The stream does not exist or no deferred data exist. - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_session_resume_data(spdylay_session *session, int32_t stream_id); -/* - * Returns nonzero value if |session| want to receive data from the +/** + * @function + * + * Returns nonzero value if |session| wants to receive data from the * remote peer. * - * If both spdylay_session_want_read() and - * spdylay_session_want_write() return 0, the application should drop - * the connection. + * If both `spdylay_session_want_read()` and + * `spdylay_session_want_write()` return 0, the application should + * drop the connection. */ int spdylay_session_want_read(spdylay_session *session); -/* - * Returns nonzero value if |session| want to send data to the remote - * peer, or 0. +/** + * @function * - * If both spdylay_session_want_read() and - * spdylay_session_want_write() return 0, the application should drop - * the connection. + * Returns nonzero value if |session| wants to send data to the remote + * peer. + * + * If both `spdylay_session_want_read()` and + * `spdylay_session_want_write()` return 0, the application should + * drop the connection. */ int spdylay_session_want_write(spdylay_session *session); -/* +/** + * @function + * * Returns stream_user_data for the stream |stream_id|. The - * stream_user_data is provided by spdylay_submit_request(). If the - * stream is initiated by the remote endpoint, stream_user_data is - * always NULL. If the stream is initiated by the local endpoint and - * NULL is given in spdylay_submit_request(), then this function - * returns NULL. If the stream does not exist, this function returns - * NULL. + * stream_user_data is provided by `spdylay_submit_request()` or + * `spdylay_submit_syn_stream()`. If the stream is initiated by the + * remote endpoint, stream_user_data is always ``NULL``. If the stream + * is initiated by the local endpoint and ``NULL`` is given in + * `spdylay_submit_request()` or `spdylay_submit_syn_stream()`, then + * this function returns ``NULL``. If the stream does not exist, this + * function returns ``NULL``. */ void* spdylay_session_get_stream_user_data(spdylay_session *session, int32_t stream_id); -/* +/** + * @function + * * Submits SYN_STREAM frame and optionally one or more DATA * frames. * - * |pri| is priority of this request. 0 is the highest priority. If - * the |session| is initialized with the version SPDYLAY_PROTO_SPDY2, - * the lowest priority is 3. If the |session| is initialized with the - * version SPDYLAY_PROTO_SPDY3, the lowest priority is 7. + * The |pri| is priority of this request. 0 is the highest priority. + * If the |session| is initialized with the version + * :macro:`SPDYLAY_PROTO_SPDY2`, the lowest priority is 3. If the + * |session| is initialized with the version + * :macro:`SPDYLAY_PROTO_SPDY3`, the lowest priority is 7. + * + * The |nv| contains the name/value pairs. For i > 0, ``nv[2*i]`` + * contains a pointer to the name string and ``nv[2*i+1]`` contains a + * pointer to the value string. The one beyond last value must be + * ``NULL``. That is, if the |nv| contains N name/value pairs, + * ``nv[2*N]`` must be ``NULL``. * * The |nv| must include following name/value pairs: * @@ -632,40 +1225,41 @@ void* spdylay_session_get_stream_user_data(spdylay_session *session, * field. * * If the |session| is initialized with the version - * SPDYLAY_PROTO_SPDY2, the above names are translated to "method", - * "scheme", "url", "version" and "host" respectively. + * :macro:`SPDYLAY_PROTO_SPDY2`, the above names are translated to + * "method", "scheme", "url", "version" and "host" respectively. * * This function creates copies of all name/value pairs in |nv|. It * also lower-cases all names in |nv|. * - * If |data_prd| is not NULL, it provides data which will be sent in - * subsequent DATA frames. In this case, a method that allows request - * message bodies + * If |data_prd| is not ``NULL``, it provides data which will be sent + * in subsequent DATA frames. In this case, a method that allows + * request message bodies * (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9) must * be specified with "method" key in |nv| (e.g. POST). If |data_prd| - * is NULL, SYN_STREAM have FLAG_FIN. The |stream_user_data| is data - * associated to the stream opened by this request and can be an - * arbitrary pointer, which can be retrieved by - * spdylay_session_get_stream_user_data(). + * is ``NULL``, SYN_STREAM have FLAG_FIN. The |stream_user_data| is + * data associated to the stream opened by this request and can be an + * arbitrary pointer, which can be retrieved later by + * `spdylay_session_get_stream_user_data()`. * * Since the library reorders the frames and tries to send the highest * prioritized one first and the SPDY specification requires the * stream ID must be strictly increasing, the stream ID of this * request cannot be known until it is about to sent. To know the * stream ID of the request, the application can use - * before_ctrl_send_callback. This callback is called just before the - * frame is sent. For SYN_STREAM frame, the argument frame has stream - * ID assigned. Also since the stream is already opened, - * spdylay_session_get_stream_user_data() can be used to get + * :member:`spdylay_session_callbacks.before_ctrl_send_callback`. This + * callback is called just before the frame is sent. For SYN_STREAM + * frame, the argument frame has the stream ID assigned. Also since + * the stream is already opened, + * `spdylay_session_get_stream_user_data()` can be used to get * |stream_user_data| to identify which SYN_STREAM we are processing. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_INVALID_ARGUMENT + * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * The |pri| is invalid; or the Associated-To-Stream-ID is * invalid. - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_request(spdylay_session *session, uint8_t pri, @@ -673,9 +1267,17 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri, const spdylay_data_provider *data_prd, void *stream_user_data); -/* +/** + * @function + * * Submits SYN_REPLY frame and optionally one or more DATA frames - * against stream |stream_id|. + * against the stream |stream_id|. + * + * The |nv| contains the name/value pairs. For i > 0, ``nv[2*i]`` + * contains a pointer to the name string and ``nv[2*i+1]`` contains a + * pointer to the value string. The one beyond last value must be + * ``NULL``. That is, if the |nv| contains N name/value pairs, + * ``nv[2*N]`` must be ``NULL``. * * The |nv| must include following name/value pairs: * @@ -685,35 +1287,37 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri, * HTTP response version (e.g., "HTTP/1.1") * * If the |session| is initialized with the version - * SPDYLAY_PROTO_SPDY2, the above names are translated to "status" and - * "version" respectively. + * :macro:`SPDYLAY_PROTO_SPDY2`, the above names are translated to + * "status" and "version" respectively. * * This function creates copies of all name/value pairs in |nv|. It * also lower-cases all names in |nv|. * - * If |data_prd| is not NULL, it provides data which will be sent in - * subsequent DATA frames. If |data_prd| is NULL, SYN_REPLY will have - * FLAG_FIN. + * If |data_prd| is not ``NULL``, it provides data which will be sent + * in subsequent DATA frames. If |data_prd| is ``NULL``, SYN_REPLY + * will have FLAG_FIN. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_response(spdylay_session *session, int32_t stream_id, const char **nv, const spdylay_data_provider *data_prd); -/* +/** + * @function + * * Submits SYN_STREAM frame. The |flags| is bitwise OR of the * following values: * - * SPDYLAY_CTRL_FLAG_FIN - * SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL + * * :enum:`SPDYLAY_CTRL_FLAG_FIN` + * * :enum:`SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL` * - * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag - * set. + * If |flags| includes :enum:`SPDYLAY_CTRL_FLAG_FIN`, this frame has + * FIN flag set. * * The |assoc_stream_id| is used for server-push. If |session| is * initialized for client use, |assoc_stream_id| is ignored. The |pri| @@ -722,152 +1326,182 @@ int spdylay_submit_response(spdylay_session *session, * this frame. The |stream_user_data| is a pointer to an arbitrary * data which is associated to the stream this frame will open. * + * The |nv| contains the name/value pairs. For i > 0, ``nv[2*i]`` + * contains a pointer to the name string and ``nv[2*i+1]`` contains a + * pointer to the value string. The one beyond last value must be + * ``NULL``. That is, if the |nv| contains N name/value pairs, + * ``nv[2*N]`` must be ``NULL``. + * * This function is low-level in a sense that the application code can * specify flags and the Associated-To-Stream-ID directly. For usual - * HTTP request, spdylay_submit_request() is useful. + * HTTP request, `spdylay_submit_request()` is useful. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_INVALID_ARGUMENT + * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * The |pri| is invalid; or the Associated-To-Stream-ID is * invalid. - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_syn_stream(spdylay_session *session, uint8_t flags, int32_t assoc_stream_id, uint8_t pri, const char **nv, void *stream_user_data); -/* +/** + * @function + * * Submits SYN_REPLY frame. The |flags| is bitwise OR of the following * values: * - * SPDYLAY_CTRL_FLAG_FIN + * * :enum:`SPDYLAY_CTRL_FLAG_FIN` * - * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag - * set. + * If |flags| includes :enum:`SPDYLAY_CTRL_FLAG_FIN`, this frame has + * FIN flag set. * - * The stream this frame belongs to is given in |stream_id|. The |nv| - * is the name/value pairs in this frame. + * The stream which this frame belongs to is given in the + * |stream_id|. The |nv| is the name/value pairs in this frame. + * + * The |nv| contains the name/value pairs. For i > 0, ``nv[2*i]`` + * contains a pointer to the name string and ``nv[2*i+1]`` contains a + * pointer to the value string. The one beyond last value must be + * ``NULL``. That is, if the |nv| contains N name/value pairs, + * ``nv[2*N]`` must be ``NULL``. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags, int32_t stream_id, const char **nv); -/* +/** + * @function + * * Submits HEADERS frame. The |flags| is bitwise OR of the following * values: * - * SPDYLAY_CTRL_FLAG_FIN + * * :enum:`SPDYLAY_CTRL_FLAG_FIN` * - * If |flags| includes SPDYLAY_CTRL_FLAG_FIN, this frame has FIN flag - * set. + * If |flags| includes :enum:`SPDYLAY_CTRL_FLAG_FIN`, this frame has + * FIN flag set. * - * The stream this frame belongs to is given in |stream_id|. The |nv| - * is the name/value pairs in this frame. + * The stream which this frame belongs to is given in the + * |stream_id|. The |nv| is the name/value pairs in this frame. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_headers(spdylay_session *session, uint8_t flags, int32_t stream_id, const char **nv); -/* - * Submits 1 or more DATA frames to the stream |stream_id|. The data - * to be sent are provided by |data_prd|. Depending on the length of - * data, 1 or more DATA frames will be sent. If |flags| contains - * SPDYLAY_DATA_FLAG_FIN, the last DATA frame has FLAG_FIN set. +/** + * @function + * + * Submits one or more DATA frames to the stream |stream_id|. The + * data to be sent are provided by |data_prd|. If |flags| contains + * :enum:`SPDYLAY_DATA_FLAG_FIN`, the last DATA frame has FLAG_FIN + * set. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_data(spdylay_session *session, int32_t stream_id, uint8_t flags, const spdylay_data_provider *data_prd); -/* - * Submits RST_STREAM frame to cancel/reject stream |stream_id| with - * status code |status_code|. +/** + * @function + * + * Submits RST_STREAM frame to cancel/reject the stream |stream_id| + * with the status code |status_code|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_rst_stream(spdylay_session *session, int32_t stream_id, uint32_t status_code); -/* +/** + * @function + * * Submits PING frame. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_ping(spdylay_session *session); -/* +/** + * @function + * * Submits GOAWAY frame. The status code |status_code| is ignored if - * the protocol version is SPDYLAY_PROTO_SPDY2. + * the protocol version is :macro:`SPDYLAY_PROTO_SPDY2`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code); -/* +/** + * @function + * * Stores local settings and submits SETTINGS frame. The |iv| is the - * pointer to the array of spdylay_settings_entry. The |niv| indicates - * the number of spdylay_settings_entry. The |flags| is bitwise-OR of - * one or more values from spdylay_settings_flag. + * pointer to the array of :type:`spdylay_settings_entry`. The |niv| + * indicates the number of :type:`spdylay_settings_entry`. The |flags| + * is bitwise-OR of one or more values from + * :type:`spdylay_settings_flag`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * SPDYLAY_ERR_INVALID_ARGUMENT + * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * The |iv| contains duplicate settings ID or invalid value. - * SPDYLAY_ERR_NOMEM + * :enum:`SPDYLAY_ERR_NOMEM` * Out of memory. */ int spdylay_submit_settings(spdylay_session *session, uint8_t flags, const spdylay_settings_entry *iv, size_t niv); -/* - * A helper function for dealing with NPN in client side. - * |in| contains server's protocol in preferable order. - * The format of |in| is length-prefixed and not null-terminated. - * For example, "spdy/2" are "http/1.1" stored in |in| like this: +/** + * @function * - * in[0] = 6 - * in[1..6] = "spdy/2" - * in[7] = 8 - * in[8..15] = "http/1.1" - * inlen = 16 + * A helper function for dealing with NPN in client side. The |in| + * contains server's protocol in preferable order. The format of |in| + * is length-prefixed and not null-terminated. For example, "spdy/2" + * are "http/1.1" stored in |in| like this:: + * + * in[0] = 6 + * in[1..6] = "spdy/2" + * in[7] = 8 + * in[8..15] = "http/1.1" + * inlen = 16 * * The selection algorithm is as follows: * * 1. If server's list contains SPDY versions the spdylay library * supports, this function selects one of them and returns its SPDY * protocol version which can be used directly with - * spdylay_session_client_new() and spdylay_session_server_new() - * . The following steps are not taken. + * `spdylay_session_client_new()` and + * `spdylay_session_server_new()` . The following steps are not + * taken. * * 2. If server's list contains "http/1.1", this function selects * "http/1.1" and returns 0. The following step is not taken. @@ -886,27 +1520,31 @@ int spdylay_submit_settings(spdylay_session *session, uint8_t flags, * See http://technotes.googlecode.com/git/nextprotoneg.html for more * details about NPN. * - * To use this method you should do something like: + * To use this method you should do something like:: * - * static int select_next_proto_cb(SSL* ssl, - * unsigned char **out, unsigned char *outlen, - * const unsigned char *in, unsigned int inlen, - * void *arg) - * { - * int version; - * version = spdylay_select_next_protocol(out, outlen, in, inlen); - * if(version > 0) { - * ((MyType*)arg)->spdy_version = version; - * } - * return SSL_TLSEXT_ERR_OK; - * } - * ... - * SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj); + * static int select_next_proto_cb(SSL* ssl, + * unsigned char **out, + * unsigned char *outlen, + * const unsigned char *in, + * unsigned int inlen, + * void *arg) + * { + * int version; + * version = spdylay_select_next_protocol(out, outlen, in, inlen); + * if(version > 0) { + * ((MyType*)arg)->spdy_version = version; + * } + * return SSL_TLSEXT_ERR_OK; + * } + * ... + * SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj); */ int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen); -/* +/** + * @function + * * Returns spdy version which spdylay library supports from given * protocol name. The |proto| is the pointer to the protocol name and * |protolen| is its length. Currently, "spdy/2" and "spdy/3" are diff --git a/lib/includes/spdylay/spdylayver.h.in b/lib/includes/spdylay/spdylayver.h.in index fb69f4e..325c515 100644 --- a/lib/includes/spdylay/spdylayver.h.in +++ b/lib/includes/spdylay/spdylayver.h.in @@ -25,7 +25,10 @@ #ifndef SPDYLAYVER_H #define SPDYLAYVER_H -/* Version number of spdylay release */ +/** + * @macro + * Version number of spdylay release + */ #define SPDYLAY_VERSION "@PACKAGE_VERSION@" #endif /* SPDYLAYVER_H */