main () { int x; sliding_buffer_t sb; char foo[200]; s_buffer_init (&sb, 32); do { x = s_buffer_read (&sb, "&"); sprintf (foo, "%03d- %03d - %03d", x, sb.eof, sb.len); write (1, foo, strlen (foo)); write (1, sb.segment, sb.len); write (1, "\n", 1); } while ((!sb.eof)); s_buffer_destroy (&sb); }
int rfc2388_handler (list_t * env) { enum mime_state_t { DISCARD, BOUNDARY, HEADER, CONTENT }; int state; int i, x; unsigned long max_len, content_length; sliding_buffer_t sbuf; char *crlf = "\r\n"; char *boundary; char *str; buffer_t buf; mime_var_t var; /* get the boundary info */ str = getenv ("CONTENT_TYPE"); i = strlen (str) - 9; while ((i >= 0) && (memcmp ("boundary=", str + i, 9))) { i--; } if (i == -1) { empty_stdin (); die_with_message (NULL, NULL, "No Mime Boundary Information Found"); } i = i + 9; if (str[i] == '"') i++; boundary = xmalloc (strlen (str + i) + 5); /* \r\n-- + NULL */ memcpy (boundary, crlf, 2); memcpy (boundary + 2, "--", 2); memcpy (boundary + 4, str + i, strlen (str + i) + 1); if ((i > 0) && (str[i - 1] == '"')) { while ((boundary[i]) && (boundary[i] != '"')) i++; boundary[i] = '\0'; } /* Allow 2MB content, unless they have a global upload set */ max_len = ((global.uploadkb == 0) ? 2048 : global.uploadkb) *1024; content_length = 0; /* initialize a 128K sliding buffer */ s_buffer_init (&sbuf, 1024 * 128); sbuf.fh = STDIN; if (getenv ("CONTENT_LENGTH")) { sbuf.maxread = strtoul (getenv ("CONTENT_LENGTH"), NULL, 10); } /* initialize the buffer, and make sure it doesn't point to null */ buffer_init (&buf); buffer_add (&buf, "", 1); buffer_reset (&buf); state = DISCARD; str = boundary + 2; /* skip the leading crlf */ do { /* x is true if this token ends with a matchstr or is at the end of stream */ x = s_buffer_read (&sbuf, str); content_length += sbuf.len; if (content_length >= max_len) { empty_stdin (); free (boundary); s_buffer_destroy (&sbuf); buffer_destroy (&buf); if (var.name) { mime_var_destroy (&var); } die_with_message (NULL, NULL, "Attempted to send content larger than allowed limits."); } switch (state) { case DISCARD: /* discard any text - used for first mime boundary */ if (x) { state = BOUNDARY; str = crlf; buffer_reset (&buf); /* reinitializes the buffer */ } break; case BOUNDARY: if (!x) { buffer_add (&buf, sbuf.segment, sbuf.len); } if (x) { buffer_add (&buf, sbuf.segment, sbuf.len); if (!memcmp (buf.data, boundary + 2, 2)) { /* "--" */ /* all done... what does that mean? */ str = boundary + 2; state = DISCARD; } else { buffer_reset (&buf); mime_var_init (&var); state = HEADER; str = crlf; } } break; case HEADER: buffer_add (&buf, sbuf.segment, sbuf.len); if (x) { if (sbuf.len == 0) { /* blank line */ buffer_reset (&buf); state = CONTENT; str = boundary; } else { buffer_add (&buf, "", 1); mime_tag_add (&var, (char *) buf.data); buffer_reset (&buf); } } break; case CONTENT: /* write to writer process, regardless */ mime_var_writer (&var, (char *) sbuf.segment, sbuf.len); if (x) { buffer_reset (&buf); mime_var_putenv (env, &var); mime_var_destroy (&var); state = BOUNDARY; str = crlf; } break; } /* end switch */ } while (!sbuf.eof); free (boundary); s_buffer_destroy (&sbuf); buffer_destroy (&buf); return (0); }
int ReadCGIPOSTValues (list_t * env) { size_t content_length = 0; size_t max_len; size_t i, j, x; sliding_buffer_t sbuf; buffer_t token; unsigned char *data; const char *CONTENT_LENGTH = "CONTENT_LENGTH"; if ((getenv (CONTENT_LENGTH) == NULL) || (strtoul (getenv (CONTENT_LENGTH), NULL, 10) == 0)) return (0); if (getenv ("CONTENT_TYPE")) { if (strncasecmp (getenv ("CONTENT_TYPE"), "multipart/form-data", 19) == 0) { /* This is a mime request, we need to go to the mime handler */ i = rfc2388_handler (env); return (i); } } s_buffer_init (&sbuf, 32768); sbuf.fh = STDIN; if (getenv (CONTENT_LENGTH)) { sbuf.maxread = strtoul (getenv (CONTENT_LENGTH), NULL, 10); } haserl_buffer_init (&token); /* Allow 2MB content, unless they have a global upload set */ max_len = ((global.uploadkb == 0) ? 2048 : global.uploadkb) *1024; do { /* x is true if this token ends with a matchstr or is at the end of stream */ x = s_buffer_read (&sbuf, "&"); content_length += sbuf.len; if (content_length > max_len) { die_with_message (NULL, NULL, "Attempted to send content larger than allowed limits."); } if ((x == 0) || (token.data)) { buffer_add (&token, (char *) sbuf.segment, sbuf.len); } if (x) { data = sbuf.segment; sbuf.segment[sbuf.len] = '\0'; if (token.data) { /* add the ASCIIZ */ buffer_add (&token, sbuf.segment + sbuf.len, 1); data = token.data; } /* change plusses into spaces */ j = strlen ((char *) data); for (i = 0; i <= j; i++) { if (data[i] == '+') { data[i] = ' '; } } unescape_url ((char *) data); myputenv (env, (char *) data, global.var_prefix); myputenv (env, (char *) data, global.post_prefix); if (token.data) { buffer_reset (&token); } } } while (!sbuf.eof); s_buffer_destroy (&sbuf); buffer_destroy (&token); return (0); }