Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
16bc89e7
Commit
16bc89e7
authored
Jan 17, 2014
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update doc
parent
4a6c86f6
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
218 additions
and
53 deletions
+218
-53
_sources/apiref.txt
_sources/apiref.txt
+59
-17
apiref.html
apiref.html
+63
-16
genindex.html
genindex.html
+18
-2
nghttp2.h.html
nghttp2.h.html
+74
-17
objects.inv
objects.inv
+0
-0
searchindex.js
searchindex.js
+1
-1
tutorial-client.html
tutorial-client.html
+2
-0
tutorial-server.html
tutorial-server.html
+1
-0
No files found.
_sources/apiref.txt
View file @
16bc89e7
...
...
@@ -800,21 +800,10 @@ Types (structs, unions and typedefs)
argument passed in to the call to `nghttp2_session_client_new()` or
`nghttp2_session_server_new()`.
If the application uses `nghttp2_session_mem_recv()`, it can return
:macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
return without processing further input bytes. The *frame*
parameter is retained until `nghttp2_session_continue()` is
called. The application must retain the input bytes which was used
to produce the *frame* parameter, because it may refer to the
memory region included in the input bytes. The application which
returns :macro:`NGHTTP2_ERR_PAUSE` must call
`nghttp2_session_continue()` before `nghttp2_session_mem_recv()`.
The implementation of this function must return 0 if it
succeeds. It may return :macro:`NGHTTP2_ERR_PAUSE`. If the other
nonzero value is returned, it is treated as fatal error and
`nghttp2_session_recv()` and `nghttp2_session_send()` functions
immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
succeeds. If nonzero value is returned, it is treated as fatal
error and `nghttp2_session_recv()` and `nghttp2_session_mem_recv()`
functions immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
.. type:: typedef int (*nghttp2_on_invalid_frame_recv_callback) (nghttp2_session *session, const nghttp2_frame *frame, nghttp2_error_code error_code, void *user_data)
...
...
@@ -857,7 +846,7 @@ Types (structs, unions and typedefs)
The implementation of this function must return 0 if it
succeeds. If nonzero is returned, it is treated as fatal error and
`nghttp2_session_recv()` and `nghttp2_session_
send
()` functions
`nghttp2_session_recv()` and `nghttp2_session_
mem_recv
()` functions
immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
.. type:: typedef int (*nghttp2_on_data_recv_callback) (nghttp2_session *session, uint16_t length, uint8_t flags, int32_t stream_id, void *user_data)
...
...
@@ -1001,6 +990,53 @@ Types (structs, unions and typedefs)
`nghttp2_session_recv()` and `nghttp2_session_send()` functions
immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
.. type:: typedef int (*nghttp2_on_header_callback) (nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, void *user_data)
Callback function invoked when a header name/value pair is received
for the *frame*. When this callback is invoked, ``frame->hd.type``
is either :macro:`NGHTTP2_HEADERS` or :macro:`NGHTTP2_PUSH_PROMISE`.
After all header name/value pairs are processed with this callback,
or header decompression error occurred, then
:type:`nghttp2_on_end_headers_callback` will be invoked unless
application returns nonzero value from this callback.
The *name* may be ``NULL`` if the *namelen* is 0. The same thing
can be said about the *value*.
If the application uses `nghttp2_session_mem_recv()`, it can return
:macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
return without processing further input bytes. The *frame*,
*name*, *namelen*, *value* and *valuelen* parameters are retained
until `nghttp2_session_continue()` is called. The application must
retain the input bytes which was used to produce the *frame*
parameter, because it may refer to the memory region included in
the input bytes. The application which returns
:macro:`NGHTTP2_ERR_PAUSE` must call `nghttp2_session_continue()`
before `nghttp2_session_mem_recv()`.
The implementation of this function must return 0 if it
succeeds. It may return :macro:`NGHTTP2_ERR_PAUSE`. If the other
nonzero value is returned, it is treated as fatal error and
`nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
.. type:: typedef int (*nghttp2_on_end_headers_callback) (nghttp2_session *session, const nghttp2_frame *frame, nghttp2_error_code error_code, void *user_data)
Callback function invoked when all header name/value pairs are
processed or after the header decompression error is detected. If
the *error_code* is :macro:`NGHTTP2_NO_ERROR`, it indicates the
header decompression succeeded. Otherwise, error prevented the
completion of the header decompression. In this case, the library
will handle the error by either transmitting RST_STREAM or GOAWAY
and terminate session.
The implementation of this function must return 0 if it
succeeds. If nonzero value is returned, it is treated as fatal
error and `nghttp2_session_recv()` and `nghttp2_session_mem_recv()`
functions immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
.. type:: nghttp2_session_callbacks
...
...
@@ -1057,6 +1093,14 @@ Types (structs, unions and typedefs)
Callback function invoked when the received frame type is
unknown.
.. member:: nghttp2_on_header_callback on_header_callback
Callback function invoked when a header name/value pair is
received.
.. member:: nghttp2_on_end_headers_callback on_end_headers_callback
Callback function invoked when all header name/value pairs are
processed.
.. type:: nghttp2_opt_set
...
...
@@ -1814,8 +1858,6 @@ Functions
:macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
The *nva* includes empty name, or name which contains invalid
characters.
:macro:`NGHTTP2_ERR_STREAM_CLOSED`
The stream is already closed or does not exist.
:macro:`NGHTTP2_ERR_NOMEM`
Out of memory.
...
...
apiref.html
View file @
16bc89e7
This diff is collapsed.
Click to expand it.
genindex.html
View file @
16bc89e7
...
...
@@ -607,15 +607,19 @@
</dt>
<dt><a
href=
"apiref.html#nghttp2_on_end_headers_callback"
>
nghttp2_on_end_headers_callback (C type)
</a>
</dt>
<dt><a
href=
"apiref.html#nghttp2_on_frame_not_send_callback"
>
nghttp2_on_frame_not_send_callback (C type)
</a>
</dt>
</dl></td>
<td
style=
"width: 33%"
valign=
"top"
><dl>
<dt><a
href=
"apiref.html#nghttp2_on_frame_recv_callback"
>
nghttp2_on_frame_recv_callback (C type)
</a>
</dt>
</dl></td>
<td
style=
"width: 33%"
valign=
"top"
><dl>
<dt><a
href=
"apiref.html#nghttp2_on_frame_recv_parse_error_callback"
>
nghttp2_on_frame_recv_parse_error_callback (C type)
</a>
</dt>
...
...
@@ -625,6 +629,10 @@
</dt>
<dt><a
href=
"apiref.html#nghttp2_on_header_callback"
>
nghttp2_on_header_callback (C type)
</a>
</dt>
<dt><a
href=
"apiref.html#nghttp2_on_invalid_frame_recv_callback"
>
nghttp2_on_invalid_frame_recv_callback (C type)
</a>
</dt>
...
...
@@ -809,6 +817,10 @@
</dt>
<dt><a
href=
"apiref.html#nghttp2_session_callbacks.on_end_headers_callback"
>
nghttp2_session_callbacks.on_end_headers_callback (C member)
</a>
</dt>
<dt><a
href=
"apiref.html#nghttp2_session_callbacks.on_frame_not_send_callback"
>
nghttp2_session_callbacks.on_frame_not_send_callback (C member)
</a>
</dt>
...
...
@@ -821,6 +833,10 @@
</dt>
<dt><a
href=
"apiref.html#nghttp2_session_callbacks.on_header_callback"
>
nghttp2_session_callbacks.on_header_callback (C member)
</a>
</dt>
<dt><a
href=
"apiref.html#nghttp2_session_callbacks.on_invalid_frame_recv_callback"
>
nghttp2_session_callbacks.on_invalid_frame_recv_callback (C member)
</a>
</dt>
...
...
nghttp2.h.html
View file @
16bc89e7
...
...
@@ -1008,21 +1008,10 @@
<span
class=
"cm"
>
* argument passed in to the call to `nghttp2_session_client_new()` or
</span>
<span
class=
"cm"
>
* `nghttp2_session_server_new()`.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* If the application uses `nghttp2_session_mem_recv()`, it can return
</span>
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
</span>
<span
class=
"cm"
>
* return without processing further input bytes. The |frame|
</span>
<span
class=
"cm"
>
* parameter is retained until `nghttp2_session_continue()` is
</span>
<span
class=
"cm"
>
* called. The application must retain the input bytes which was used
</span>
<span
class=
"cm"
>
* to produce the |frame| parameter, because it may refer to the
</span>
<span
class=
"cm"
>
* memory region included in the input bytes. The application which
</span>
<span
class=
"cm"
>
* returns :enum:`NGHTTP2_ERR_PAUSE` must call
</span>
<span
class=
"cm"
>
* `nghttp2_session_continue()` before `nghttp2_session_mem_recv()`.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* The implementation of this function must return 0 if it
</span>
<span
class=
"cm"
>
* succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE`. If the other
</span>
<span
class=
"cm"
>
* nonzero value is returned, it is treated as fatal error and
</span>
<span
class=
"cm"
>
* `nghttp2_session_recv()` and `nghttp2_session_send()` functions
</span>
<span
class=
"cm"
>
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
</span>
<span
class=
"cm"
>
* succeeds. If nonzero value is returned, it is treated as fatal
</span>
<span
class=
"cm"
>
* error and `nghttp2_session_recv()` and `nghttp2_session_mem_recv()`
</span>
<span
class=
"cm"
>
* functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
typedef
</span>
<span
class=
"nf"
>
int
</span>
<span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
nghttp2_on_frame_recv_callback
</span><span
class=
"p"
>
)
</span>
<span
class=
"p"
>
(
</span><span
class=
"n"
>
nghttp2_session
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
session
</span><span
class=
"p"
>
,
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"n"
>
nghttp2_frame
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
frame
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
void
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
user_data
</span><span
class=
"p"
>
);
</span>
...
...
@@ -1072,7 +1061,7 @@
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* The implementation of this function must return 0 if it
</span>
<span
class=
"cm"
>
* succeeds. If nonzero is returned, it is treated as fatal error and
</span>
<span
class=
"cm"
>
* `nghttp2_session_recv()` and `nghttp2_session_
send
()` functions
</span>
<span
class=
"cm"
>
* `nghttp2_session_recv()` and `nghttp2_session_
mem_recv
()` functions
</span>
<span
class=
"cm"
>
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
typedef
</span>
<span
class=
"nf"
>
int
</span>
<span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
nghttp2_on_data_chunk_recv_callback
</span><span
class=
"p"
>
)
</span>
...
...
@@ -1257,6 +1246,66 @@
<span
class=
"k"
>
const
</span>
<span
class=
"kt"
>
uint8_t
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
payload
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
size_t
</span>
<span
class=
"n"
>
payloadlen
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
void
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
user_data
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* @functypedef
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* Callback function invoked when a header name/value pair is received
</span>
<span
class=
"cm"
>
* for the |frame|. When this callback is invoked, ``frame-
>
hd.type``
</span>
<span
class=
"cm"
>
* is either :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`.
</span>
<span
class=
"cm"
>
* After all header name/value pairs are processed with this callback,
</span>
<span
class=
"cm"
>
* or header decompression error occurred, then
</span>
<span
class=
"cm"
>
* :type:`nghttp2_on_end_headers_callback` will be invoked unless
</span>
<span
class=
"cm"
>
* application returns nonzero value from this callback.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* The |name| may be ``NULL`` if the |namelen| is 0. The same thing
</span>
<span
class=
"cm"
>
* can be said about the |value|.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* If the application uses `nghttp2_session_mem_recv()`, it can return
</span>
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
</span>
<span
class=
"cm"
>
* return without processing further input bytes. The |frame|,
</span>
<span
class=
"cm"
>
* |name|, |namelen|, |value| and |valuelen| parameters are retained
</span>
<span
class=
"cm"
>
* until `nghttp2_session_continue()` is called. The application must
</span>
<span
class=
"cm"
>
* retain the input bytes which was used to produce the |frame|
</span>
<span
class=
"cm"
>
* parameter, because it may refer to the memory region included in
</span>
<span
class=
"cm"
>
* the input bytes. The application which returns
</span>
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_PAUSE` must call `nghttp2_session_continue()`
</span>
<span
class=
"cm"
>
* before `nghttp2_session_mem_recv()`.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* The implementation of this function must return 0 if it
</span>
<span
class=
"cm"
>
* succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE`. If the other
</span>
<span
class=
"cm"
>
* nonzero value is returned, it is treated as fatal error and
</span>
<span
class=
"cm"
>
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
</span>
<span
class=
"cm"
>
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
typedef
</span>
<span
class=
"nf"
>
int
</span>
<span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
nghttp2_on_header_callback
</span><span
class=
"p"
>
)
</span>
<span
class=
"p"
>
(
</span><span
class=
"n"
>
nghttp2_session
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
session
</span><span
class=
"p"
>
,
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"n"
>
nghttp2_frame
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
frame
</span><span
class=
"p"
>
,
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"kt"
>
uint8_t
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
name
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
size_t
</span>
<span
class=
"n"
>
namelen
</span><span
class=
"p"
>
,
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"kt"
>
uint8_t
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
value
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
size_t
</span>
<span
class=
"n"
>
valuelen
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
void
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
user_data
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* @functypedef
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* Callback function invoked when all header name/value pairs are
</span>
<span
class=
"cm"
>
* processed or after the header decompression error is detected. If
</span>
<span
class=
"cm"
>
* the |error_code| is :enum:`NGHTTP2_NO_ERROR`, it indicates the
</span>
<span
class=
"cm"
>
* header decompression succeeded. Otherwise, error prevented the
</span>
<span
class=
"cm"
>
* completion of the header decompression. In this case, the library
</span>
<span
class=
"cm"
>
* will handle the error by either transmitting RST_STREAM or GOAWAY
</span>
<span
class=
"cm"
>
* and terminate session.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* The implementation of this function must return 0 if it
</span>
<span
class=
"cm"
>
* succeeds. If nonzero value is returned, it is treated as fatal
</span>
<span
class=
"cm"
>
* error and `nghttp2_session_recv()` and `nghttp2_session_mem_recv()`
</span>
<span
class=
"cm"
>
* functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
typedef
</span>
<span
class=
"nf"
>
int
</span>
<span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
nghttp2_on_end_headers_callback
</span><span
class=
"p"
>
)
</span>
<span
class=
"p"
>
(
</span><span
class=
"n"
>
nghttp2_session
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
session
</span><span
class=
"p"
>
,
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"n"
>
nghttp2_frame
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
frame
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
nghttp2_error_code
</span>
<span
class=
"n"
>
error_code
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
void
</span>
<span
class=
"o"
>
*
</span><span
class=
"n"
>
user_data
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* @struct
</span>
<span
class=
"cm"
>
*
</span>
...
...
@@ -1329,6 +1378,16 @@
<span
class=
"cm"
>
* unknown.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"n"
>
nghttp2_on_unknown_frame_recv_callback
</span>
<span
class=
"n"
>
on_unknown_frame_recv_callback
</span><span
class=
"p"
>
;
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* Callback function invoked when a header name/value pair is
</span>
<span
class=
"cm"
>
* received.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"n"
>
nghttp2_on_header_callback
</span>
<span
class=
"n"
>
on_header_callback
</span><span
class=
"p"
>
;
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* Callback function invoked when all header name/value pairs are
</span>
<span
class=
"cm"
>
* processed.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"n"
>
nghttp2_on_end_headers_callback
</span>
<span
class=
"n"
>
on_end_headers_callback
</span><span
class=
"p"
>
;
</span>
<span
class=
"p"
>
}
</span>
<span
class=
"n"
>
nghttp2_session_callbacks
</span><span
class=
"p"
>
;
</span>
<span
class=
"cm"
>
/**
</span>
...
...
@@ -2222,8 +2281,6 @@
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
</span>
<span
class=
"cm"
>
* The |nva| includes empty name, or name which contains invalid
</span>
<span
class=
"cm"
>
* characters.
</span>
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_STREAM_CLOSED`
</span>
<span
class=
"cm"
>
* The stream is already closed or does not exist.
</span>
<span
class=
"cm"
>
* :enum:`NGHTTP2_ERR_NOMEM`
</span>
<span
class=
"cm"
>
* Out of memory.
</span>
<span
class=
"cm"
>
*/
</span>
...
...
objects.inv
View file @
16bc89e7
No preview for this file type
searchindex.js
View file @
16bc89e7
This diff is collapsed.
Click to expand it.
tutorial-client.html
View file @
16bc89e7
...
...
@@ -606,6 +606,8 @@ here.</p>
<span
class=
"cm"
>
*/
</span>
<span
class=
"cp"
>
#include
<
sys/types.h
>
</span>
<span
class=
"cp"
>
#include
<
unistd.h
>
</span>
<span
class=
"cp"
>
#include
<
sys/socket.h
>
</span>
<span
class=
"cp"
>
#include
<
netinet/in.h
>
</span>
<span
class=
"cp"
>
#include
<
netinet/tcp.h
>
</span>
<span
class=
"cp"
>
#include
<
err.h
>
</span>
<span
class=
"cp"
>
#include
<
signal.h
>
</span>
...
...
tutorial-server.html
View file @
16bc89e7
...
...
@@ -738,6 +738,7 @@ stream is about to close and we no longer use that object.</p>
<span
class=
"cp"
>
#include
<
sys/stat.h
>
</span>
<span
class=
"cp"
>
#include
<
fcntl.h
>
</span>
<span
class=
"cp"
>
#include
<
ctype.h
>
</span>
<span
class=
"cp"
>
#include
<
netinet/in.h
>
</span>
<span
class=
"cp"
>
#include
<
netinet/tcp.h
>
</span>
<span
class=
"cp"
>
#include
<
err.h
>
</span>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment