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 set_uri (Event_Type et, Call * c) { int len, did_wrap = 0; const char *uri; assert (et == EV_CALL_NEW && object_is_call (c)); do { if (fcurrent >= fend) { if (did_wrap) panic ("%s: %s does not contain any valid URIs\n", prog_name, param.wlog.file); did_wrap = 1; /* We reached the end of the uri list so wrap around to the beginning. If not looping, also ask for the test to stop as soon as possible (the current request will still go out, but httperf won't wait for its reply to show up). */ fcurrent = fbase; if (!param.wlog.do_loop) core_exit (); } uri = fcurrent; len = strlen (fcurrent); call_set_uri (c, uri, len); fcurrent += len + 1; } while (len == 0); if (verbose) printf ("%s: accessing URI `%s'\n", prog_name, uri); }
static void recv_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; int index; Time xfer_time; assert (et == EV_CALL_RECV_STOP && object_is_call (c)); assert (c->basic.time_recv_start > 0); xfer_time = timer_now () - c->basic.time_recv_start; updatestats(&es_transfer, xfer_time); basic.hdr_bytes_received += c->reply.header_bytes; basic.reply_bytes_received += c->reply.content_bytes; basic.footer_bytes_received += c->reply.footer_bytes; index = (c->reply.status / 100); assert ((unsigned) index < NELEMS (basic.num_replies)); ++basic.num_replies[index]; ++num_replies; ++c->conn->basic.num_calls_completed; }
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 send_start(Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; assert(et == EV_CALL_SEND_START && object_is_call(c)); c->basic.time_send_start = timer_now(); }
static void send_stop(Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; assert(et == EV_CALL_SEND_STOP && object_is_call(c)); basic.req_bytes_sent += c->req.size; ++basic.num_sent; }
static void send_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call *call; assert (et == EV_CALL_SEND_RAW_DATA && object_is_call (obj)); call = (Call *) obj; print_request (call); }
static void uri_wrange_call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { assert (object_is_call (c)); Call *call = (Call *) obj; // this cleaning part is not actually called free(call->extra_header); }
static void recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { struct iovec *iov; Call *call; assert (et == EV_CALL_RECV_DATA && object_is_call (obj)); call = (Call *) obj; iov = callarg.vp; print_buf (call, "RB", iov->iov_base, iov->iov_len); }
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); }
static void recv_start(Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; Time now; assert(et == EV_CALL_RECV_START && object_is_call(c)); now = timer_now(); basic.call_response_sum += now - c->basic.time_send_start; c->basic.time_recv_start = now; ++basic.num_responses; }
static void call_created (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type arg) { Call *c = (Call *) obj; assert (et == EV_CALL_NEW && object_is_call (obj)); if (method_len > 0) call_set_method (c, param.method, method_len); if (extra_len > 0) call_append_request_header (c, extra, extra_len); }
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 recv_stop (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; flush_print_buf (call, "RB"); printf ("RS%ld: header %ld content %ld footer %ld\n", call->id, (long) call->reply.header_bytes, (long) call->reply.content_bytes, (long) call->reply.footer_bytes); }
static void recv_start (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; Time now; assert (et == EV_CALL_RECV_START && object_is_call (c)); now = timer_now (); updatestats(&es_response, now - c->basic.time_send_start); c->basic.time_recv_start = now; }
static void call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Conn_Private_Data *cpriv; struct Conn_Info *ci; Sess *sess; Conn *conn; Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; conn = call->conn; cpriv = CONN_PRIVATE_DATA (conn); sess = cpriv->sess; ci = cpriv->ci; ci->is_successful = 1; /* conn has received at least one reply */ /* remove the call from the conn_info structure */ assert (ci->call[ci->rd] == call && ci->num_pending > 0 && ci->num_sent > 0); ci->call[ci->rd] = 0; ci->rd = (ci->rd + 1) % MAX_PIPED; --ci->num_pending; --ci->num_sent; /* if the reply status matches the failure status, the session has failed */ if (param.failure_status && call->reply.status == param.failure_status) { if (param.retry_on_failure) session_issue_call (sess, call); else sess_failure (sess); } call_dec_ref (call); if (param.http_version < 0x10001) { /* Rather than waiting for the connection to close on us, we close it pro-actively (this is what a pre-1.1 browser would do. */ core_close (ci->conn); ci->conn = 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); } } }
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 recv_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; int index; Time transfer_time; assert (et == EV_CALL_RECV_STOP && object_is_call (c)); assert (c->basic.time_recv_start > 0); transfer_time=timer_now () - c->basic.time_recv_start; basic.call_xfer_sum += transfer_time; basic.hdr_bytes_received += c->reply.header_bytes; basic.reply_bytes_received += c->reply.content_bytes; basic.footer_bytes_received += c->reply.footer_bytes; index = (c->reply.status / 100); assert ((unsigned) index < NELEMS (basic.num_replies)); ++basic.num_replies[index]; ++num_replies; #ifdef EXTENDED_STATS basic.measurement[measure_index].connect=c->conn->basic.connect; basic.measurement[measure_index].reply=c->basic.reply; basic.measurement[measure_index].xfer=transfer_time; basic.measurement[measure_index].response_size = c->reply.header_bytes + c->reply.content_bytes + c->reply.footer_bytes; basic.measurement[measure_index].id = c->sess_id; if(c->conn->basic.connect!=-1) basic.measurement[measure_index].start=c->conn->basic.time_connect_start-start; else basic.measurement[measure_index].start=c->basic.time_send_start-start; basic.measurement[measure_index].num_active_conns=num_active_conns; measure_index++; if(measure_index==MAX_LOG_SIZE) measure_index=0; #endif c->conn->basic.connect=-1; ++c->conn->basic.num_calls_completed; }
static void set_uri (Event_Type et, Call *call) { assert (et == EV_CALL_NEW && object_is_call (call)); call_set_uri (call, param.uri, uri_len); }
Sess * session_get_sess_from_call (Call *call) { assert (object_is_call (call)); return CALL_PRIVATE_DATA (call)->sess; }
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; } } }
static void set_uri (Event_Type et, Call * c) { char *uri; int uri_len, did_wrap = 0, range_len, input_len; const char *input_line; assert (et == EV_CALL_NEW && object_is_call (c)); do { if (fcurrent >= fend) { if (did_wrap) panic ("%s: %s does not contain any valid URIs\n", prog_name, param.wrangelog.file); did_wrap = 1; /* We reached the end of the uri list so wrap around to the beginning. If not looping, also ask for the test to stop as soon as possible (the current request will still go out, but httperf won't wait for its reply to show up). */ fcurrent = fbase; if (!param.wrangelog.do_loop) core_exit (); } input_line = fcurrent; input_len = strlen (fcurrent); /*****************************/ // int j; // while (input_line[j] != ' ') { // j++; // if (j > input_len) // { // panic ("Error: illegal format for wrangelog\n"); // } // } // // uri_len = j; uri_len = strcspn( input_line, " "); uri = fcurrent; /***************************/ int range_size = input_len - uri_len - 1; char prefix_extra_hdrs[] = "Range: bytes="; size_t prefix_size = strlen(prefix_extra_hdrs); char suffix_extra_hdrs[] = "\r\n"; size_t suffix_size = strlen(suffix_extra_hdrs); size_t extra_header_len = prefix_size + range_size + suffix_size; c->extra_header = (char*) malloc( sizeof(char) * extra_header_len); // Copy the prefix strncpy(c->extra_header, prefix_extra_hdrs, prefix_size); // Copy the range value strncpy(c->extra_header + prefix_size, fcurrent + uri_len + 1, range_size); // Copy the suffix strncpy(c->extra_header + prefix_size + range_size, suffix_extra_hdrs, suffix_size); call_set_uri (c, uri, uri_len); fcurrent += input_len + 1; call_append_request_header (c, c->extra_header,extra_header_len); } while (input_len == 0); if (verbose) printf ("%s: accessing URI `%s'\n", prog_name, uri); }