httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Drew Bertola <d...@jupiterhosting.com>
Subject Re: splitting a string...
Date Mon, 01 Jan 2007 09:48:19 GMT
Thanks for all the ideas.   They've come in very handy.  I haven't done
extensive testing, and the module is still too stupid to read
configuration data, but I've gotten much farther.

Right now, static html works fine, but php pages (need both per customer
requirements) spit out too much at the tail end.  I'll post my code
below for review, as well as a snippet of the php page code as
delivered.  The problem is much worse when the pages are very large, so
the example php code uses a loop to print a comment 1000 times.  I
suspect I'm filling the brigade or a bucket to full, or not doing
something to tell it where the end is.

Please send me any and all feedback that may help (stupid mistakes or
items I've overlooked most of all).

Here's my php test code:

<?php

echo "<html>\n";
echo "<head>\n";

echo "<!-- ";

for ( $i = 0; $i < 1000; $i++ )
  {
    echo "nothing just filling up space,\n";
  }

echo "-->\n";
echo "<title>PHP Test Page</title>\n";
echo "</head>\n";
echo "<body>\n";
echo "Now, I say goodbye at " . date("m/d/Y") . "\n";
echo "</body>\n";
echo "</html>\n";

Here's what php code looks like when delivered:

<html>
<head>
<meta yadayada sadssssssssssssssssssss />

<!-- nothing just filling up space,
nothing just filling up space,

[snip ~1000 lines the same]

nothing just filling up space,
-->
<title>PHP Test Page</title>
</head>
<body>
Now, I say goodbye at 01/01/2007
</body>
</html>                      <---- looks good to here, but then...
ng just filling up space,
nothing just filling up space,

[snip ~1000 lines the same]

nothing just filling up space,
-->
<title>PHP Test Page</title>
</head>
<body>

Now, I say goodbye at 01/01/2007
</body>
</html>




And here's the module:

#define DEBUG 1

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_request.h"
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_buckets.h"
#include "util_filter.h"
#include <string.h>

module AP_MODULE_DECLARE_DATA lt_insert_module;

typedef struct lt_insert_t {
  apr_bucket_brigade *bb;
} lt_insert_struct;

static int lt_insert_filter(ap_filter_t *f,
                            apr_bucket_brigade *bb)
{
  lt_insert_struct *ctx = f->ctx;
  apr_bucket *e;
 
  if ( ! ctx )
    {
      f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
      ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    }

  for( e = APR_BRIGADE_FIRST(bb);
       e != APR_BRIGADE_SENTINEL(bb);
       e = APR_BUCKET_NEXT(e) )
    {
      if ( APR_BUCKET_IS_EOS(e) || APR_BUCKET_IS_FLUSH(e) )
        {
          APR_BUCKET_REMOVE(e);
          APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
          ap_pass_brigade(f->next, ctx->bb);
          return APR_SUCCESS;
        }

      apr_size_t len;
      const char *str;
      const char *search_tag = "<head>";
      const char *insert_line = "<meta yadayada sadssssssssssssssssssss
/>\n";
      char *position = NULL;
      char *tail = NULL;
      int i = 0;
      int insert_done = 0;

      apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);

      if ( ( ( position = strcasestr(str, search_tag) ) == NULL ) ||
           ( insert_done ) )
        {
          /*
           * If we didn't find the <head> tag, just pass along
           * everything to the next filter and we're done.
           */
          i = 0;

          while ( i < len )
            {
              ap_fputc(f->next, ctx->bb, str[i++]);
            }
        }
      else
        {
          /*
           * so, we have a <head> tag.  So, lets find and process it
           * and insert our notice.
           */
          tail = position + strlen(search_tag);

          i = 0;

          while ( (str + i) < ( position + strlen(search_tag) ) )
            {
              ap_fputc(f->next, ctx->bb, str[i++]);
            }

          ap_fputs(f->next, ctx->bb, "\n");
          ap_fputs(f->next, ctx->bb, insert_line);

          while ( i < len )
            {
              ap_fputc(f->next, ctx->bb, str[i++]);
            }
         
          insert_done = 1;
        }
    }

  return APR_SUCCESS;   
}

static void register_hooks(apr_pool_t *p)
{
  ap_register_output_filter("LT_INSERT",
                            lt_insert_filter,
                            NULL,
                            AP_FTYPE_CONTENT_SET);
}

module AP_MODULE_DECLARE_DATA lt_insert_module =
  {
    STANDARD20_MODULE_STUFF,
    NULL,                    /* create per-directory config structure */
    NULL,                    /* merge per-directory config structures */
    NULL,                    /* create per-server config structure    */
    NULL,                    /* merge per-server config structures    */
    NULL,                    /* command apr_table_t                   */
    register_hooks           /* register hooks                        */
  };

----------------------------------------------------------------

--
Drew



Mime
View raw message