001: // PutFilter.java
002: // $Id: GrepPutFilter.java,v 1.12 2003/01/27 16:14:54 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
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.ResourceReference;
019: import org.w3c.tools.resources.StringArrayAttribute;
020: import org.w3c.tools.resources.StringAttribute;
021:
022: import org.w3c.www.mime.MimeType;
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.jigsaw.http.Client;
030: import org.w3c.jigsaw.http.Reply;
031: import org.w3c.jigsaw.http.Request;
032:
033: import org.w3c.jigsaw.frames.HTTPFrame;
034:
035: public class GrepPutFilter extends PutFilter {
036:
037: class ByteArrayComp {
038: byte[] tab = null;
039: String string = null;
040: int idx = -1;
041: int length = -1;
042:
043: boolean matchNow(byte c) {
044: if (tab[idx++] == c) {
045: return (idx == length);
046: } else {
047: idx = 0;
048: return false;
049: }
050: }
051:
052: void reset() {
053: idx = 0;
054: }
055:
056: String getString() {
057: return string;
058: }
059:
060: ByteArrayComp(String string) {
061: tab = string.getBytes();
062: idx = 0;
063: length = tab.length;
064: this .string = string;
065: }
066: }
067:
068: protected ByteArrayComp[] forbiddenBytes = null;
069:
070: /**
071: * Attribute index - The strings to grep.
072: */
073: protected static int ATTR_FORBIDSTRING_ARRAY = -1;
074:
075: /**
076: * Attribute index - The url to redirect.
077: */
078: protected static int ATTR_REDIRECT = -1;
079:
080: static {
081: Class c = null;
082: Attribute a = null;
083:
084: try {
085: c = Class.forName("org.w3c.jigedit.filters.GrepPutFilter");
086: } catch (Exception ex) {
087: ex.printStackTrace();
088: System.exit(1);
089: }
090: a = new StringArrayAttribute("forbidden-strings", null,
091: Attribute.EDITABLE | Attribute.MANDATORY);
092: ATTR_FORBIDSTRING_ARRAY = AttributeRegistry.registerAttribute(
093: c, a);
094:
095: a = new StringAttribute("redirect-url", null,
096: Attribute.EDITABLE | Attribute.MANDATORY);
097: ATTR_REDIRECT = AttributeRegistry.registerAttribute(c, a);
098: }
099:
100: protected String[] getForbiddenStrings() {
101: return (String[]) getValue(ATTR_FORBIDSTRING_ARRAY, null);
102: }
103:
104: protected String getRedirectURL() {
105: return (String) getValue(ATTR_REDIRECT, null);
106: }
107:
108: protected ByteArrayComp[] getForbiddenBytes() {
109: if (forbiddenBytes == null) {
110: String[] fstrings = getForbiddenStrings();
111: forbiddenBytes = new ByteArrayComp[fstrings.length];
112: for (int i = 0; i < fstrings.length; i++)
113: forbiddenBytes[i] = new ByteArrayComp(fstrings[i]);
114: }
115: return forbiddenBytes;
116: }
117:
118: /**
119: * Catch assignements to the forbidden strings attribute.
120: * <p>When a change to that attribute is detected, the cached value
121: * are updated.
122: */
123: public void setValue(int idx, Object value) {
124: super .setValue(idx, value);
125: if (idx == ATTR_FORBIDSTRING_ARRAY) {
126: forbiddenBytes = null;
127: }
128: }
129:
130: /**
131: * Searh for a forbidden string in given stream.
132: * @param in the InputStream
133: * @return The String found or <strong>null</strong> if none
134: * was found.
135: */
136: protected String searchForbiddenStrings(InputStream in) {
137: if (getForbiddenStrings() == null)
138: return null;
139: try {
140: ByteArrayComp comp[] = getForbiddenBytes();
141: int len = in.available();
142: int c;
143: in.mark(len);
144: int baclen = comp.length;
145:
146: for (int j = 0; j < baclen; j++)
147: comp[j].reset();
148:
149: while ((c = in.read()) != -1) {
150: for (int i = 0; i < baclen; i++) {
151: if (comp[i].matchNow((byte) c)) {
152: in.reset();
153: return comp[i].getString();
154: }
155: }
156: }
157: in.reset();
158: return null;
159: } catch (IOException ex) {
160: return null;
161: }
162: }
163:
164: /**
165: * Search the forbidden string in the body, if found return
166: * an ACCES FORBIDDEN Reply.
167: * @param request The request that is about to be processsed.
168: */
169:
170: public ReplyInterface ingoingFilter(RequestInterface req) {
171: ReplyInterface rep = super .ingoingFilter(req);
172: if (rep != null)
173: return rep;
174:
175: Request request = (Request) req;
176: if (request.getMethod().equals("PUT")) {
177: try {
178: MimeType req_mt = request.getContentType();
179: if (req_mt.match(MimeType.TEXT) == MimeType.NO_MATCH)
180: return null;
181: } catch (NullPointerException ex) {
182: // no Content-Type sent! check anyway
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.equalsIgnoreCase(HTTP.HTTP_100_CONTINUE)) {
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: }
|