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