[MEDIUM] http: automatically re-aling request buffer
When parsing a request that does not start at the beginning of the
buffer, we may experience a buffer full issue. In order to avoid
this, we try to realign the buffer if it is not really full. That
will be required when we have to deal with pipelined requests.
diff --git a/src/proto_http.c b/src/proto_http.c
index 7c722e6..3a93360 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1890,6 +1890,7 @@
/* we're speaking HTTP here, so let's speak HTTP to the client */
s->srv_error = http_return_srv_error;
+ http_parse_again:
if (likely(req->lr < req->r))
http_msg_analyzer(req, msg, &txn->hdr_idx);
@@ -1937,6 +1938,58 @@
* must terminate it now.
*/
if (unlikely(req->flags & BF_FULL)) {
+ /* It is possible the analyser has stopped because of
+ * lack of space at the end of the buffer, while the
+ * beginning is free (skipped blanks or previous
+ * requests vanished). In this case, we try to re-aling
+ * the buffer, and update the few relevant pointers.
+ * Since we're copying via the trash, it's important that
+ * it is always as large as a buffer.
+ */
+ if (req->l < buffer_max_len(req)) {
+ /* let's move what remains */
+ int max, done;
+ unsigned offset = req->w - req->data;
+
+ done = 0;
+ while (done < req->l) {
+ if (req->r > req->w)
+ max = req->r - req->w;
+ else
+ max = req->data + req->size - req->w;
+ memcpy(trash + done, req->w, max);
+ done += max;
+ req->w += max;
+ if (req->w >= req->data + req->size)
+ req->w -= req->size;
+ }
+ if (done)
+ memcpy(req->data, trash, done);
+ msg->eoh = msg->som = 0;
+
+ /* move all known pointers */
+ req->w = req->data;
+ req->lr -= offset; if (req->lr < req->data) req->lr += req->size;
+ req->r -= offset; if (req->r < req->data) req->r += req->size;
+ msg->sol -= offset; if (msg->sol < req->data) msg->sol += req->size;
+ msg->eol -= offset; if (msg->eol < req->data) msg->eol += req->size;
+
+ /* adjust relative pointers */
+ msg->col += req->size - offset; if (msg->col >= req->size) msg->col -= req->size;
+ msg->sov += req->size - offset; if (msg->sov >= req->size) msg->sov -= req->size;
+ msg->sl.rq.u += req->size - offset; if (msg->sl.rq.u >= req->size) msg->sl.rq.u -= req->size;
+ msg->sl.rq.v += req->size - offset; if (msg->sl.rq.v >= req->size) msg->sl.rq.v -= req->size;
+
+ if (msg->err_pos >= 0) {
+ msg->err_pos += req->size - offset;
+ if (msg->err_pos >= req->size)
+ msg->err_pos -= req->size;
+ }
+
+ req->flags &= ~BF_FULL;
+ goto http_parse_again;
+ }
+
/* FIXME: check if URI is set and return Status
* 414 Request URI too long instead.
*/