Try this on for size. Looks "okay" to me, but I really have no
clue if this does what we really want. The first patch moves the
fd to the request_rec's pool. The second one implements setaside
for apr_bucket_file.
Let me explain why I implemented setaside (please verify my logic
- this is all new code to me):
The key is that http_core.c:3145 calls ap_save_brigade in our
condition, which calls setaside on all of the buckets
(util_filter.c:260). Hence, this seems proper to implement
set_aside (what about something else in the brigade that doesn't
support setaside? Oh no.).
The implemented file_read will read into a buffer (of its choosing)
and split any remaining buffers into new buckets (inserting them
after our file bucket - which would be okay in any event - since
we'll get to them in a second - in our keepalive case, it should
only be one bucket). We then call apr_bucket_heap_make to store
a copy of that buffer in the heap (must copy since orig alloc
from the request pool).
Hopefully, this is close. I dunno. =)
After trying to chase down all of this code, my mind is a puddle.
I tried my best to track the code. This seems like it does the
"right thing." If not, oh well... -- justin
Index: server/core.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/core.c,v
retrieving revision 1.9
diff -u -r1.9 core.c
--- server/core.c 2001/04/22 22:19:32 1.9
+++ server/core.c 2001/04/29 05:10:47
@@ -2965,7 +2965,7 @@
return HTTP_METHOD_NOT_ALLOWED;
}
- if ((status = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY, 0,
r->connection->pool)) != APR_SUCCESS) {
+ if ((status = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY, 0, r->pool))
+!= APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
"file permissions deny server access: %s", r->filename);
return HTTP_FORBIDDEN;
Index: buckets/apr_buckets_file.c
===================================================================
RCS file: /home/cvspublic/apr-util/buckets/apr_buckets_file.c,v
retrieving revision 1.40
diff -u -r1.40 apr_buckets_file.c
--- buckets/apr_buckets_file.c 2001/04/11 19:07:04 1.40
+++ buckets/apr_buckets_file.c 2001/04/29 05:45:58
@@ -198,11 +198,30 @@
return apr_bucket_file_make(b, fd, offset, len);
}
+static apr_status_t file_setaside(apr_bucket *b)
+{
+ char * buf;
+ apr_size_t len;
+
+ /* Read into our buffer. Notice the API mismatch. */
+ file_read(b, &buf, &len, APR_BLOCK_READ);
+
+ /* The memory of the file_read was allocated from the pool
+ * which is going away, hence we need to copy it when we
+ * make the heap. */
+ b = apr_bucket_heap_make(b, buf, len, 1, NULL);
+
+ if (b == NULL)
+ return APR_ENOMEM;
+
+ return APR_SUCCESS;
+}
+
APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_file = {
"FILE", 5,
file_destroy,
file_read,
- apr_bucket_setaside_notimpl,
+ file_setaside,
apr_bucket_shared_split,
apr_bucket_shared_copy
};