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 */ |
46 | enum 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 | */ |
70 | typedef 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 */ |
76 | struct 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 | */ |
99 | LWS_VISIBLE LWS_EXTERN struct lws_spa * |
100 | lws_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 | |
104 | typedef 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 | */ |
131 | LWS_VISIBLE LWS_EXTERN struct lws_spa * |
132 | lws_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 | */ |
141 | LWS_VISIBLE LWS_EXTERN int |
142 | lws_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 | */ |
149 | LWS_VISIBLE LWS_EXTERN int |
150 | lws_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 | */ |
158 | LWS_VISIBLE LWS_EXTERN int |
159 | lws_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 | */ |
166 | LWS_VISIBLE LWS_EXTERN const char * |
167 | lws_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 | */ |
174 | LWS_VISIBLE LWS_EXTERN int |
175 | lws_spa_destroy(struct lws_spa *spa); |
176 | ///@} |
177 | |