Commit 33945d39 authored by Pekka Pessi's avatar Pekka Pessi

nua: accept incoming PUBLISH if the Event matches with nua Allow-Events.

Updated nua_publish.c, test_simple.c.

Moved #nua_i_publish documentation to nua_publish.c from nua.docs.

darcs-hash:20061017165456-65a35-ecf4ad618e4d702fa07f37421c534d540b48e792.gz
parent 1085fa0b
......@@ -2123,18 +2123,7 @@ NUTAG_AUTOANSWER(0) on B side, NUTAG_AUTOACK(0) on A side.
* @param tags empty
*/
/** @var nua_event_e::nua_i_publish
*
* Incoming PUBLISH.
*
* @param nh operation handle associated with the call
* @param hmagic operation magic associated with the call
* (NULL if outside session)
* @param status statuscode of response sent automatically by stack
* @param sip incoming PUBLISH request
* @param tags empty
*/
/* nua_i_publish documented with nua_stack_process_publish() */
/** @var nua_event_e::nua_i_refer
*
......
......@@ -399,18 +399,80 @@ static int nua_publish_usage_shutdown(nua_handle_t *nh,
return -1; /* Request in progress */
}
/* ---------------------------------------------------------------------- */
/* Server side */
static
int respond_to_publish(nua_server_request_t *sr, tagi_t const *tags);
/** @var nua_event_e::nua_i_publish
*
* Incoming PUBLISH request.
*
* In order to receive #nua_i_publish events, the application must enable
* both the PUBLISH method with NUTAG_ALLOW() tag and the acceptable SIP
* events with nua_set_params() tag NUTAG_ALLOW_EVENTS().
*
* The nua_response() call responding to a PUBLISH request must have
* NUTAG_WITH() (or NUTAG_WITH_CURRENT()/NUTAG_WITH_SAVED()) tag. Note that
* a successful response to PUBLISH @b MUST include @Expires and @SIPETag
* headers.
*
* @param nh operation handle associated with the call
* @param hmagic operation magic associated with the call
* (NULL if outside session)
* @param status statuscode of response sent automatically by stack
* @param sip incoming PUBLISH request
* @param tags empty
*
* @sa @RFC3903, nua_respond(),
* @Expires, @SIPETag, @SIPIfMatch, @Event,
* nua_subscribe(), #nua_i_subscribe,
* nua_notifier(), #nua_i_subscription,
*/
int nua_stack_process_publish(nua_t *nua,
nua_handle_t *nh,
nta_incoming_t *irq,
sip_t const *sip)
{
if (nh == NULL)
if (!(nh = nua_stack_incoming_handle(nua, irq, sip, 0)))
return 500; /* Respond with 500 Internal Server Error */
nua_server_request_t *sr, sr0[1];
sip_allow_events_t *allow_events = NUA_PGET(nua, nh, allow_events);
sip_event_t *o = sip->sip_event;
char const *event = o ? o->o_type : NULL;
sr = SR_INIT(sr0);
if (!allow_events)
SR_STATUS1(sr, SIP_501_NOT_IMPLEMENTED);
else if (!event || !msg_header_find_param(allow_events->k_common, event))
SR_STATUS1(sr, SIP_489_BAD_EVENT);
sr = nua_server_request(nua, nh, irq, sip, sr, sizeof *sr,
respond_to_publish, nua_i_publish, 0);
return nua_stack_server_event(nua, sr, TAG_END());
}
nua_stack_event(nh->nh_nua, nh, nta_incoming_getrequest(irq),
nua_i_publish, SIP_501_NOT_IMPLEMENTED, TAG_END());
static
int respond_to_publish(nua_server_request_t *sr, tagi_t const *tags)
{
nua_handle_t *nh = sr->sr_owner;
nua_t *nua = nh->nh_nua;
msg_t *msg;
msg = nua_server_response(sr, sr->sr_status, sr->sr_phrase, TAG_NEXT(tags));
return 501; /* Respond automatically with 501 Not Implemented */
if (msg) {
nta_incoming_mreply(sr->sr_irq, msg);
}
else {
SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR);
nta_incoming_treply(sr->sr_irq, sr->sr_status, sr->sr_phrase, TAG_END());
nua_stack_event(nua, nh, NULL,
nua_i_error, 900, "PUBLISH Response Fails",
TAG_END());
}
return sr->sr_status >= 200 ? sr->sr_status : 0;
}
......@@ -23,7 +23,7 @@
*/
/**@CFILE test_nua_simple.c
* @brief NUA-11: Test MESSAGE and PUBLISH.
* @brief NUA-11: Test SIMPLE methods: MESSAGE and PUBLISH.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti Mela@nokia.com>
......@@ -43,10 +43,7 @@
#define __func__ "test_simple"
#endif
/* ======================================================================== */
/* Test simple methods: MESSAGE, PUBLISH */
int test_simple(struct context *ctx)
int test_message(struct context *ctx)
{
BEGIN();
......@@ -159,15 +156,68 @@ int test_simple(struct context *ctx)
if (print_headings)
printf("TEST NUA-11.2: PASSED\n");
END();
}
int respond_with_etag(CONDITION_PARAMS)
{
msg_t *with = nua_current_request(nua);
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
return 0;
save_event_in_list(ctx, event, ep, call);
switch (event) {
char const *etag;
case nua_i_publish:
etag = sip->sip_if_match ? sip->sip_if_match->g_value : NULL;
if (sip->sip_if_match && (etag == NULL || strcmp(etag, "tagtag"))) {
RESPOND(ep, call, nh, SIP_412_PRECONDITION_FAILED,
NUTAG_WITH(with),
TAG_END());
}
else {
RESPOND(ep, call, nh, SIP_200_OK,
NUTAG_WITH(with),
SIPTAG_ETAG_STR("tagtag"),
SIPTAG_EXPIRES_STR("3600"),
SIPTAG_EXPIRES(sip->sip_expires), /* overrides 3600 */
TAG_END());
}
return 1;
default:
return 0;
}
}
int test_publish(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a, *b = &ctx->b;
struct call *a_call = a->call, *b_call = b->call;
struct event *e;
sip_t const *sip;
/* PUBLISH test
A B
|-------PUBLISH----->|
|<-------405---------| (not allowed by default)
|<-------405---------| (method not allowed by default)
| |
|-------PUBLISH----->|
|<-------500---------| (XXX - not implemented)
|<-------501---------| (no events allowed)
| |
|-------PUBLISH----->|
|<-------489---------| (event not allowed by default)
| |
|-------PUBLISH----->|
|<-------200---------| (event allowed, responded)
| |
|-----un-PUBLISH---->|
|<-------200---------| (event allowed, responded)
*/
if (print_headings)
......@@ -191,14 +241,6 @@ int test_simple(struct context *ctx)
TEST(e->data->e_status, 405);
TEST_1(!e->next);
/*
Server events:
nua_i_publish
*/
/* TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_publish);
TEST(e->data->e_status, 405); */
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
......@@ -218,7 +260,7 @@ int test_simple(struct context *ctx)
SIPTAG_PAYLOAD_STR("sip:example.com\n"),
TAG_END());
run_ab_until(ctx, -1, save_until_final_response, -1, save_until_received);
run_a_until(ctx, -1, save_until_final_response);
/* Client events:
nua_publish(), nua_r_publish
......@@ -227,22 +269,106 @@ int test_simple(struct context *ctx)
TEST(e->data->e_status, 501); /* Not implemented */
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
/* Allow presence event */
nua_set_params(b->nua, NUTAG_ALLOW_EVENTS("presence"), TAG_END());
run_b_until(ctx, nua_r_set_params, until_final_response);
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
PUBLISH(a, a_call, a_call->nh,
TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
SIPTAG_EVENT_STR("reg"),
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
SIPTAG_PAYLOAD_STR("sip:example.com\n"),
TAG_END());
run_a_until(ctx, -1, save_until_final_response);
/* Client events:
nua_publish(), nua_r_publish
*/
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_publish);
TEST(e->data->e_status, 489); /* Bad Event */
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
PUBLISH(a, a_call, a_call->nh,
TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
SIPTAG_EVENT_STR("presence"),
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
SIPTAG_PAYLOAD_STR("sip:example.com\n"),
TAG_END());
run_ab_until(ctx, -1, save_until_final_response, -1, respond_with_etag);
/* Client events:
nua_publish(), nua_r_publish
*/
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_publish);
TEST(e->data->e_status, 200);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(sip->sip_etag);
TEST_S(sip->sip_etag->g_string, "tagtag");
TEST_1(!e->next);
/*
Server events:
nua_i_publish
*/
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_publish);
TEST(e->data->e_status, 501);
TEST(e->data->e_status, 100);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
free_events_in_list(ctx, b->events);
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
UNPUBLISH(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, save_until_final_response, -1, respond_with_etag);
/* Client events:
nua_publish(), nua_r_publish
*/
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_unpublish);
TEST(e->data->e_status, 200);
TEST_1(!e->next);
/*
Server events:
nua_i_publish
*/
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_publish);
TEST(e->data->e_status, 100);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
free_events_in_list(ctx, b->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
if (print_headings)
printf("TEST NUA-11.3: PASSED\n");
END();
}
/* ======================================================================== */
/* Test simple methods: MESSAGE and PUBLISH */
int test_simple(struct context *ctx)
{
return
test_message(ctx)
|| test_publish(ctx)
;
}
......@@ -126,6 +126,9 @@ int test_events(struct context *ctx)
if (print_headings)
printf("TEST NUA-12.1: SUBSCRIBE without notifier\n");
nua_set_params(b->nua, SIPTAG_ALLOW_EVENTS(NULL), TAG_END());
run_b_until(ctx, nua_r_set_params, until_final_response);
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
SUBSCRIBE(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
......
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