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); } }
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; } }
static void call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); ++priv->num_calls_completed; }
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); } } }
static void call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { char *hdr, *start, *end; Sess_Private_Data *priv; size_t len; struct iovec *line; Sess *sess; Call *call; assert (et == EV_CALL_RECV_HDR && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); line = callarg.vp; hdr = line->iov_base; if (tolower (hdr[0]) == 's' && line->iov_len > 12 && strncasecmp (hdr + 1, "et-cookie: ", 11) == 0) { /* munch time! */ start = hdr + 12; end = strchr (start, ';'); if (!end) end = hdr + line->iov_len; len = end - start; if (DBG > 0 && priv->cookie_len > 0) fprintf (stderr, "%s: can't handle more than one " "cookie at a time, replacing existing one\n", prog_name); if (len + 10 >= MAX_COOKIE_LEN) { fprintf (stderr, "%s.sess_cookie: truncating cookie to %d bytes\n", prog_name, MAX_COOKIE_LEN - 11); len = MAX_COOKIE_LEN - 11; } memcpy (priv->cookie, "Cookie: ", 8); memcpy (priv->cookie + 8, start, len); memcpy (priv->cookie + 8 + len, "\r\n", 2); priv->cookie[10 + len] = '\0'; priv->cookie_len = len + 10; if (DBG > 0) fprintf (stderr, "%s: got cookie `%s'\n", prog_name, start); } }
static void call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Any_Type arg; Sess *sess; Call *call; Sess_Private_Data *priv; assert (et == EV_CALL_DESTROYED && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); ++priv->num_calls_destroyed; if (priv->num_calls_destroyed >= param.wsess.num_calls) { /* we're done with this session */ if (!sess->failed) sess_dec_ref (sess); } else if (priv->num_calls_in_this_burst < param.burst_len) /* now that we received the reply to the first call in this burst, create the remaining calls */ issue_calls (sess, priv); else if (priv->num_calls_destroyed >= priv->num_calls_target) { /* we're done with this burst---schedule the user-think-time timer */ priv->num_calls_in_this_burst = 0; priv->num_calls_target += param.burst_len; assert (!priv->timer); arg.vp = sess; priv->timer = timer_schedule (user_think_time_expired, arg, param.wsess.think_time); } }
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; } } }