blob: ce71825873bb98dd6355bd28436cc167c0198155 [file] [log] [blame]
/** @file
A brief file description
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
static unsigned int
get_addr(char *host)
{
unsigned int addr = inet_addr(host);
struct hostent *host_info = NULL;
if (!addr || (-1 == (int) addr)) {
host_info = gethostbyname(host);
if (!host_info) {
perror("gethostbyname");
return (unsigned int) -1;
}
addr = *((unsigned int *) host_info->h_addr);
}
return addr;
}
char *origin_server = "trafficserver.apache.org";
unsigned int origin_server_ip;
unsigned short origin_server_port = 8080;
struct NetTesterSM:public Continuation
{
VIO *client_read_vio;
VIO *client_resp_write_vio;
VIO *server_resp_read_vio;
int server_vc_closed, client_vc_closed;
IOBufferReader *client_reader, *client_parse_reader;
NetVConnection *client_vc, *server_vc;
MIOBuffer *request_buf;
MIOBuffer *response_buf;
char request[2000];
int req_len;
NetTesterSM(ProxyMutex * _mutex, NetVConnection * _vc):Continuation(_mutex),
server_vc_closed(0), client_vc_closed(0)
{
MUTEX_TRY_LOCK(lock, mutex, _vc->thread);
ink_release_assert(lock);
client_vc = _vc;
server_vc = NULL;
SET_HANDLER(&NetTesterSM::handle_request_read_from_client);
// jtest headers are really short
request_buf = new_MIOBuffer(1);
response_buf = new_MIOBuffer(8);
client_reader = request_buf->alloc_reader();
client_parse_reader = request_buf->alloc_reader();
client_read_vio = client_vc->do_io_read(this, INT_MAX, request_buf);
//client_vc->set_inactivity_timeout(HRTIME_SECONDS(60));
req_len = 0;
}
~NetTesterSM()
{
request_buf->dealloc_all_readers();
request_buf->clear();
free_MIOBuffer(request_buf);
response_buf->dealloc_all_readers();
response_buf->clear();
free_MIOBuffer(response_buf);
//close_server_vc();
//close_client_vc();
}
/* ********************* jtest sample request **********************
GET http://npdev:8080/0.5216393021/6000 HTTP/1.0
Proxy-Connection: Keep-Alive
*/
int handle_request_read_from_client(int event, void *data)
{
int r;
char *str;
switch (event) {
case VC_EVENT_READ_READY:
r = client_parse_reader->read_avail();
client_parse_reader->read(&request[req_len], r);
req_len += r;
request[req_len] = 0;
Debug("net_test", "%s\n", request);
fflush(stdout);
//client_vc->set_inactivity_timeout(HRTIME_SECONDS(30));
if (strcmp(&request[req_len - 4], "\r\n\r\n") == 0) {
Debug("net_test", "The request header is :\n%s\n", request);
client_vc->cancel_inactivity_timeout();
// connect to the origin server
SET_HANDLER(&NetTesterSM::handle_server_connect);
sslNetProcessor.connect_re(this, origin_server_ip, origin_server_port);
}
break;
case VC_EVENT_READ_COMPLETE:
/* FALLSTHROUGH */
case VC_EVENT_EOS:
r = client_parse_reader->read_avail();
str = NEW(new char[r + 10]);
client_parse_reader->read(str, r);
/* FALLSTHROUGH */
case VC_EVENT_ERROR:
case VC_EVENT_INACTIVITY_TIMEOUT:
close_client_vc();
// fixme
// handle timeout events
break;
default:
ink_release_assert(!"unknown event");
}
return EVENT_CONT;
}
int handle_server_connect(int event, Event * e)
{
switch (event) {
case NET_EVENT_OPEN:
server_vc = (NetVConnection *) e;
SET_HANDLER(&NetTesterSM::handle_write_request_to_server);
Debug("net_test", "connected to server\n");
Debug("net_test", "writing %d to server\n", client_reader->read_avail());
server_vc->do_io_write(this, client_reader->read_avail(), client_reader);
//vc->set_inactivity_timeout(HRTIME_SECONDS(10));
break;
case NET_EVENT_OPEN_FAILED:
default:
close_client_vc();
delete this;
}
return EVENT_CONT;
}
int handle_write_request_to_server(int event, Event * e)
{
IOBufferReader *resp_reader;
switch (event) {
case VC_EVENT_WRITE_READY:
Debug("net_test", "wrote some bytes to server\n");
break;
case VC_EVENT_WRITE_COMPLETE:
Debug("net_test", "wrote request to server\n");
SET_HANDLER(&NetTesterSM::handle_response_pump);
resp_reader = response_buf->alloc_reader();
response_buf->autopilot = 1;
server_resp_read_vio = server_vc->do_io_read(this, INT64_MAX, response_buf);
client_resp_write_vio = client_vc->do_io_write(this, INT64_MAX, resp_reader);
response_buf->assign_reader_vio(client_resp_write_vio, resp_reader);
response_buf->assign_writer_vio(server_resp_read_vio);
break;
case VC_EVENT_EOS:
case VC_EVENT_ERROR:
case VC_EVENT_INACTIVITY_TIMEOUT:
close_server_vc();
close_client_vc();
delete this;
return EVENT_DONE;
break;
default:
ink_release_assert(!"unknown event");
}
return EVENT_CONT;
}
void close_server_vc()
{
if (!server_vc_closed)
server_vc->do_io_close();
server_vc = NULL;
server_vc_closed = 1;
}
void close_client_vc()
{
if (!client_vc_closed)
client_vc->do_io_close();
client_vc = NULL;
client_vc_closed = 1;
}
int handle_response_pump(int event, Event * e)
{
int doc_len;
switch (event) {
case VC_EVENT_ERROR:
case VC_EVENT_INACTIVITY_TIMEOUT:
close_server_vc();
close_client_vc();
delete this;
return EVENT_DONE;
break;
case VC_EVENT_WRITE_READY:
case VC_EVENT_READ_READY:
ink_release_assert(!"unexpected READY event in handle_response_pump");
break;
case VC_EVENT_READ_COMPLETE:
case VC_EVENT_EOS:
doc_len = server_resp_read_vio->ndone;
Debug("net_test", "Got response %d bytes from server\n", doc_len);
close_server_vc();
if (client_resp_write_vio->ndone != doc_len) {
client_resp_write_vio->set_nbytes(doc_len);
client_vc->reenable(client_resp_write_vio);
} else {
Debug("net_test", "Wrote response %d bytes to client\n", client_resp_write_vio->ndone);
close_client_vc();
delete this;
return EVENT_DONE;
}
break;
case VC_EVENT_WRITE_COMPLETE:
Debug("net_test", "Wrote response %d bytes to client\n", client_resp_write_vio->ndone);
close_client_vc();
delete this;
return EVENT_DONE;
default:
ink_release_assert(!"unexpected event in handle_response_pump");
}
return EVENT_CONT;
}
};
struct NetTesterAccept:public Continuation
{
NetTesterAccept(ProxyMutex * _mutex):Continuation(_mutex)
{
SET_HANDLER(&NetTesterAccept::handle_accept);
}
int handle_accept(int event, void *data)
{
Debug("net_test", "Accepted a connection\n");
NetVConnection *vc = (NetVConnection *) data;
NEW(new NetTesterSM(new_ProxyMutex(), vc));
return EVENT_CONT;
}
};
//#define TEST_ACCEPT_CANCEL
struct Stop:public Continuation
{
Action *a;
Stop(ProxyMutex * m):Continuation(m)
{
SET_HANDLER(&Stop::stop);
}
int stop(int event, Event * e)
{
printf("Cancelling accept\n");
a->cancel();
return EVENT_DONE;
}
};
int
test_main()
{
Action *a;
origin_server_ip = get_addr(origin_server);
a = sslNetProcessor.accept(NEW(new NetTesterAccept(new_ProxyMutex())), 45080, true);
#ifdef TEST_ACCEPT_CANCEL
Stop *s = NEW(new Stop(new_ProxyMutex()));
eventProcessor.schedule_in(s, HRTIME_SECONDS(10));
s->a = a;
#endif
return 0;
}