Esempio n. 1
0
static void
print_reply_hdr (Call *call, const char *buf, int len)
{
  Call_Private_Data *priv = CALL_PRIVATE_DATA (call);
  const char *eoh;

  if (len <= 0 || priv->done_with_reply_hdr)
    return;

  eoh = strstr (buf, "\r\n\r\n");
  if (eoh)
    {
      priv->done_with_reply_hdr = 1;
      eoh += 4;
    }
  else
    {
      /* no CRLFCRLF: non-conforming server */
      eoh = strstr (buf, "\n\n");
      if (eoh)
	{
	  priv->done_with_reply_hdr = 1;
	  eoh += 2;
	}
      else
	eoh = buf + len;
    }
  print_buf (call, "RH", buf, eoh - buf);
}
Esempio n. 2
0
static void
call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  struct iovec *line;
  Call *call;
  Sess *sess;
  char *hdr;

  assert (et == EV_CALL_RECV_HDR && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  line = callarg.vp;
  hdr = line->iov_base;

  switch (tolower (hdr[0]))
    {
    case 'c':
      if (line->iov_len >= 23
	  && strncasecmp (hdr + 1, "ontent-type: text/html", 22) == 0)
	cpriv->state = P_HTML;
      break;

    case 'l':
      if (line->iov_len > 10
	  && strncasecmp (hdr + 1, "ocation: ", 9) == 0)
	fetch_uri (sess, priv, cpriv, hdr + 10, line->iov_len - 10);
      break;
    }

}
Esempio n. 3
0
static void
call_issue (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_ISSUE && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);

  if (cpriv->cookie_present)
    /* don't do anything if cookie has been set already */
    return;

  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (priv->cookie_len > 0)
    {
      if (DBG > 1)
	fprintf (stderr, "call_issue.%ld: inserting `%s'\n",
		 call->id, priv->cookie);
      cpriv->cookie_present = 1;
      memcpy (cpriv->cookie, priv->cookie, priv->cookie_len + 1);
      call_append_request_header (call, cpriv->cookie, priv->cookie_len);
    }
}
Esempio n. 4
0
int
session_issue_call (Sess *sess, Call *call)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  struct Conn_Info *ci;
  int i;

  priv = SESS_PRIVATE_DATA (sess);

  cpriv = CALL_PRIVATE_DATA (call);
  cpriv->sess = sess;

  for (i = 0; i < param.max_conns; ++i)
    {
      ci = priv->conn_info + i;
      if (ci->num_pending < param.max_piped)
	{
	  ++ci->num_pending;
	  ci->call[ci->wr] = call;
	  call_inc_ref (call);
	  ci->wr = (ci->wr + 1) % MAX_PIPED;
	  send_calls (sess, ci);
	  return 0;
	}
    }
  fprintf (stderr, "%s.session_issue_call: too many calls pending!\n"
	   "\tIncrease --max-connections and/or --max-piped-calls.\n",
	   prog_name);
  exit (1);
}
Esempio n. 5
0
static void
flush_print_buf (Call *call, const char *prefix)
{
  Call_Private_Data *priv = CALL_PRIVATE_DATA (call);

  if (priv->len)
    printf ("%s%ld:%.*s\n", prefix, call->id, (int) priv->len, priv->line);
  priv->len = 0;
}
Esempio n. 6
0
static void
call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *priv;
  Call *call;

  assert (et == EV_CALL_DESTROYED && object_is_call (obj));
  call = (Call *) obj;
  priv = CALL_PRIVATE_DATA (call);

  if (priv->line)
    free (priv->line);
}
Esempio n. 7
0
static void
print_buf (Call *call, const char *prefix, const char *buf, int len)
{
  Call_Private_Data *priv = CALL_PRIVATE_DATA (call);
  const char *eol, *end;
  size_t line_len;

  for (end = buf + len; buf < end; buf += line_len)
    {
      line_len = (end - buf);
      eol = strchr (buf, '\n');
      if (eol)
	{
	  /* got a complete line: print it */
	  line_len = eol - buf;
	  printf ("%s%ld:", prefix, call->id);

	  if (priv->len)
	    printf ("%.*s", (int) priv->len, priv->line);
	  priv->len = 0;

	  if (line_len > 0)
	    printf ("%.*s", (int) line_len, buf);
	  putchar ('\n');

	  ++line_len;	/* skip over newline */
	}
      else
	{
	  /* got a partial line: buffer it */
	  if (priv->len + line_len > priv->size)
	    {
	      priv->size = priv->len + line_len;
	      if (priv->line)
		priv->line = realloc (priv->line, priv->size);
	      else
		priv->line = malloc (priv->size);
	      if (!priv->line)
		{
		  fprintf (stderr, "%s.print_buf: Out of memory\n", prog_name);
		  exit (1);
		}
	    }
	  memcpy (priv->line + priv->len, buf, line_len);
	  priv->len += line_len;
	}
    }
}
Esempio n. 8
0
static void
issue_calls (Sess *sess, Sess_Private_Data *priv)
{
  int i, to_create, retval, embedded = 0;
  Call_Private_Data *cpriv;
  struct uri_list *el;
  Call *call;

  /* Mimic browser behavior of fetching html object, then a couple of
     embedded objects: */

  to_create = 1;
  if (priv->num_created > 0)
    {
      to_create = session_max_qlen (sess) - session_current_qlen (sess);
      embedded = 1;
    }

  for (i = 0; i < to_create && (!embedded || priv->uri_list); ++i)
    {
      ++priv->num_created;

      call = call_new ();
      if (!call)
	{
	  sess_failure (sess);
	  return;
	}
      if (embedded)
	{
	  el = priv->uri_list;
	  priv->uri_list = el->next;

	  cpriv = CALL_PRIVATE_DATA (call);
	  cpriv->to_free = el;
	  call_set_uri (call, el->uri, el->uri_len);
	}

      if (verbose > 1)
	printf ("%s: fetching `%s'\n",
		prog_name, (char *)call->req.iov[IE_URI].iov_base);

      retval = session_issue_call (sess, call);
      call_dec_ref (call);
      if (retval < 0)
	return;
    }
}
Esempio n. 9
0
static void
call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  Any_Type arg;
  Sess *sess;
  Call *call;

  assert (et == EV_CALL_DESTROYED && object_is_call (obj));

  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (cpriv->to_free)
    {
      free (cpriv->to_free);
      cpriv->to_free = 0;
    }
  ++priv->num_destroyed;

  if (sess->failed)
    return;

  if (priv->uri_list)
    /* there are some queued URI's which we may be able to issue now */
    issue_calls (sess, priv);
  else if (priv->num_destroyed >= priv->num_created)
    {
      /* we're done with this burst */
      if (++priv->num_reqs_completed >= param.wsesspage.num_reqs)
	/* we're done with this session */
	sess_dec_ref (sess);
      else 
	{
	  /* schedule the user-think-time timer */
	  priv->num_created = 0;
	  assert (!priv->timer);
	  arg.vp = sess;
	  priv->timer = timer_schedule (user_think_time_expired, arg,
					param.wsesspage.think_time);
	}
    }
}
Esempio n. 10
0
static void
call_recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
{
  Call_Private_Data *cpriv;
  Sess_Private_Data *priv;
  const char *cp, *end;
  struct iovec *line;
  Sess *sess;
  Call *call;
  int ch;

  assert (et == EV_CALL_RECV_DATA && object_is_call (obj));
  call = (Call *) obj;
  cpriv = CALL_PRIVATE_DATA (call);
  sess = session_get_sess_from_call (call);
  priv = SESS_PRIVATE_DATA (sess);

  if (cpriv->state == P_INITIAL)
    return;	/* not an html object */

  line = callarg.vp;
  cp = line->iov_base;
  end = cp + line->iov_len;
  while (cp < end)
    {
      ch = *cp++;

      switch (cpriv->state)
	{
	case P_INITIAL:
	  break;

	case P_HTML:
	  cpriv->buf_len = 0;
	  if (ch == '<')
	    cpriv->state = P_CMD;
	  break;

	case P_CMD:
	  if (isspace (ch) || ch == '=')
	    {
	      if (cpriv->buf_len > 0)
		{
		  if (DBG > 3)
		    fprintf (stderr, "found command `%.*s'\n",
			     cpriv->buf_len, cpriv->buf);

		  if (cpriv->buf_len == 3
		      && strcmp (cpriv->buf, "!--") == 0)
		    cpriv->state = P_DASH_ONE;
		  else if (cpriv->buf_len == 5
			   && strncasecmp (cpriv->buf, "frame", 5) == 0)
		    cpriv->state = P_SRC;
		  else if (cpriv->buf_len == 6
			   && strncasecmp (cpriv->buf, "iframe", 6) == 0)
		    cpriv->state = P_SRC;
		  else if (cpriv->buf_len == 6
			   && strncasecmp (cpriv->buf, "data", 6) == 0)
		    cpriv->state = P_DATA;
		  else if (cpriv->buf_len == 3
			   && strncasecmp (cpriv->buf, "img", 3) == 0)
		    cpriv->state = P_SRC;
		  cpriv->buf_len = 0;
		}
	      else
		cpriv->state = P_HTML;
	    }
	  else if (ch == '>')
	    cpriv->state = P_HTML;
	  else if (cpriv->buf_len < sizeof (cpriv->buf))
	    cpriv->buf[cpriv->buf_len++] = ch;
	  break;

	case P_DASH_ONE:
	  if (ch == '-')
	    cpriv->state = P_DASH_TWO;
	  break;

	case P_DASH_TWO:
	  cpriv->state = (ch == '-') ? P_RANGLE : P_DASH_ONE;
	  break;

	case P_RANGLE:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  break;

	case P_SRC:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  else
	    {
	      cpriv->buf[cpriv->buf_len++] = ch;
	      if (cpriv->buf_len == 4)
		{
		  if (strncasecmp (cpriv->buf, "src=", 4) == 0)
		    {
		      cpriv->state = P_LQUOTE;
		      cpriv->buf_len = 0;
		    }
		  else
		    {
		      memcpy (cpriv->buf, cpriv->buf + 1, 3);
		      cpriv->buf_len = 3;
		    }
		}
	    }
	  break;

	case P_DATA:
	  if (ch == '>')
	    cpriv->state = P_HTML;
	  else
	    {
	      cpriv->buf[cpriv->buf_len++] = ch;
	      if (cpriv->buf_len == 5)
		{
		  if (strncasecmp (cpriv->buf, "data=", 5) == 0)
		    {
		      cpriv->state = P_LQUOTE;
		      cpriv->buf_len = 0;
		    }
		  else
		    {
		      memcpy (cpriv->buf, cpriv->buf + 1, 4);
		      cpriv->buf_len = 4;
		    }
		}
	    }
	  break;

	case P_LQUOTE:
	  if (ch == '"')
	    cpriv->state = P_QUOTED_URI;
	  else if (!isspace (ch))
	    {
	      cpriv->state = P_NAKED_URI;
	      cpriv->buf[cpriv->buf_len++] = ch;
	    }
	  break;

	case P_NAKED_URI:
	case P_QUOTED_URI:
	  if ((cpriv->state == P_QUOTED_URI && ch == '"')
	      || (cpriv->state == P_NAKED_URI && isspace (ch)))
	    {
	      cpriv->buf[cpriv->buf_len] = '\0';
	      fetch_uri (sess, priv, cpriv, cpriv->buf, cpriv->buf_len);
	      cpriv->state = P_HTML;
	      cpriv->buf_len = 0;
	    }
	  else if (cpriv->buf_len < sizeof (cpriv->buf) - 1)
	    cpriv->buf[cpriv->buf_len++] = ch;
	  break;
	}
    }
}
Esempio n. 11
0
Sess *
session_get_sess_from_call (Call *call)
{
  assert (object_is_call (call));
  return CALL_PRIVATE_DATA (call)->sess;
}