Merge pull request #17 from sorced-jim/master

Add a timeout to spdycat
This commit is contained in:
Tatsuhiro Tsujikawa 2012-04-05 10:25:26 -07:00
commit dec472d6c7
3 changed files with 25 additions and 6 deletions

View File

@ -460,6 +460,9 @@ void prepare_response(Request *req, SpdyEventHandler *hd)
const std::string &field = req->headers[i].first; const std::string &field = req->headers[i].first;
const std::string &value = req->headers[i].second; const std::string &value = req->headers[i].second;
if(!url_found && field == ":path") { if(!url_found && field == ":path") {
// Do not response to this request to allow clients to test timeouts.
if (value.find("?spdyd_do_not_respond_to_req=yes") != std::string::npos)
return;
url_found = true; url_found = true;
url = value; url = value;
} else if(field == ":method") { } else if(field == ":method") {

View File

@ -62,8 +62,9 @@ struct Config {
bool remote_name; bool remote_name;
bool verbose; bool verbose;
bool spdy3_only; bool spdy3_only;
int timeout;
Config():null_out(false), remote_name(false), verbose(false), Config():null_out(false), remote_name(false), verbose(false),
spdy3_only(false) {} spdy3_only(false), timeout(-1) {}
}; };
struct Request { struct Request {
@ -193,18 +194,20 @@ int communicate(const std::string& host, uint16_t port,
} }
pollfds[0].fd = fd; pollfds[0].fd = fd;
ctl_poll(pollfds, &sc); ctl_poll(pollfds, &sc);
int end_time = time(NULL) + config.timeout;
int timeout = config.timeout;
bool ok = true; bool ok = true;
while(sc.want_read() || sc.want_write()) { while(sc.want_read() || sc.want_write()) {
int nfds = poll(pollfds, npollfds, -1); int nfds = poll(pollfds, npollfds, timeout);
if(nfds == -1) { if(nfds == -1) {
perror("poll"); perror("poll");
return -1; return -1;
} }
if(pollfds[0].revents & (POLLIN | POLLOUT)) { if(pollfds[0].revents & (POLLIN | POLLOUT)) {
if(sc.recv() != 0 || sc.send() != 0) { if(sc.recv() != 0 || sc.send() != 0) {
ok = false;
std::cout << "Fatal" << std::endl; std::cout << "Fatal" << std::endl;
ok = false;
break; break;
} }
} }
@ -213,9 +216,13 @@ int communicate(const std::string& host, uint16_t port,
ok = false; ok = false;
break; break;
} }
if(!ok) { timeout = timeout == -1 ? timeout : end_time - time(NULL);
if (config.timeout != -1 && timeout <= 0) {
std::cout << "Requests to " << hostport << "timed out.";
ok = false;
break; break;
} }
assert(ok);
ctl_poll(pollfds, &sc); ctl_poll(pollfds, &sc);
} }
@ -275,7 +282,7 @@ int run(char **uris, int n)
void print_usage(std::ostream& out) void print_usage(std::ostream& out)
{ {
out << "Usage: spdycat [-Onv] [URI...]" << std::endl; out << "Usage: spdycat [-Onv3] [--timeout=seconds] [URI...]" << std::endl;
} }
void print_help(std::ostream& out) void print_help(std::ostream& out)
@ -291,6 +298,7 @@ void print_help(std::ostream& out)
<< " ends with '/', 'index.html' is used as a\n" << " ends with '/', 'index.html' is used as a\n"
<< " filename. Not implemented yet.\n" << " filename. Not implemented yet.\n"
<< " -3, --spdy3 Only use SPDY/3.\n" << " -3, --spdy3 Only use SPDY/3.\n"
<< " -t, --timeout=N Timeout each request after N seconds.\n"
<< "\n" << "\n"
<< std::endl; << std::endl;
} }
@ -303,11 +311,12 @@ int main(int argc, char **argv)
{"null-out", no_argument, 0, 'n' }, {"null-out", no_argument, 0, 'n' },
{"remote-name", no_argument, 0, 'O' }, {"remote-name", no_argument, 0, 'O' },
{"spdy3", no_argument, 0, '3' }, {"spdy3", no_argument, 0, '3' },
{"timeout", required_argument, 0, 't' },
{"help", no_argument, 0, 'h' }, {"help", no_argument, 0, 'h' },
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "Onhv3", long_options, &option_index); int c = getopt_long(argc, argv, "Onhv3t", long_options, &option_index);
if(c == -1) { if(c == -1) {
break; break;
} }
@ -327,6 +336,9 @@ int main(int argc, char **argv)
case '3': case '3':
config.spdy3_only = true; config.spdy3_only = true;
break; break;
case 't':
config.timeout = atoi(optarg);
break;
case '?': case '?':
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:

View File

@ -83,6 +83,10 @@ class EndToEndSpdy2Tests(EndToEndSpdyTests):
def testOneFailedRequest(self): def testOneFailedRequest(self):
self.assertEquals(1, subprocess.call([self.client, 'http://localhost:2/'])) self.assertEquals(1, subprocess.call([self.client, 'http://localhost:2/']))
def testOneTimedOutRequest(self):
self.assertEquals(1, self.call('/?spdyd_do_not_respond_to_req=yes',
['--timeout=2']))
class EndToEndSpdy3Tests(EndToEndSpdyTests): class EndToEndSpdy3Tests(EndToEndSpdyTests):
@classmethod @classmethod