commit c665b7d92648d5b839d40b198610aa05d11cceb8
parent 10284d59b6ee5f48e496135839677a854ded024a
Author: Joris Vink <joris@coders.se>
Date:   Sun, 10 Aug 2014 18:46:44 +0200
Add a callback to http_response_stream().
This way we can get our code called whenever a stream is
completed. This cb handler does stand alone from an http_request
and is passed a netbuf data structure.
Diffstat:
5 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -201,8 +201,8 @@ char		*http_post_data_text(struct http_request *);
 void		http_process_request(struct http_request *, int);
 u_int8_t	*http_post_data_bytes(struct http_request *, u_int32_t *);
 void		http_response(struct http_request *, int, void *, u_int32_t);
-void		http_response_stream(struct http_request *, int,
-		    void *, u_int64_t);
+void		http_response_stream(struct http_request *, int, void *,
+		    u_int64_t, int (*cb)(struct netbuf *), void *);
 int		http_request_header(struct http_request *,
 		    const char *, char **);
 void		http_response_header(struct http_request *,
diff --git a/includes/kore.h b/includes/kore.h
@@ -456,14 +456,15 @@ int		net_send(struct connection *);
 int		net_send_flush(struct connection *);
 int		net_recv_flush(struct connection *);
 void		net_remove_netbuf(struct netbuf_head *, struct netbuf *);
-void		net_recv_queue(struct connection *, size_t, int,
+void		net_recv_queue(struct connection *, u_int32_t, int,
 		    struct netbuf **, int (*cb)(struct netbuf *));
-int		net_recv_expand(struct connection *c, struct netbuf *, size_t,
-		    int (*cb)(struct netbuf *));
+int		net_recv_expand(struct connection *c, struct netbuf *,
+		    u_int32_t, int (*cb)(struct netbuf *));
 void		net_send_queue(struct connection *, void *,
 		    u_int32_t, struct spdy_stream *, int);
 void		net_send_stream(struct connection *, void *,
-		    u_int32_t, struct spdy_stream *);
+		    u_int32_t, struct spdy_stream *,
+		    int (*cb)(struct netbuf *), struct netbuf **);
 
 void		kore_buf_free(struct kore_buf *);
 struct kore_buf	*kore_buf_create(u_int32_t);
diff --git a/src/connection.c b/src/connection.c
@@ -276,8 +276,11 @@ kore_connection_remove(struct connection *c)
 	for (nb = TAILQ_FIRST(&(c->send_queue)); nb != NULL; nb = next) {
 		next = TAILQ_NEXT(nb, list);
 		TAILQ_REMOVE(&(c->send_queue), nb, list);
-		if (!(nb->flags & NETBUF_IS_STREAM))
+		if (!(nb->flags & NETBUF_IS_STREAM)) {
 			kore_mem_free(nb->buf);
+		} else if (nb->cb != NULL) {
+			(void)nb->cb(nb);
+		}
 		kore_pool_put(&nb_pool, nb);
 	}
 
diff --git a/src/http.c b/src/http.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ * Copyright (c) 2013-2014 Joris Vink <joris@coders.se>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -394,8 +394,10 @@ http_response(struct http_request *req, int status, void *d, u_int32_t l)
 
 void
 http_response_stream(struct http_request *req, int status, void *base,
-    u_int64_t len)
+    u_int64_t len, int (*cb)(struct netbuf *), void *arg)
 {
+	struct netbuf		*nb;
+
 	req->status = status;
 
 	switch (req->owner->proto) {
@@ -408,7 +410,8 @@ http_response_stream(struct http_request *req, int status, void *base,
 		break;
 	}
 
-	net_send_stream(req->owner, base, len, req->stream);
+	net_send_stream(req->owner, base, len, req->stream, cb, &nb);
+	nb->extra = arg;
 }
 
 int
diff --git a/src/net.c b/src/net.c
@@ -86,14 +86,14 @@ net_send_queue(struct connection *c, void *data, u_int32_t len,
 
 void
 net_send_stream(struct connection *c, void *data, u_int32_t len,
-    struct spdy_stream *s)
+    struct spdy_stream *s, int (*cb)(struct netbuf *), struct netbuf **out)
 {
 	struct netbuf		*nb;
 
 	kore_debug("net_send_stream(%p, %p, %d, %p)", c, data, len, s);
 
 	nb = kore_pool_get(&nb_pool);
-	nb->cb = NULL;
+	nb->cb = cb;
 	nb->owner = c;
 	nb->s_off = 0;
 	nb->buf = data;
@@ -104,10 +104,12 @@ net_send_stream(struct connection *c, void *data, u_int32_t len,
 	nb->flags  = NETBUF_IS_STREAM;
 
 	TAILQ_INSERT_TAIL(&(c->send_queue), nb, list);
+	if (out != NULL)
+		*out = nb;
 }
 
 void
-net_recv_queue(struct connection *c, size_t len, int flags,
+net_recv_queue(struct connection *c, u_int32_t len, int flags,
     struct netbuf **out, int (*cb)(struct netbuf *))
 {
 	struct netbuf		*nb;
@@ -129,7 +131,7 @@ net_recv_queue(struct connection *c, size_t len, int flags,
 }
 
 int
-net_recv_expand(struct connection *c, struct netbuf *nb, size_t len,
+net_recv_expand(struct connection *c, struct netbuf *nb, u_int32_t len,
     int (*cb)(struct netbuf *))
 {
 	if (nb->type != NETBUF_RECV) {
@@ -328,8 +330,11 @@ net_remove_netbuf(struct netbuf_head *list, struct netbuf *nb)
 		return;
 	}
 
-	if (!(nb->flags & NETBUF_IS_STREAM))
+	if (!(nb->flags & NETBUF_IS_STREAM)) {
 		kore_mem_free(nb->buf);
+	} else if (nb->cb != NULL) {
+		(void)nb->cb(nb);
+	}
 
 	TAILQ_REMOVE(list, nb, list);
 	kore_pool_put(&nb_pool, nb);