001: // SimpleGrepFIlter.java
002: // $Id: SimpleGrepFilter.java,v 1.7 2003/01/27 16:14:54 ylafon Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 1999.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigedit.filters;
007:
008: import java.io.IOException;
009: import java.io.InputStream;
010:
011: import org.w3c.tools.resources.Attribute;
012: import org.w3c.tools.resources.AttributeRegistry;
013: import org.w3c.tools.resources.FramedResource;
014: import org.w3c.tools.resources.InvalidResourceException;
015: import org.w3c.tools.resources.ReplyInterface;
016: import org.w3c.tools.resources.RequestInterface;
017: import org.w3c.tools.resources.Resource;
018: import org.w3c.tools.resources.ResourceFilter;
019: import org.w3c.tools.resources.ResourceFrame;
020: import org.w3c.tools.resources.ResourceReference;
021: import org.w3c.tools.resources.StringArrayAttribute;
022: import org.w3c.tools.resources.StringAttribute;
023:
024: import org.w3c.www.http.HTTP;
025: import org.w3c.www.http.HttpEntityMessage;
026: import org.w3c.www.http.HttpReplyMessage;
027: import org.w3c.www.http.HttpRequestMessage;
028:
029: import org.w3c.www.mime.MimeType;
030:
031: import org.w3c.jigsaw.http.Client;
032: import org.w3c.jigsaw.http.Reply;
033: import org.w3c.jigsaw.http.Request;
034:
035: import org.w3c.jigsaw.frames.HTTPFrame;
036:
037: public class SimpleGrepFilter extends ResourceFilter {
038:
039: class ByteArrayComp {
040: byte[] tab = null;
041: String string = null;
042: int idx = -1;
043: int length = -1;
044:
045: boolean matchNow(byte c) {
046: if (tab[idx++] == c) {
047: return (idx == length);
048: } else {
049: idx = 0;
050: return false;
051: }
052: }
053:
054: void reset() {
055: idx = 0;
056: }
057:
058: String getString() {
059: return string;
060: }
061:
062: ByteArrayComp(String string) {
063: tab = string.getBytes();
064: idx = 0;
065: length = tab.length;
066: this .string = string;
067: }
068: }
069:
070: protected ByteArrayComp[] forbiddenBytes = null;
071:
072: /**
073: * Attribute index - The strings to grep.
074: */
075: protected static int ATTR_FORBIDSTRING_ARRAY = -1;
076:
077: /**
078: * Attribute index - The url to redirect.
079: */
080: protected static int ATTR_REDIRECT = -1;
081:
082: static {
083: Class c = null;
084: Attribute a = null;
085:
086: try {
087: c = Class
088: .forName("org.w3c.jigedit.filters.SimpleGrepFilter");
089: } catch (Exception ex) {
090: ex.printStackTrace();
091: System.exit(1);
092: }
093: a = new StringArrayAttribute("forbidden-strings", null,
094: Attribute.EDITABLE | Attribute.MANDATORY);
095: ATTR_FORBIDSTRING_ARRAY = AttributeRegistry.registerAttribute(
096: c, a);
097:
098: a = new StringAttribute("redirect-url", null,
099: Attribute.EDITABLE | Attribute.MANDATORY);
100: ATTR_REDIRECT = AttributeRegistry.registerAttribute(c, a);
101: }
102:
103: protected String[] getForbiddenStrings() {
104: return (String[]) getValue(ATTR_FORBIDSTRING_ARRAY, null);
105: }
106:
107: protected String getRedirectURL() {
108: return (String) getValue(ATTR_REDIRECT, null);
109: }
110:
111: protected ByteArrayComp[] getForbiddenBytes() {
112: if (forbiddenBytes == null) {
113: String[] fstrings = getForbiddenStrings();
114: forbiddenBytes = new ByteArrayComp[fstrings.length];
115: for (int i = 0; i < fstrings.length; i++)
116: forbiddenBytes[i] = new ByteArrayComp(fstrings[i]);
117: }
118: return forbiddenBytes;
119: }
120:
121: /**
122: * Catch assignements to the forbidden strings attribute.
123: * <p>When a change to that attribute is detected, the cached value
124: * are updated.
125: */
126: public void setValue(int idx, Object value) {
127: super .setValue(idx, value);
128: if (idx == ATTR_FORBIDSTRING_ARRAY) {
129: forbiddenBytes = null;
130: }
131: }
132:
133: /**
134: * Searh for a forbidden string in given stream.
135: * @param in the InputStream
136: * @return The String found or <strong>null</strong> if none
137: * was found.
138: */
139: protected String searchForbiddenStrings(InputStream in) {
140: if (getForbiddenStrings() == null)
141: return null;
142: try {
143: ByteArrayComp comp[] = getForbiddenBytes();
144: int len = in.available();
145: int c;
146: in.mark(len);
147: int baclen = comp.length;
148:
149: for (int j = 0; j < baclen; j++)
150: comp[j].reset();
151:
152: while ((c = in.read()) != -1) {
153: for (int i = 0; i < baclen; i++) {
154: if (comp[i].matchNow((byte) c)) {
155: in.reset();
156: return comp[i].getString();
157: }
158: }
159: }
160: in.reset();
161: return null;
162: } catch (IOException ex) {
163: return null;
164: }
165: }
166:
167: /**
168: * Search the forbidden string in the body, if found return
169: * an ACCES FORBIDDEN Reply.
170: * @param request The request that is about to be processsed.
171: */
172:
173: public ReplyInterface ingoingFilter(RequestInterface req) {
174: Request request = (Request) req;
175: if (request.getMethod().equals("PUT")) {
176: try {
177: MimeType req_mt = request.getContentType();
178: if (req_mt.match(MimeType.TEXT) == MimeType.NO_MATCH)
179: return null;
180: } catch (NullPointerException ex) {
181: // no Content-Type sent! check anyway
182: }
183:
184: InputStream in = null;
185: try {
186: in = request.getInputStream();
187: if (in == null) {
188: return null;
189: }
190: } catch (IOException ex) {
191: return null;
192: }
193: // verify that the target resource is putable
194: ResourceReference rr = request.getTargetResource();
195: if (rr != null) {
196: try {
197: FramedResource target = (FramedResource) rr.lock();
198: HTTPFrame frame = null;
199: try {
200: frame = (HTTPFrame) target
201: .getFrame(Class
202: .forName("org.w3c.jigsaw.frames.HTTPFrame"));
203: } catch (ClassNotFoundException cex) {
204: cex.printStackTrace();
205: //big big problem ...
206: }
207: if (frame == null) // can't be putable
208: return null;
209: // now we can verify if the target resource is putable
210: if (!frame.getPutableFlag()) {
211: return null;
212: }
213: // and that the PUT can happen (taken from putFileResource
214: int cim = frame.checkIfMatch(request);
215: if ((cim == HTTPFrame.COND_FAILED)
216: || (cim == HTTPFrame.COND_WEAK)
217: || (frame.checkIfNoneMatch(request) == HTTPFrame.COND_FAILED)
218: || (frame.checkIfModifiedSince(request) == HTTPFrame.COND_FAILED)
219: || (frame.checkIfUnmodifiedSince(request) == HTTPFrame.COND_FAILED)) {
220: Reply r = request
221: .makeReply(HTTP.PRECONDITION_FAILED);
222: r.setContent("Pre-condition failed.");
223: return r;
224: }
225: } catch (InvalidResourceException ex) {
226: ex.printStackTrace();
227: // problem ...
228: } finally {
229: rr.unlock();
230: }
231: }
232: String expect = request.getExpect();
233: if (expect != null) {
234: if (expect.startsWith("100")) { // expect 100?
235: Client client = request.getClient();
236: if (client != null) {
237: try {
238: client.sendContinue();
239: } catch (java.io.IOException ex) {
240: return null;
241: }
242: }
243: }
244: }
245: String found = searchForbiddenStrings(in);
246: if (found != null) {
247: Reply error = request.makeReply(HTTP.FORBIDDEN);
248: error.setReason("the string \"" + found
249: + "\" is forbidden.");
250: error.setContent("<p>the string \"" + found
251: + "\" is forbidden.</p><br> click "
252: + "<A HREF=\"" + getRedirectURL()
253: + "\">here</A>" + " for explaination.");
254: return error;
255: }
256: return null;
257: } else
258: return null;
259: }
260:
261: }
|