예제 #1
0
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);
}
예제 #2
0
파일: rfc2388.c 프로젝트: ms13sp/haserl
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);
}
예제 #3
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);
}