+#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdint.h>
Client::Client(const ClientProto &serialized, Stream *stream)
: sock(serialized.sock()),
remote_addr(serialized.remote_addr()),
+ referer(serialized.referer()),
+ user_agent(serialized.user_agent()),
state(State(serialized.state())),
request(serialized.request()),
url(serialized.url()),
}
}
}
- if (serialized.has_connect_time_old()) {
- // Do a rough conversion from time() to monotonic time.
- if (clock_gettime(CLOCK_MONOTONIC_COARSE, &connect_time) == -1) {
- log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)");
- return;
- }
- connect_time.tv_sec += serialized.connect_time_old() - time(NULL);
- } else {
- connect_time.tv_sec = serialized.connect_time_sec();
- connect_time.tv_nsec = serialized.connect_time_nsec();
- }
+ connect_time.tv_sec = serialized.connect_time_sec();
+ connect_time.tv_nsec = serialized.connect_time_nsec();
}
ClientProto Client::serialize() const
ClientProto serialized;
serialized.set_sock(sock);
serialized.set_remote_addr(remote_addr);
+ serialized.set_referer(referer);
+ serialized.set_user_agent(user_agent);
serialized.set_connect_time_sec(connect_time.tv_sec);
serialized.set_connect_time_nsec(connect_time.tv_nsec);
serialized.set_state(state);
serialized.set_num_loss_events(num_loss_events);
return serialized;
}
+
+namespace {
+
+string escape_string(const string &str) {
+ string ret;
+ for (size_t i = 0; i < str.size(); ++i) {
+ char buf[16];
+ if (isprint(str[i]) && str[i] >= 32 && str[i] != '"' && str[i] != '\\') {
+ ret.push_back(str[i]);
+ } else {
+ snprintf(buf, sizeof(buf), "\\x%02x", (unsigned char)str[i]);
+ ret += buf;
+ }
+ }
+ return ret;
+}
+
+} // namespace
ClientStats Client::get_stats() const
{
}
stats.sock = sock;
stats.remote_addr = remote_addr;
+ stats.referer = escape_string(referer);
+ stats.user_agent = escape_string(user_agent);
stats.connect_time = connect_time;
stats.bytes_sent = bytes_sent;
stats.bytes_lost = bytes_lost;