(no subject)

From: Yee Man Chan <ymc@dont-contact.us>
Date: Mon, 27 Sep 1999 20:35:41 -0400

Hi,

I was trying to do that popup window thing. So I wrote the following module
and I inserted a call to popup() inside fwdComplete just before
storeComplete(e).
I get the strange assertion error at assert(mem == e->mem_obj) inside popup()

Yee Man

#include "squid.h"

static char * stristr(const char *, const char *);
static char * strichr(const char *, int);
static int imatch(const char, const char);
static char * popupCombineDataBuf(MemObject *);
static char * popupProcessHTML(char *, int, int);
static void popupSplitDataBuf(MemObject *, char *);

#define ONLOAD " OnLoad=\"openWindow()\""
#define ONLOADURL "http://www.yahoo.com"

void
popup(StoreEntry * e)
{
  char * html; /* string of HTML doc to be processed */
  MemObject * mem = e->mem_obj;

  assert(mem != NULL);
  assert(mem->reply != NULL);
  /* we don't process non-HTML replies and objects that is not entirely in
     the memory */
  if (mem->inmem_lo != 0 || strCmp(mem->reply->content_type, "text/html"))
    return;
  html = popupCombineDataBuf(mem);
  if (stristr(html, ONLOAD) == NULL) {
    html = popupProcessHTML(html, 640, 480);
    assert(mem == e->mem_obj);
    mem->inmem_hi = strlen(html);
  }
  popupSplitDataBuf(mem, html);
}

/*
  Given a MemObject. Combine the fragmented data buffer linked list to a
  single NULL-terminated string.
*/
static char *
popupCombineDataBuf(MemObject * mem)
{
  mem_node * temp = mem->data_hdr.head;
  int totalBufSize = 0;
  char * ret = NULL; /* the combined buf string to be returned */
  void * tmp = ret;

  while (temp) {
    totalBufSize += temp->len;
    temp = temp->next;
  }
  
  ret = (char *) xmalloc((totalBufSize+1)*sizeof(char));
  ret[totalBufSize] = '\0';
  tmp = ret;
  /* this while loop really combines the buffers into one NULL-terminated
     string. It also free the linked list and set mem->data_hdr.head to NULL */
  while (mem->data_hdr.head) {
    xmemcpy((void *) tmp, (void *) mem->data_hdr.head->data, mem->
data_hdr.head->len*sizeof(char));
    tmp += mem->data_hdr.head->len;
    temp = mem->data_hdr.head->next;
    safe_free(mem->data_hdr.head);
    mem->data_hdr.head = temp;
  }
  mem->data_hdr.tail = NULL;
  return ret;
}

/*
  Insert the combined NULL terminated buffer to mem. Then split it into a
  linked list of buffer of size CLIENT_SOCK_SZ
*/
static void
popupSplitDataBuf(MemObject * mem, char * html)
{
  int totalBufSize = strlen(html);
  int fullBuf = totalBufSize / CLIENT_SOCK_SZ; /* # of full buffers */
  /* the buf at the tail, size must be < CLIENT_SOCK_SZ */
  int lastBufSize = totalBufSize % CLIENT_SOCK_SZ;
  char * bufEnd = &html[totalBufSize]; /* point to the NULL byte */
  mem_node * temp = NULL;
  
  if (lastBufSize != 0) {
    mem->data_hdr.head = (mem_node *) xmalloc(sizeof(mem_node));
    mem->data_hdr.head->data = (char *) xmalloc(lastBufSize*sizeof(char));
    xmemcpy((void *) mem->data_hdr.head->data, (void *) (bufEnd -
lastBufSize), lastBufSize*sizeof(char));
    bufEnd -= lastBufSize;
    mem->data_hdr.tail = mem->data_hdr.head;
    mem->data_hdr.head->len = lastBufSize;
    mem->data_hdr.head->next = NULL;
  }
  while (fullBuf) {
    temp = mem->data_hdr.head;
    mem->data_hdr.head = (mem_node *) xmalloc(sizeof(mem_node));
    mem->data_hdr.head->data = (char *) xmalloc(CLIENT_SOCK_SZ*sizeof(char));
    bufEnd -= CLIENT_SOCK_SZ;
    xmemcpy((void *) mem->data_hdr.head->data, (void *) bufEnd,
CLIENT_SOCK_SZ*sizeof(char));
    mem->data_hdr.head->next = temp;
  }
  assert(html == bufEnd);
  safe_free(html);
}

/*
   Given a string of an HTML document, add the popup script to it.
*/
static char *
popupProcessHTML(char * str, int width, int height)
{
    char * s;
    char * rs;
    char * onload;
    char script[CLIENT_SOCK_SZ];

    script[CLIENT_SOCK_SZ] = '\0';
    snprintf(script, CLIENT_SOCK_SZ, "\n<SCRIPT LANGUAGE=\"JavaScript\">
\nfunction openWindow() {\n\tmenuWindow=window.open('%s','menuWindow','toolbar=
no,scrollbars=yes,status=no,width=%d,height=%d');\n\tif (menuWindow != null)
{\n\t\tif (menuWindow.opener == null) {\n\t\t\tmenuWindow.opener =
self;\n\t\t}\n\t\tmenuWindow.location.href=\"%s\";\n\t\t}\n\tif
(menuWindow.focus) menuWindow.focus();\n\t}\n</SCRIPT>\n", ONLOADURL, width,
height, ONLOADURL);

    /* assert no buffer overflow */
    assert(script[CLIENT_SOCK_SZ] == '\0');
    onload = stristr(str, "body");
    onload = stristr(onload, "onload");
    if (onload) {
        s = strchr(onload, '"');
        ++s;
        s = strchr(s, '"');
        ++s;
        rs = (char *) xmalloc((strlen(str) - (int) s + (int) onload +
strlen(ONLOAD) + strlen(script))*sizeof(char));
        xstrncpy(rs, str, (int) onload - 1 - (int) str);
        strcat(rs, ONLOAD);
        strcat(rs, s);
        assert(rs[strlen(str)-(int)s+(int)onload+strlen(ONLOAD)+strlen(script)]
 == '\0');
    }
    else {
        s = stristr(str, "body");
        s = strchr(s, '>');
        rs = (char *) xmalloc((strlen(str) + strlen(ONLOAD) + 1 +
strlen(script))*sizeof(char));
        xstrncpy(rs, str, (int) s - (int) str);
        strcat(rs, ONLOAD);
        strcat(rs, s);
        assert(rs[strlen(str)+strlen(ONLOAD)+1+strlen(script)] == '\0');
    }
    strcat(rs, script);
    safe_free(str);
    return rs;
}

/*
  a case-insensitive version of ANSI C strstr.
*/
static char *
stristr(const char * s1, const char * s2)
{
    if (*s2 == '\0')
        return ((char *) s1);
    for (; (s1 = strichr(s1, *s2)) != NULL; ++s1) {
        const char * sc1, *sc2;
        for (sc1 = s1, sc2 = s2; ; )
            if (*++sc2 == '\0')
                return ((char *) s1);
            else if (!imatch(*++sc1, *sc2))
                break;
    }
    return NULL;
}

/*
   a case-insensitive version of ANSI C strchr.
*/
static char *
strichr(const char * s, int c)
{
    const char ch = c;

    for (; !imatch(*s, ch); ++s)
        if (*s == '\0')
            return NULL;
    return ((char *) s);
}

/*
  a case-insensitive comparison between two char's.
*/
static int
imatch(const char c1, const char c2)
{
    if (xisalpha(c1) && xisalpha(c2)) {
       return toupper(c1) == toupper(c2);
    }
    else {
       return c1 == c2;
    }
}
Received on Mon Sep 27 1999 - 20:36:44 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:12:17 MST