]> granicus.if.org Git - apache/commitdiff
* modules/ssl/ssl_engine_io.c (ssl_io_input_getline): Document
authorJoe Orton <jorton@apache.org>
Wed, 6 Aug 2008 14:45:48 +0000 (14:45 +0000)
committerJoe Orton <jorton@apache.org>
Wed, 6 Aug 2008 14:45:48 +0000 (14:45 +0000)
  interface.
  (ssl_io_filter_input): For GETLINE mode, pull lines directly from
  the char_buffer if possible, to avoid unnecessarily copying the
  entire buffer once per invocation.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@683283 13f79535-47bb-0310-9956-ffa450edef68

modules/ssl/ssl_engine_io.c

index 2554edddca288bb8bf2fa301aea4076c69081b44..befc53ad07101ac9cb2fe45768f7c3b80c45d8bb 100644 (file)
@@ -714,6 +714,9 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
     return inctx->rc;
 }
 
+/* Read a line of input from the SSL input layer into buffer BUF of
+ * length *LEN; updating *len to reflect the length of the line
+ * including the LF character. */
 static apr_status_t ssl_io_input_getline(bio_filter_in_ctx_t *inctx,
                                          char *buf,
                                          apr_size_t *len)
@@ -1204,8 +1207,8 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
 {
     apr_status_t status;
     bio_filter_in_ctx_t *inctx = f->ctx;
-
-    apr_size_t len = sizeof(inctx->buffer);
+    const char *start = inctx->buffer; /* start of block to return */
+    apr_size_t len = sizeof(inctx->buffer); /* length of block to return */
     int is_init = (mode == AP_MODE_INIT);
 
     if (f->c->aborted) {
@@ -1257,7 +1260,25 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
         status = ssl_io_input_read(inctx, inctx->buffer, &len);
     }
     else if (inctx->mode == AP_MODE_GETLINE) {
-        status = ssl_io_input_getline(inctx, inctx->buffer, &len);
+        const char *pos;
+
+        /* Satisfy the read directly out of the buffer if possible;
+         * invoking ssl_io_input_getline will mean the entire buffer
+         * is copied once (unnecessarily) for each GETLINE call. */
+        if (inctx->cbuf.length 
+            && (pos = memchr(inctx->cbuf.value, APR_ASCII_LF, 
+                             inctx->cbuf.length)) != NULL) {
+            start = inctx->cbuf.value;
+            len = 1 + pos - start; /* +1 to include LF */
+            /* Buffer contents now consumed. */
+            inctx->cbuf.value += len;
+            inctx->cbuf.length -= len;
+            status = APR_SUCCESS;
+        }
+        else {
+            /* Otherwise fall back to the hard way. */
+            status = ssl_io_input_getline(inctx, inctx->buffer, &len);
+        }
     }
     else {
         /* We have no idea what you are talking about, so return an error. */
@@ -1271,7 +1292,7 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
     /* Create a transient bucket out of the decrypted data. */
     if (len > 0) {
         apr_bucket *bucket =
-            apr_bucket_transient_create(inctx->buffer, len, f->c->bucket_alloc);
+            apr_bucket_transient_create(start, len, f->c->bucket_alloc);
         APR_BRIGADE_INSERT_TAIL(bb, bucket);
     }