Commit 16651823 authored by Pekka Pessi's avatar Pekka Pessi

Added client timeout and NTHTAG_EXPIRES() to nth http client library.

darcs-hash:20051115161442-65a35-f9297bc09422ff8b2a83d6a039db5ed0925a2066.gz
parent 68848bbe
......@@ -96,6 +96,7 @@ struct nth_engine_s {
url_t *he_default_proxy;
unsigned he_now;
unsigned he_expires;
/* Attributes */
unsigned he_streaming:1; /**< Enable streaming */
......@@ -125,7 +126,8 @@ struct nth_client_s {
char const *hc_method_name;
url_t const *hc_url; /**< Original RequestURI */
su_duration_t hc_timeout; /**< Timer */
unsigned hc_timeout; /**< Client timeout */
unsigned hc_expires; /**< Client expires */
/* Request state */
unsigned short hc_status;
......@@ -286,6 +288,7 @@ nth_engine_t *nth_engine_create(su_root_t *root,
he->he_root = root;
he->he_mflags = MSG_DO_CANONIC;
he->he_mclass = http_default_mclass();
he->he_expires = 32000;
ta_start(ta, tag, value);
......@@ -323,6 +326,7 @@ int nth_engine_set_params(nth_engine_t * he,
{
int n;
ta_list ta;
unsigned expires;
int error_msg;
msg_mclass_t const *mclass;
int mflags;
......@@ -334,6 +338,7 @@ int nth_engine_set_params(nth_engine_t * he,
ta_start(ta, tag, value);
expires = he->he_expires;
error_msg = he->he_error_msg;
mclass = he->he_mclass;
mflags = he->he_mflags;
......@@ -341,6 +346,7 @@ int nth_engine_set_params(nth_engine_t * he,
proxy = (void *) he->he_default_proxy;
n = tl_gets(ta_args(ta),
NTHTAG_EXPIRES_REF(expires),
NTHTAG_ERROR_MSG_REF(error_msg),
NTHTAG_MCLASS_REF(mclass),
NTHTAG_MFLAGS_REF(mflags),
......@@ -361,6 +367,7 @@ int nth_engine_set_params(nth_engine_t * he,
}
if (n > 0) {
he->he_expires = expires;
he->he_error_msg = error_msg != 0;
if (mclass)
he->he_mclass = mclass;
......@@ -396,6 +403,7 @@ int nth_engine_get_params(nth_engine_t const *he,
NTHTAG_ERROR_MSG(he->he_error_msg),
NTHTAG_MCLASS(mclass),
NTHTAG_MFLAGS(he->he_mflags),
NTHTAG_EXPIRES(he->he_expires),
NTHTAG_STREAMING(he->he_streaming),
NTHTAG_PROXY((url_string_t *) he->he_default_proxy),
TAG_END());
......@@ -620,6 +628,7 @@ nth_client_t *nth_client_tcreate(nth_engine_t * engine,
char const *version = http_version_1_1;
nth_client_t const *template = NULL;
auth_client_t **auc = none;
unsigned expires = engine->he_expires;
int ok = 0;
ta_start(ta, tag, value);
......@@ -627,7 +636,10 @@ nth_client_t *nth_client_tcreate(nth_engine_t * engine,
tl_gets(ta_args(ta),
NTHTAG_TEMPLATE_REF(template),
NTHTAG_AUTHENTICATION_REF(auc),
NTHTAG_MESSAGE_REF(msg), HTTPTAG_VERSION_REF(version), TAG_END());
NTHTAG_MESSAGE_REF(msg),
NTHTAG_EXPIRES_REF(expires),
HTTPTAG_VERSION_REF(version),
TAG_END());
if (msg == none) {
if (template && template->hc_request)
......@@ -655,6 +667,9 @@ nth_client_t *nth_client_tcreate(nth_engine_t * engine,
hc = hc_create(engine, callback, magic, msg, ta_tags(ta));
if (hc)
hc->hc_expires = expires;
if (hc == NULL);
else if (http_add_tl(msg, http,
//HTTPTAG_CONNECTION((http_connection_t *)-1),
......@@ -1027,7 +1042,11 @@ static nth_client_t *hc_send(nth_client_t * hc)
if (hc->hc_pending < 0)
hc->hc_pending = 0;
hc->hc_timeout = he_now(he) + 32000; /* XXX */
if (hc->hc_expires) {
hc->hc_timeout = he_now(he) + hc->hc_expires; /* XXX */
if (hc->hc_timeout == 0)
hc->hc_timeout++;
}
return hc;
}
......@@ -1232,8 +1251,11 @@ int hc_default_cb(nth_client_magic_t * magic,
static
void hc_timer(nth_engine_t * he, nth_client_t * hc, uint32_t now)
{
/* Not implemented.
*
* How to define meaningful timeout policy?
*/
if (hc->hc_timeout == 0)
return;
if ((int)hc->hc_timeout - (int)now > 0)
return;
hc_reply(hc, HTTP_408_TIMEOUT);
}
......@@ -31,7 +31,7 @@
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Tue Jul 24 22:28:34 2001 ppessi
* @date Last modified: Wed Jul 20 20:35:32 2005 kaiv
* @date Last modified: Tue Nov 15 17:01:14 2005 ppessi
*/
#include "config.h"
......@@ -56,6 +56,7 @@ tag_typedef_t nthtag_streaming = BOOLTAG_TYPEDEF(streaming);
/* Client */
tag_typedef_t nthtag_proxy = URLTAG_TYPEDEF(proxy);
tag_typedef_t nthtag_expires = UINTTAG_TYPEDEF(expires);
tag_typedef_t nthtag_error_msg = BOOLTAG_TYPEDEF(error_msg);
tag_typedef_t nthtag_template = PTRTAG_TYPEDEF(template);
tag_typedef_t nthtag_authentication = PTRTAG_TYPEDEF(authentication);
......
......@@ -31,7 +31,6 @@
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Sun Oct 13 22:23:48 2002 ppessi
* @date Last modified: Wed Jul 20 20:35:32 2005 kaiv
*/
#ifndef SU_TAG_H
......@@ -88,6 +87,13 @@ NTH_DLL extern tag_typedef_t nthtag_proxy;
NTH_DLL extern tag_typedef_t nthtag_proxy_ref;
#define NTHTAG_PROXY_REF(x) nthtag_proxy_ref, urltag_url_vr(&(x))
NTH_DLL extern tag_typedef_t nthtag_expires;
/** Expires in milliseconds for client transactions. @HI */
#define NTHTAG_EXPIRES(x) nthtag_expires, tag_uint_v((x))
NTH_DLL extern tag_typedef_t nthtag_expires_ref;
#define NTHTAG_EXPIRES_REF(x) nthtag_expires_ref, tag_uint_vr(&(x))
NTH_DLL extern tag_typedef_t nthtag_error_msg;
/** If true, nth engine generates complete error messages. @HI */
#define NTHTAG_ERROR_MSG(x) nthtag_error_msg, tag_bool_v((x))
......
......@@ -28,7 +28,6 @@
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Tue Oct 22 20:52:37 2002 ppessi
* @date Last modified: Wed Aug 10 11:25:38 2005 ppessi
*/
#include "config.h"
......@@ -36,19 +35,25 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <assert.h>
#if HAVE_ALARM
#include <unistd.h>
#include <signal.h>
#endif
typedef struct tester tester_t;
typedef struct site site_t;
typedef struct client client_t;
#define SU_ROOT_MAGIC_T tester_t
#include <su_tagarg.h>
#include <su_wait.h>
#define NTH_CLIENT_MAGIC_T tester_t
#define NTH_CLIENT_MAGIC_T client_t
#define NTH_SITE_MAGIC_T site_t
#include "nth.h"
......@@ -91,6 +96,11 @@ struct site
tagi_t *s_tags;
};
struct client
{
unsigned c_status;
};
struct tester
{
su_home_t t_home[1];
......@@ -104,6 +114,11 @@ struct tester
su_sockaddr_t t_addr[1];
socklen_t t_addrlen;
su_socket_t t_sink;
url_string_t *t_sinkuri;
su_sockaddr_t t_sinkaddr[1];
socklen_t t_sinkaddrlen;
site_t *t_sites;
site_t *t_master;
};
......@@ -229,6 +244,7 @@ static int test_nth_client_api(tester_t *t)
int error_msg = -1;
msg_mclass_t const *mclass = (void *)-1;
int mflags = -1;
unsigned expires = -1;
int streaming = -1;
url_string_t const *proxy = (void *)-1;
......@@ -238,14 +254,16 @@ static int test_nth_client_api(tester_t *t)
NTHTAG_ERROR_MSG_REF(error_msg),
NTHTAG_MCLASS_REF(mclass),
NTHTAG_MFLAGS_REF(mflags),
NTHTAG_EXPIRES_REF(expires),
NTHTAG_STREAMING_REF(streaming),
NTHTAG_PROXY_REF(proxy),
TAG_END()),
5);
6);
TEST(error_msg, 1);
TEST(mclass, t->t_mclass);
TEST(mflags, MSG_DO_CANONIC|MSG_DO_COMPACT);
TEST(expires, 32000);
TEST(streaming, 0);
TEST_1(proxy != NULL);
TEST_1(proxy_str = url_as_string(t->t_home, proxy->us_url));
......@@ -257,14 +275,16 @@ static int test_nth_client_api(tester_t *t)
NTHTAG_ERROR_MSG(0),
NTHTAG_MCLASS(http_default_mclass()),
NTHTAG_MFLAGS(0),
NTHTAG_EXPIRES(10000),
NTHTAG_STREAMING(2),
NTHTAG_PROXY(proxy),
TAG_END()),
5);
6);
error_msg = -1;
mclass = (void *)-1;
mflags = -1;
expires = (unsigned)-1;
streaming = -1;
proxy = (void *)-1;
......@@ -272,14 +292,16 @@ static int test_nth_client_api(tester_t *t)
NTHTAG_ERROR_MSG_REF(error_msg),
NTHTAG_MCLASS_REF(mclass),
NTHTAG_MFLAGS_REF(mflags),
NTHTAG_EXPIRES_REF(expires),
NTHTAG_STREAMING_REF(streaming),
NTHTAG_PROXY_REF(proxy),
TAG_END()),
5);
6);
TEST(error_msg, 0);
TEST(mclass, NULL);
TEST(mflags, 0);
TEST(expires, 10000);
TEST(streaming, 1);
TEST_1(proxy != NULL);
TEST_1(proxy_str = url_as_string(t->t_home, proxy->us_url));
......@@ -429,8 +451,6 @@ static int send_request(tester_t *t, char const *req, size_t reqlen,
BEGIN();
alarm(5);
if (c == -1) {
c = socket(t->t_addr->su_family, SOCK_STREAM, 0); TEST_1(c != -1);
TEST_1(connect(c, &t->t_addr->su_sa, t->t_addrlen) != -1);
......@@ -587,14 +607,85 @@ static int test_requests(tester_t *t)
static int init_engine(tester_t *t)
{
BEGIN();
int s;
t->t_engine = nth_engine_create(t->t_root,
NTHTAG_STREAMING(0),
TAG_END());
TEST_1(t->t_engine);
t->t_sink = s = su_socket(AF_INET, SOCK_STREAM, 0); TEST_1(s != -1);
TEST(bind(s, &t->t_sinkaddr->su_sa,
t->t_sinkaddrlen = (sizeof t->t_sinkaddr->su_sin)),
0);
TEST_1(getsockname(s, &t->t_sinkaddr->su_sa, &t->t_sinkaddrlen) != -1);
TEST(listen(t->t_sink, 5), 0);
TEST_1(t->t_sinkuri = (url_string_t *)
su_sprintf(t->t_home, "HTTP://127.0.0.1:%u",
htons(t->t_sinkaddr->su_port)));
END();
}
static int response_to_client(client_t *c,
nth_client_t *hc,
http_t const *http)
{
if (http) {
c->c_status = http->http_status->st_status;
}
else {
c->c_status = nth_client_status(hc);
}
return 0;
}
static int test_client(tester_t *t)
{
BEGIN();
nth_client_t *hc;
char *uri;
client_t client[1];
memset(client, 0, sizeof client);
TEST_1(uri = su_strcat(NULL, t->t_master->s_url->us_str, "/"));
TEST_1(hc = nth_client_tcreate(t->t_engine,
response_to_client, client,
HTTP_METHOD_GET,
URL_STRING_MAKE(uri),
TAG_END()));
while (client->c_status == 0) su_root_step(t->t_root, 1);
TEST(client->c_status, 200);
nth_client_destroy(hc);
su_free(NULL, uri);
memset(client, 0, sizeof client);
TEST_1(hc = nth_client_tcreate(t->t_engine,
response_to_client, client,
HTTP_METHOD_GET,
URL_STRING_MAKE(t->t_sinkuri),
NTHTAG_EXPIRES(1000),
TAG_END()));
while (client->c_status == 0) su_root_step(t->t_root, 1);
TEST(client->c_status, 408);
nth_client_destroy(hc);
END();
}
#if HAVE_ALARM
static RETSIGTYPE sig_alarm(int s)
{
fprintf(stderr, "%s: FAIL! test timeout!\n", name);
exit(1);
}
#endif
void usage(void)
{
......@@ -606,6 +697,7 @@ int main(int argc, char **argv)
{
int i;
int retval = 0;
int o_alarm = 1;
tester_t t[1] = {{{ SU_HOME_INIT(t) }}};
......@@ -623,6 +715,9 @@ int main(int argc, char **argv)
t->t_proxy = (url_string_t *)argv[++i];
else if (strcmp(argv[i], "-s") == 0 && argv[i + 1])
srcdir = argv[++i];
else if (strcmp(argv[i], "--no-alarm") == 0) {
o_alarm = 0;
}
else if (strcmp(argv[i], "-") == 0) {
i++; break;
}
......@@ -635,6 +730,13 @@ int main(int argc, char **argv)
t->t_srcdir = srcdir;
#if HAVE_ALARM
if (o_alarm) {
alarm(60);
signal(SIGALRM, sig_alarm);
}
#endif
su_init();
retval |= init_test(t);
......@@ -643,10 +745,10 @@ int main(int argc, char **argv)
retval |= init_server(t);
retval |= test_requests(t);
retval |= init_engine(t);
retval |= test_client(t);
retval |= deinit_test(t);
su_deinit();
return retval;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment