4 * This is a really bad attempt at writing a parser to handle multipart
5 * messages -- in the case of WebCit, a form containing uploaded files.
16 #include <sys/types.h>
18 #include <sys/socket.h>
21 #include <netinet/in.h>
35 void extract_key(char *target, char *source, char *key)
39 strcpy(target, source);
40 for (a = 0; a < strlen(target); ++a) {
41 if ((!strncasecmp(&target[a], key, strlen(key)))
42 && (target[a + strlen(key)] == '=')) {
43 strcpy(target, &target[a + strlen(key) + 1]);
45 strcpy(target, &target[1]);
46 for (b = 0; b < strlen(target); ++b)
58 * The very back end for the component handler
59 * (This function expects to be fed CONTENT ONLY, no headers)
61 void do_something_with_it(char *content,
64 char *content_disposition,
77 extract_key(name, content_disposition, " name");
78 extract_key(filename, content_disposition, "filename");
80 /* Nested multipart gets recursively fed back into the parser */
81 if (!strncasecmp(content_type, "multipart", 9)) {
82 mime_parser(content, length, content_type, CallBack);
84 /**** OTHERWISE, HERE'S WHERE WE HANDLE THE STUFF!! *****/
86 CallBack(name, filename, "", content, content_type, length);
88 /**** END OF STUFF-HANDLER ****/
94 * Take a part, figure out its length, and do something with it
95 * (This function expects to be fed HEADERS+CONTENT)
97 void handle_part(char *content,
99 char *supplied_content_type,
109 char content_type[256];
110 char content_disposition[256];
113 int crlf = 0; /* set to 1 for crlf-style newlines */
116 strcpy(content_type, supplied_content_type);
118 /* Strip off any leading blank lines. */
120 while ((!strncmp(start, "\r", 1)) || (!strncmp(start, "\n", 1))) {
125 /* At this point all we have left is the headers and the content. */
129 buf[strlen(buf) + 1] = 0;
130 if (strlen(buf) < ((sizeof buf) - 1)) {
131 strncpy(&buf[strlen(buf)], start, 1);
135 } while ((buf[strlen(buf) - 1] != 10) && (part_length > 0));
136 if (part_length <= 0)
138 buf[strlen(buf) - 1] = 0;
139 if (buf[strlen(buf) - 1] == 13) {
140 buf[strlen(buf) - 1] = 0;
143 if (!strncasecmp(buf, "Content-type: ", 14)) {
144 strcpy(content_type, &buf[14]);
146 if (!strncasecmp(buf, "Content-disposition: ", 21)) {
147 strcpy(content_disposition, &buf[21]);
149 } while (strlen(buf) > 0);
152 actual_length = part_length - 2;
154 actual_length = part_length - 1;
156 /* Now that we've got this component isolated, what to do with it? */
157 do_something_with_it(start, actual_length,
158 content_type, content_disposition, CallBack);
164 * Break out the components of a multipart message
165 * (This function expects to be fed CONTENT ONLY, no headers)
169 void mime_parser(char *content,
183 int have_boundary = 0;
187 int bytes_processed = 0;
190 /* If it's not multipart, don't process it as multipart */
191 if (strncasecmp(ContentType, "multipart", 9)) {
192 do_something_with_it(content, ContentLength,
193 ContentType, "", CallBack);
196 /* Figure out what the boundary is */
197 strcpy(boundary, ContentType);
198 for (a = 0; a < strlen(boundary); ++a) {
199 if (!strncasecmp(&boundary[a], "boundary=", 9)) {
202 strcpy(&boundary[2], &boundary[a + 9]);
206 if ((boundary[a] == 13) || (boundary[a] == 10)) {
211 /* We can't process multipart messages without a boundary. */
212 if (have_boundary == 0)
214 strcpy(endary, boundary);
215 strcat(endary, "--");
219 /* Seek to the beginning of the next boundary */
220 while (bytes_processed < ContentLength) {
221 /* && (strncasecmp(ptr, boundary, strlen(boundary))) ) { */
223 if (strncasecmp(ptr, boundary, strlen(boundary))) {
227 /* See if we're at the end */
228 if (!strncasecmp(ptr, endary, strlen(endary))) {
231 /* Seek to the end of the boundary string */
232 if (!strncasecmp(ptr, boundary, strlen(boundary))) {
233 while ((bytes_processed < ContentLength)
234 && (strncasecmp(ptr, "\n", 1))) {
240 while ((bytes_processed < ContentLength)
241 && (strncasecmp(ptr, boundary, strlen(boundary)))) {
246 handle_part(beginning, part_length, "", CallBack);
247 /* Back off so we can see the next boundary */