[svn:mod_parrot] r481 - in mod_parrot/trunk: . lib lib/ModParrot/Apache src

[email protected] Fri, 7 Nov 2008 08:54:38 -0800 (PST)
Newsgroups perl.cvs.mod_parrot
Message-ID <[email protected]>
Author: jhorwitz
Date: Fri Nov  7 08:54:37 2008
New Revision: 481

Added:
   mod_parrot/trunk/src/modparrot_io.c
Modified:
   mod_parrot/trunk/Makefile.in
   mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir
   mod_parrot/trunk/lib/mod_parrot.pir
   mod_parrot/trunk/src/nci.c

Log:
implement read() method for ModParrot;Apache;RequestRec


Modified: mod_parrot/trunk/Makefile.in
==============================================================================
--- mod_parrot/trunk/Makefile.in	(original)
+++ mod_parrot/trunk/Makefile.in	Fri Nov  7 08:54:37 2008
@@ -29,6 +29,7 @@
 	$(SRC_DIR)/modparrot_config.c \
 	$(SRC_DIR)/nci.c \
 	$(SRC_DIR)/context.c \
+	$(SRC_DIR)/modparrot_io.c \
 	$(SRC_DIR)/module.c
 
 OBJ_FILES= \
@@ -37,6 +38,7 @@
 	$(SRC_DIR)/modparrot_config.lo \
 	$(SRC_DIR)/nci.lo \
 	$(SRC_DIR)/context.lo \
+        $(SRC_DIR)/modparrot_io.lo \
 	$(SRC_DIR)/module.lo
 
 MPLIBS=	lib/ModParrot/Apache/RequestRec \

Modified: mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir
==============================================================================
--- mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir	(original)
+++ mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir	Fri Nov  7 08:54:37 2008
@@ -135,6 +135,30 @@
     ap_rputc( data, r )
 .end
 
+=item C<INT read(PMC buf, INT len)>
+
+=over 4
+
+Reads len bytes of data from the HTTP stream into a PMC.  Returns the number
+of bytes read.
+
+=back
+
+=cut
+
+.sub read :method
+    .param pmc buf
+    .param int len
+    .local pmc r
+    .local pmc request_read
+    .local int bytes
+
+    getattribute r, self, 'r'
+    request_read = get_root_global [ 'ModParrot'; 'NCI' ], 'request_read'
+    bytes = request_read( buf, len, r )
+    .return(bytes)
+.end
+
 =item C<INT write(pmc, size)>
 
 =over 4

Modified: mod_parrot/trunk/lib/mod_parrot.pir
==============================================================================
--- mod_parrot/trunk/lib/mod_parrot.pir	(original)
+++ mod_parrot/trunk/lib/mod_parrot.pir	Fri Nov  7 08:54:37 2008
@@ -81,6 +81,9 @@
     dlfunc func, nul, "mpnci_csd", "pJ"
     set_root_global [ 'ModParrot'; 'NCI' ], "csd", func
 
+    dlfunc func, nul, "mpnci_request_read", "iJPip"
+    set_root_global [ 'ModParrot'; 'NCI' ], "request_read", func
+
     # load required libraries
     load_bytecode 'Protoobject.pbc'
     load_bytecode 'ModParrot/Interpreter.pbc'

Added: mod_parrot/trunk/src/modparrot_io.c
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/src/modparrot_io.c	Fri Nov  7 08:54:37 2008
@@ -0,0 +1,105 @@
+/* $Id$ */
+
+/* Copyright (c) 2008 Jeff Horwitz
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+
+#include "apr_strings.h"
+
+#include "httpd.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_config.h"
+#include "http_request.h"
+#include "http_core.h"
+#include "http_connection.h"
+#include "http_main.h"
+
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+#include "parrot/extend.h"
+
+#include "mod_parrot.h"
+#include "modparrot_config.h"
+#include "modparrot_log.h"
+
+/* stolen and adapted from mod_perl2's modperl_request_read */
+apr_size_t modparrot_request_read(request_rec *r, char *buffer, apr_size_t len)
+{
+    apr_size_t total = 0;
+    apr_size_t wanted = len;
+    int seen_eos = 0;
+    char *tmp = buffer;
+    apr_bucket_brigade *bb;
+
+    if (len <= 0) {
+        return 0;
+    }
+
+    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+    if (bb == NULL) {
+        r->connection->keepalive = AP_CONN_CLOSE;
+        MPLOG_ERROR(r->server, "modparrot_request_read: "
+                               "failed to create bucket brigade");
+        return 0 ;
+    }
+
+    do {
+        apr_size_t read;
+        apr_status_t rc;
+
+        rc = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                            APR_BLOCK_READ, len);
+        if (rc != APR_SUCCESS) {
+            r->connection->keepalive = AP_CONN_CLOSE;
+            apr_brigade_destroy(bb);
+            MPLOG_ERROR(r->server, "modparrot_request_read: "
+                                   "failed to get bucket brigade");
+        }
+
+        if (APR_BRIGADE_EMPTY(bb)) {
+            apr_brigade_destroy(bb);
+            MPLOG_ERROR(r->server, "modparrot_request_read: "
+                       "Aborting read from client. "
+                       "One of the input filters is broken. "
+                       "It returned an empty bucket brigade for "
+                       "the APR_BLOCK_READ mode request");
+        }
+
+        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
+            seen_eos = 1;
+        }
+
+        read = len;
+        rc = apr_brigade_flatten(bb, tmp, &read);
+        if (rc != APR_SUCCESS) {
+            apr_brigade_destroy(bb);
+            MPLOG_ERROR(r->server, "modparrot_request_read: "
+                                   "apr_brigade_flatten failed");
+        }
+
+        total += read;
+        tmp   += read;
+        len   -= read;
+
+        apr_brigade_cleanup(bb);
+
+    } while (len > 0 && !seen_eos);
+
+    apr_brigade_destroy(bb);
+
+    return total;
+}

Modified: mod_parrot/trunk/src/nci.c
==============================================================================
--- mod_parrot/trunk/src/nci.c	(original)
+++ mod_parrot/trunk/src/nci.c	Fri Nov  7 08:54:37 2008
@@ -176,6 +176,26 @@
     return(bytes);
 }
 
+size_t mpnci_request_read(Parrot_Interp interp, Parrot_PMC pbuf, size_t len,
+    request_rec *r)
+{
+    modparrot_context *ctxp;
+    Parrot_Interp interpreter;
+    char *buf;
+    int bytes;
+
+    ctxp = get_interp_ctx(interp);
+    if (!ctxp) return 0;
+    interpreter = ctxp->interp;
+
+    /* buf should be freed by apache when the request pool is destroyed */
+    buf = apr_pcalloc(r->pool, len);
+    bytes = modparrot_request_read(r, buf, len);
+    Parrot_PMC_set_cstringn(interp, pbuf, buf, bytes);
+
+    return(bytes);
+}
+
 char *mpnci_backtrace(Parrot_Interp interp)
 {
     return (char *)modparrot_backtrace(interp);