? replyaccess.patch
Index: acl.c
===================================================================
RCS file: /cvsroot/squid/squid/src/acl.c,v
retrieving revision 1.16
diff -u -r1.16 acl.c
--- acl.c	2001/01/12 08:20:32	1.16
+++ acl.c	2001/01/28 23:24:07
@@ -214,6 +214,8 @@
 #endif
     if (!strcmp(s, "req_mime_type"))
 	return ACL_REQ_MIME_TYPE;
+    if (!strcmp(s, "rep_mime_type"))
+	return ACL_REP_MIME_TYPE;
     return ACL_NONE;
 }
 
@@ -278,6 +280,8 @@
 #endif
     if (type == ACL_REQ_MIME_TYPE)
 	return "req_mime_type";
+    if (type == ACL_REP_MIME_TYPE)
+	return "rep_mime_type";
     return "ERROR";
 }
 
@@ -823,7 +827,8 @@
 	break;
 #endif
     case ACL_REQ_MIME_TYPE:
-	aclParseWordList(&A->data);
+    case ACL_REP_MIME_TYPE:
+	aclParseRegexList(&A->data);
 	break;
     case ACL_NONE:
     default:
@@ -1641,6 +1646,15 @@
 #endif
     case ACL_REQ_MIME_TYPE:
 	header = httpHeaderGetStr(&checklist->request->header,
+	    HDR_CONTENT_TYPE);
+	if (NULL == header)
+	    header = "";
+	return aclMatchRegex(ae->data, header);
+	/* NOTREACHED */
+    case ACL_REP_MIME_TYPE:
+	if (!checklist->reply)
+	    return 0;
+	header = httpHeaderGetStr(&checklist->reply->header,
 	    HDR_CONTENT_TYPE);
 	if (NULL == header)
 	    header = "";
Index: cf.data.pre
===================================================================
RCS file: /cvsroot/squid/squid/src/cf.data.pre,v
retrieving revision 1.16
diff -u -r1.16 cf.data.pre
--- cf.data.pre	2001/01/28 15:59:41	1.16
+++ cf.data.pre	2001/01/28 23:24:11
@@ -1801,10 +1801,20 @@
 	  # NOTE: This does NOT match the reply. You cannot use this
 	  # to match the returned file type.
 
+	acl rep_mime_type mime-type1 ...
+	  # regex match against the mime type of the reply recieved by
+	  # squid. Can be used to detect file download or some
+	  # types HTTP tunelling requests.
+	  # NOTE: This has no effect in http_access rules. It only has
+	  # effect in rules that affect the reply data stream such as
+	  # http_reply_access.
+
+
 Examples:
 acl myexample dst_as 1241
 acl password proxy_auth REQUIRED
 acl fileupload req_mime_type -i ^multipart/form-data$
+acl javascript rep_mime_type -i ^application/x-javascript$
 
 NOCOMMENT_START
 #Recommended minimum configuration:
@@ -1864,6 +1874,34 @@
 #
 # And finally deny all other access to this proxy
 http_access deny all
+NOCOMMENT_END
+DOC_END
+
+NAME: http_reply_access
+TYPE: acl_access
+LOC: Config.accessList.reply
+DEFAULT: none
+DEFAULT_IF_NONE: allow all
+DOC_START
+        Allow replies to client requests. This is complementary to http_access.
+
+        http_reply_access allow|deny [!] aclname ...
+
+        NOTE: if there are no access lines present, the default is to allow 
+	all replies
+
+        If none of the access lines cause a match, then the opposite of the
+        last line will apply. Thus it is good practice to end the rules
+        with an "allow all" or "deny all" entry.
+
+NOCOMMENT_START
+#Recommended minimum configuration:
+#
+# Insert your own rules here.
+#
+#
+# and finally allow by default
+http_reply_access allow all
 NOCOMMENT_END
 DOC_END
 
Index: client_side.c
===================================================================
RCS file: /cvsroot/squid/squid/src/client_side.c,v
retrieving revision 1.15
diff -u -r1.15 client_side.c
--- client_side.c	2001/01/12 08:20:32	1.15
+++ client_side.c	2001/01/28 23:24:15
@@ -1761,12 +1761,39 @@
 	    httpReplyDestroy(rep);
 	    return;
 	} else if (rep) {
-	    body_size = size - rep->hdr_sz;
+	    aclCheck_t *ch;
+	    int rv;
+ 	    body_size = size - rep->hdr_sz;
 	    assert(body_size >= 0);
 	    body_buf = buf + rep->hdr_sz;
 	    http->range_iter.prefix_size = rep->hdr_sz;
 	    debug(33, 3) ("clientSendMoreData: Appending %d bytes after %d bytes of headers\n",
 		body_size, rep->hdr_sz);
+	    ch = aclChecklistCreate(Config.accessList.reply, http->request, NULL);
+	    ch->reply = rep;
+	    rv = aclCheckFast(Config.accessList.reply, ch);
+	    debug(33, 2) ("The reply for %s %s is %s, because it matched '%s'\n",
+		RequestMethodStr[http->request->method], http->uri,
+		rv ? "ALLOWED" : "DENIED",
+		AclMatchedName ? AclMatchedName : "NO ACL's");
+	    if (!rv && rep->sline.status!=HTTP_FORBIDDEN) {
+		/* the if above is slightly broken( 403 responses from upstream
+		 * will always be permitted, but AFAIK there is no way
+		 * to tell if this is a squid generated error page, or one from 
+		 * upstream at this point. */
+		ErrorState *err;
+		err = errorCon(ERR_ACCESS_DENIED, HTTP_FORBIDDEN);
+		err->request = requestLink(http->request);
+		storeUnregister(http->sc, http->entry, http);
+		http->sc = NULL;
+		storeUnlockObject(http->entry);
+		http->entry = clientCreateStoreEntry(http, http->request->method,
+		    null_request_flags);
+		errorAppendEntry(http->entry, err);
+		httpReplyDestroy(rep);
+		return;
+	    }
+	    aclChecklistFree(ch);
 	} else if (size < CLIENT_SOCK_SZ && entry->store_status == STORE_PENDING) {
 	    /* wait for more to arrive */
 	    storeClientCopy(http->sc, entry,
Index: enums.h
===================================================================
RCS file: /cvsroot/squid/squid/src/enums.h,v
retrieving revision 1.12
diff -u -r1.12 enums.h
--- enums.h	2001/01/12 08:20:32	1.12
+++ enums.h	2001/01/28 23:24:15
@@ -122,6 +122,7 @@
     ACL_NETDB_SRC_RTT,
     ACL_MAXCONN,
     ACL_REQ_MIME_TYPE,
+    ACL_REP_MIME_TYPE,
     ACL_ENUM_MAX
 } squid_acl;
 
Index: structs.h
===================================================================
RCS file: /cvsroot/squid/squid/src/structs.h,v
retrieving revision 1.21
diff -u -r1.21 structs.h
--- structs.h	2001/01/12 08:20:33	1.21
+++ structs.h	2001/01/28 23:24:20
@@ -246,6 +246,8 @@
     struct in_addr my_addr;
     unsigned short my_port;
     request_t *request;
+    /* for acls that look at reply data */
+    HttpReply * reply;
     ConnStateData *conn;	/* hack for ident and NTLM */
     char rfc931[USER_IDENT_SZ];
     auth_user_request_t *auth_user_request;
@@ -551,6 +553,7 @@
 	acl_access *identLookup;
 #endif
 	acl_access *redirector;
+	acl_access *reply;
     } accessList;
     acl_deny_info_list *denyInfoList;
     struct _authConfig {
