#define BF_EXPECT_MORE 0x2000000 /* more data expected to be sent very soon (one-shoot) */
#define BF_SEND_DONTWAIT 0x4000000 /* don't wait for sending data (one-shoot) */
+#define BF_WAKE_ONCE 0x8000000 /* pretend there is activity on this buffer (one-shoot) */
+
/* Use these masks to clear the flags before going back to lower layers */
#define BF_CLEAR_READ (~(BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR|BF_READ_ATTACHED))
#define BF_CLEAR_WRITE (~(BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_WRITE_ERROR))
#define BF_CLEAR_TIMEOUT (~(BF_READ_TIMEOUT|BF_WRITE_TIMEOUT|BF_ANA_TIMEOUT))
/* Masks which define input events for stream analysers */
-#define BF_MASK_ANALYSER (BF_READ_ATTACHED|BF_READ_ACTIVITY|BF_READ_TIMEOUT|BF_ANA_TIMEOUT|BF_WRITE_ACTIVITY)
+#define BF_MASK_ANALYSER (BF_READ_ATTACHED|BF_READ_ACTIVITY|BF_READ_TIMEOUT|BF_ANA_TIMEOUT|BF_WRITE_ACTIVITY|BF_WAKE_ONCE)
/* Mask for static flags which cause analysers to be woken up when they change */
#define BF_MASK_STATIC (BF_OUT_EMPTY|BF_FULL|BF_SHUTR|BF_SHUTW|BF_SHUTR_NOW|BF_SHUTW_NOW)
req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
return 0;
}
- if (req->l <= req->size - global.tune.maxrewrite)
+ if (req->r < req->lr || req->r > req->data + req->size - global.tune.maxrewrite)
http_buffer_heavy_realign(req, msg);
}
/* don't let a connection request be initiated */
buffer_dont_connect(req);
s->rep->flags &= ~BF_EXPECT_MORE; /* speed up sending a previous response */
+ s->rep->analysers |= an_bit; /* wake us up once it changes */
return 0;
}
}
rq_prod_last = s->si[0].state;
rq_cons_last = s->si[1].state;
+ s->req->flags &= ~BF_WAKE_ONCE;
rqf_last = s->req->flags;
if ((s->req->flags ^ flags) & BF_MASK_STATIC)
s->si[1].state != rp_prod_last) {
unsigned int flags = s->rep->flags;
+ if ((s->rep->flags & BF_MASK_ANALYSER) &&
+ (s->rep->analysers & AN_REQ_WAIT_HTTP)) {
+ /* Due to HTTP pipelining, the HTTP request analyser might be waiting
+ * for some free space in the response buffer, so we might need to call
+ * it when something changes in the response buffer, but still we pass
+ * it the request buffer. Note that the SI state might very well still
+ * be zero due to us returning a flow of redirects!
+ */
+ s->rep->analysers &= ~AN_REQ_WAIT_HTTP;
+ s->req->flags |= BF_WAKE_ONCE;
+ }
+
if (s->rep->prod->state >= SI_ST_EST) {
int max_loops = global.tune.maxpollevents;
unsigned int ana_list;
if (s->req->analysers & ~req_ana_back)
goto resync_request;
+ if ((s->req->flags & ~rqf_last) & BF_MASK_ANALYSER)
+ goto resync_request;
+
/* FIXME: here we should call protocol handlers which rely on
* both buffers.
*/