Hi all,

We didn't have time to discuss blob serving at the IRC meet last night,
so I'll do it via the list.

I think that Midgard should be able to serve files other than HTML so
we can use the content management and upcoming AC for things like
movies,
images, sounds, file attachments, etc too.

I see 2 options: serve the blobs from the database or from the
filesystem.

Serving blobs from the filesystem is easy and can be done entirely by
mod_midgard; you'll find a sample implementation attached which handles
blobs attached to page records. This is not meant to be production
code *at all* (and addresses only serving, not management), just an
example. This approach has the added benefit of having Apache handle
the mime determination for us.

Serving page blobs from the database can be handled by mod_midgard too,
but
I suspect that it would get very memory consuming. AFAICT you would 
retrieve the file contents by an SQL query into memory and then serve
it out to the client. I hope there's another way of doing this, but even
if you can flush blobs directly to a temporary file (and then handling
it as above) this is going to be a strain on the server (file creation
and deletion is expensive). Imagine what would happen if the monster
package gets popular :<. And there's the point of field size
limitataions,
too.

All this would lead to the straight FS approach being the obvious
choice,
save for one thing: access control. If your PHP setup allows access to
the filesystem (which is the default) users will be able to read the
files
(which would probably be gathered in a single directory) directly, if
they
know the name and location. Names would be random (and not related to
the
"name" in the url), and not visible to the user, but still. And if your
PHP setup allows the running of shell commands (again, the default)
and the user knows the location of the blob directory, a listing
of those random names is easily produced.

There is also the issue of how to serve blobs that are not attached to
page records. These could be served from a 'magic' url
(/attachment/table/id/filename, or just /attachment/blobid/filename),
but
I don't really like the concept of 'magic' parts of the URL space. They
can be served by active pages too, using the PHP 'readfile' command,
but this requires FS access again, and disclosure of the random name.

Am I makeing too much of a point of this? I want use Midgard for a
intranet
site that has parts of it available only for specific groups (management
for example) and there may be documents stored on the server that
require
confidentiality.

Last (but least, I think), serveing blobs from the FS iso the DB puts
them outside the current packaging proposal.

Bye,
Emile "AU,IWAI" Heyns

#
# Table structure for table 'blob'
#
DROP TABLE IF EXISTS blobs;
CREATE TABLE blobs (
  id smallint(5) unsigned DEFAULT '0' NOT NULL auto_increment,
  tbl varchar(255) DEFAULT '' NOT NULL,
  parent smallint(5) DEFAULT '0' NOT NULL,
  mimetype varchar(255) DEFAULT '' NOT NULL,
  name varchar(255) DEFAULT '' NOT NULL,
  location varchar(255) DEFAULT '' NOT NULL,
  size int(10) unsigned DEFAULT '0' NOT NULL,
  md5 varchar(255) DEFAULT '' NOT NULL,
  PRIMARY KEY (id)
);

--- mod_midgard-1.2.5/mod_midgard.c,bak Tue Nov  9 22:14:06 1999
+++ mod_midgard-1.2.5/mod_midgard.c     Fri Nov 26 10:17:16 1999
@@ -71,7 +71,7 @@
        pool        *pool;
        midgard     *mgd;
 
-       int host, style, page;
+       int host, style, page, blob;
        int auth, prelen, author;
        const char *title, *content;
        const char *type;       
@@ -336,6 +336,7 @@
        rcfg->host   = 0;
        rcfg->style  = 0;
        rcfg->page   = 0;
+       rcfg->blob   = 0;
        rcfg->auth   = 0;
        rcfg->prelen = 0;
        rcfg->type   = "text/html";
@@ -421,11 +422,43 @@
        mgd_release(res);
 }
 
+static int midgard_serve_page_blob(midgard_request_config *rcfg)
+{
+char* mimetype;
+
+       if (!mgd_access(rcfg->mgd->user, "blobs", rcfg->blob, MGD_ACL_READ))
+       {
+               return DECLINED;
+       }
+
+       res = mgd_select(rcfg->mgd, "mimetype,location", "blobs",
+                        "id=$d", NULL, rcfg->blob);
+       if (!res || !mgd_fetch(res)) {
+               if (res) mgd_release(res);
+               ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s,
+                    "Midgard: cannot retrieve page blob %d", rfcg->blob);
+               return DECLINED;
+       }
+
+       mimetype = mgd_colvalue(res, 0));
+       if (mimetype && *mimetype) {
+               r->content_type = ap_pstrdup(rcfg->pool, mimetype);
+       }
+       rcfg->filename = ap_pstrdup(rcfg->pool, mgd_colvalue(res, 1));
+
+       mgd_release(res);
+
+       return OK;
+}
+
 static void midgard_page_walk(midgard_request_config *rcfg)
 {
        midgard_res *res;
        char *uri, *tok, *part, **arg;
        int tmp, active = 0, addslash;
+
+       rcfg->page = 0;
+       rcfg->blob = 0;
  
        part = strrchr(rcfg->req->uri + rcfg->prelen, '.');
        if (part && strcmp(part, ".html") == 0) {
@@ -457,6 +490,19 @@
                        if (res)
                                mgd_release(res);
                        if (!active) {
+
+                               /* search for blobs */
+                               res = mgd_select(rcfg->mgd, "id", "blobs",
+                                       "tbl='page' AND parent=$d AND name=$q", NULL,
+                                       rcfg->page, tok);
+
+                               if (res && mgd_fetch(res)) {
+                                       rcfg->blob  = atoi(mgd_colvalue(res, 0));
+                               }
+
+                               if (res)
+                                       mgd_release(res);
+
                                rcfg->page = 0;
                                return;
                        }
@@ -563,9 +609,13 @@
        /* Directory walk */
        midgard_page_walk(rcfg);
        if (!rcfg->page) {
-               ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
+               if (!rcfg->blob)
+                       return midgard_serve_page_blob(rcfg);
+               else {
+                       ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
                              "Midgard: page record for %s not found", r->uri);
-               return DECLINED;
+                       return DECLINED;
+               }
        } else if (rcfg->page == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
                              "Midgard: adding trailing slash to %s", r->uri);

--
This is The Midgard Project's mailing list. For more information,
please visit the project's web site at http://www.midgard-project.org

To unsubscribe the list, send an empty email message to address
[EMAIL PROTECTED]

Reply via email to