1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25/** \defgroup form-parsing Form Parsing
26 * \ingroup http
27 * ##POSTed form parsing functions
28 *
29 * These lws_spa (stateful post arguments) apis let you parse and urldecode
30 * POSTed form arguments, both using simple urlencoded and multipart transfer
31 * encoding.
32 *
33 * It's capable of handling file uploads as well a named input parsing,
34 * and the apis are the same for both form upload styles.
35 *
36 * You feed it a list of parameter names and it creates pointers to the
37 * urldecoded arguments: file upload parameters pass the file data in chunks to
38 * a user-supplied callback as they come.
39 *
40 * Since it's stateful, it handles the incoming data needing more than one
41 * POST_BODY callback and has no limit on uploaded file size.
42 */
43///@{
44
45/** enum lws_spa_fileupload_states */
46enum lws_spa_fileupload_states {
47 LWS_UFS_CONTENT,
48 /**< a chunk of file content has arrived */
49 LWS_UFS_FINAL_CONTENT,
50 /**< the last chunk (possibly zero length) of file content has arrived */
51 LWS_UFS_OPEN,
52 /**< a new file is starting to arrive */
53 LWS_UFS_CLOSE
54 /**< the file decode stuff is being destroyed */
55};
56
57/**
58 * lws_spa_fileupload_cb() - callback to receive file upload data
59 *
60 * \param data: opt_data pointer set in lws_spa_create
61 * \param name: name of the form field being uploaded
62 * \param filename: original filename from client
63 * \param buf: start of data to receive
64 * \param len: length of data to receive
65 * \param state: information about how this call relates to file
66 *
67 * Notice name and filename shouldn't be trusted, as they are passed from
68 * HTTP provided by the client.
69 */
70typedef int (*lws_spa_fileupload_cb)(void *data, const char *name,
71 const char *filename, char *buf, int len,
72 enum lws_spa_fileupload_states state);
73
74/** struct lws_spa - opaque urldecode parser capable of handling multipart
75 * and file uploads */
76struct lws_spa;
77
78/**
79 * lws_spa_create() - create urldecode parser
80 *
81 * \param wsi: lws connection (used to find Content Type)
82 * \param param_names: array of form parameter names, like "username"
83 * \param count_params: count of param_names
84 * \param max_storage: total amount of form parameter values we can store
85 * \param opt_cb: NULL, or callback to receive file upload data.
86 * \param opt_data: NULL, or user pointer provided to opt_cb.
87 *
88 * Creates a urldecode parser and initializes it.
89 *
90 * It's recommended to use the newer api, lws_spa_create_via_info()
91 * instead.
92 *
93 * opt_cb can be NULL if you just want normal name=value parsing, however
94 * if one or more entries in your form are bulk data (file transfer), you
95 * can provide this callback and filter on the name callback parameter to
96 * treat that urldecoded data separately. The callback should return -1
97 * in case of fatal error, and 0 if OK.
98 */
99LWS_VISIBLE LWS_EXTERN struct lws_spa *
100lws_spa_create(struct lws *wsi, const char * const *param_names,
101 int count_params, int max_storage, lws_spa_fileupload_cb opt_cb,
102 void *opt_data);
103
104typedef struct lws_spa_create_info {
105 const char * const *param_names; /* array of form parameter names, like "username" */
106 int count_params; /* count of param_names */
107 int max_storage; /* total amount of form parameter values we can store */
108 lws_spa_fileupload_cb opt_cb; /* NULL, or callback to receive file upload data. */
109 void *opt_data; /* NULL, or user pointer provided to opt_cb. */
110 size_t param_names_stride; /* 0 if param_names is an array of char *.
111 Else stride to next char * */
112 struct lwsac **ac; /* NULL, or pointer to lwsac * to contain all
113 related heap allocations */
114 size_t ac_chunk_size; /* 0 for default, or ac chunk size */
115} lws_spa_create_info_t;
116
117/**
118 * lws_spa_create_via_info() - create urldecode parser
119 *
120 * \param wsi: lws connection (used to find Content Type)
121 * \param info: pointer to struct defining the arguments
122 *
123 * Creates a urldecode parser and initializes it.
124 *
125 * opt_cb can be NULL if you just want normal name=value parsing, however
126 * if one or more entries in your form are bulk data (file transfer), you
127 * can provide this callback and filter on the name callback parameter to
128 * treat that urldecoded data separately. The callback should return -1
129 * in case of fatal error, and 0 if OK.
130 */
131LWS_VISIBLE LWS_EXTERN struct lws_spa *
132lws_spa_create_via_info(struct lws *wsi, const lws_spa_create_info_t *info);
133
134/**
135 * lws_spa_process() - parses a chunk of input data
136 *
137 * \param spa: the parser object previously created
138 * \param in: incoming urlencoded data
139 * \param len: count of bytes valid at \p in
140 */
141LWS_VISIBLE LWS_EXTERN int
142lws_spa_process(struct lws_spa *spa, const char *in, int len);
143
144/**
145 * lws_spa_finalize() - indicate incoming data completed
146 *
147 * \param spa: the parser object previously created
148 */
149LWS_VISIBLE LWS_EXTERN int
150lws_spa_finalize(struct lws_spa *spa);
151
152/**
153 * lws_spa_get_length() - return length of parameter value
154 *
155 * \param spa: the parser object previously created
156 * \param n: parameter ordinal to return length of value for
157 */
158LWS_VISIBLE LWS_EXTERN int
159lws_spa_get_length(struct lws_spa *spa, int n);
160
161/**
162 * lws_spa_get_string() - return pointer to parameter value
163 * \param spa: the parser object previously created
164 * \param n: parameter ordinal to return pointer to value for
165 */
166LWS_VISIBLE LWS_EXTERN const char *
167lws_spa_get_string(struct lws_spa *spa, int n);
168
169/**
170 * lws_spa_destroy() - destroy parser object
171 *
172 * \param spa: the parser object previously created
173 */
174LWS_VISIBLE LWS_EXTERN int
175lws_spa_destroy(struct lws_spa *spa);
176///@}
177