summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2008-02-08 14:47:40 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2008-02-08 14:47:40 +0000
commit395ff40c214c0f9de46833d0319d4d9393dfbd41 (patch)
tree615120031481f925a7c131b521a8aee0514426b6 /src
parent3aaa5ccd6d2d6853c085f6ec405744aca205e261 (diff)
downloadneon-395ff40c214c0f9de46833d0319d4d9393dfbd41.tar.gz
Add a close-connection hook (thanks to Robert J. van der Boon):
* src/ne_private.h (struct ne_session_s): Add close_conn_hooks. * src/ne_session.c (ne_hook_close_conn, ne_unhook_close_conn): New functions. (ne_close_connection): Run close_conn hooks. * src/ne_request.h (ne_hook_close_conn, ne_unhook_close_conn): New prototypes. * test/request.c (hook_close_conn, hooks): Add tests. git-svn-id: http://svn.webdav.org/repos/projects/neon/trunk@1344 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
Diffstat (limited to 'src')
-rw-r--r--src/ne_private.h3
-rw-r--r--src/ne_request.h11
-rw-r--r--src/ne_session.c32
3 files changed, 38 insertions, 8 deletions
diff --git a/src/ne_private.h b/src/ne_private.h
index 69b4b35..5124cea 100644
--- a/src/ne_private.h
+++ b/src/ne_private.h
@@ -90,7 +90,8 @@ struct ne_session_s {
int rdtimeout, cotimeout; /* read, connect timeouts. */
struct hook *create_req_hooks, *pre_send_hooks, *post_send_hooks,
- *post_headers_hooks, *destroy_req_hooks, *destroy_sess_hooks, *private;
+ *post_headers_hooks, *destroy_req_hooks, *destroy_sess_hooks,
+ *close_conn_hooks, *private;
char *user_agent; /* full User-Agent: header field */
diff --git a/src/ne_request.h b/src/ne_request.h
index b057869..bfe5cdc 100644
--- a/src/ne_request.h
+++ b/src/ne_request.h
@@ -1,6 +1,6 @@
/*
HTTP Request Handling
- Copyright (C) 1999-2006, Joe Orton <joe@manyfish.co.uk>
+ Copyright (C) 1999-2006, 2008, Joe Orton <joe@manyfish.co.uk>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -278,10 +278,15 @@ void ne_hook_destroy_request(ne_session *sess,
ne_destroy_req_fn fn, void *userdata);
typedef void (*ne_destroy_sess_fn)(void *userdata);
-/* Hook called when the session is destroyed. */
+/* Hook called when the session is about to be destroyed. */
void ne_hook_destroy_session(ne_session *sess,
ne_destroy_sess_fn fn, void *userdata);
+typedef void (*ne_close_conn_fn)(void *userdata);
+/* Hook called when the connection is closed; note that this hook
+ * may be called *AFTER* the destroy_session hook. */
+void ne_hook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata);
+
/* The ne_unhook_* functions remove a hook registered with the given
* session. If a hook is found which was registered with a given
* function 'fn', and userdata pointer 'userdata', then it will be
@@ -298,6 +303,8 @@ void ne_unhook_destroy_request(ne_session *sess,
ne_destroy_req_fn fn, void *userdata);
void ne_unhook_destroy_session(ne_session *sess,
ne_destroy_sess_fn fn, void *userdata);
+void ne_unhook_close_conn(ne_session *sess,
+ ne_close_conn_fn fn, void *userdata);
/* Store an opaque context for the request, 'priv' is returned by a
* call to ne_request_get_private with the same ID. */
diff --git a/src/ne_session.c b/src/ne_session.c
index b0bf31a..cd3949c 100644
--- a/src/ne_session.c
+++ b/src/ne_session.c
@@ -58,7 +58,7 @@ void ne_session_destroy(ne_session *sess)
{
struct hook *hk;
- NE_DEBUG(NE_DBG_HTTP, "ne_session_destroy called.\n");
+ NE_DEBUG(NE_DBG_HTTP, "sess: Destroying session.\n");
/* Run the destroy hooks. */
for (hk = sess->destroy_sess_hooks; hk != NULL; hk = hk->next) {
@@ -69,7 +69,7 @@ void ne_session_destroy(ne_session *sess)
/* Close the connection; note that the notifier callback could
* still be invoked here. */
if (sess->connected) {
- ne_close_connection(sess);
+ ne_close_connection(sess);
}
destroy_hooks(sess->create_req_hooks);
@@ -289,18 +289,28 @@ const char *ne_get_error(ne_session *sess)
void ne_close_connection(ne_session *sess)
{
if (sess->connected) {
+ struct hook *hk;
+
+ NE_DEBUG(NE_DBG_SOCKET, "sess: Closing connection.\n");
+
if (sess->notify_cb) {
sess->status.cd.hostname =
sess->use_proxy ? sess->proxy.hostname : sess->server.hostname;
sess->notify_cb(sess->notify_ud, ne_status_disconnected,
&sess->status);
}
- NE_DEBUG(NE_DBG_SOCKET, "Closing connection.\n");
+
+ /* Run the close_conn hooks. */
+ for (hk = sess->close_conn_hooks; hk != NULL; hk = hk->next) {
+ ne_close_conn_fn fn = (ne_close_conn_fn)hk->fn;
+ fn(hk->userdata);
+ }
+
ne_sock_close(sess->socket);
sess->socket = NULL;
- NE_DEBUG(NE_DBG_SOCKET, "Connection closed.\n");
+ NE_DEBUG(NE_DBG_SOCKET, "sess: Connection closed.\n");
} else {
- NE_DEBUG(NE_DBG_SOCKET, "(Not closing closed connection!).\n");
+ NE_DEBUG(NE_DBG_SOCKET, "sess: Not closing closed connection.\n");
}
sess->connected = 0;
}
@@ -442,6 +452,12 @@ void ne_hook_destroy_session(ne_session *sess,
ADD_HOOK(sess->destroy_sess_hooks, fn, userdata);
}
+void ne_hook_close_conn(ne_session *sess,
+ ne_close_conn_fn fn, void *userdata)
+{
+ ADD_HOOK(sess->close_conn_hooks, fn, userdata);
+}
+
void ne_set_session_private(ne_session *sess, const char *id, void *userdata)
{
add_hook(&sess->private, id, NULL, userdata);
@@ -497,3 +513,9 @@ void ne_unhook_destroy_session(ne_session *sess,
{
REMOVE_HOOK(sess->destroy_sess_hooks, fn, userdata);
}
+
+void ne_unhook_close_conn(ne_session *sess,
+ ne_close_conn_fn fn, void *userdata)
+{
+ REMOVE_HOOK(sess->close_conn_hooks, fn, userdata);
+}