001: package bdd.search.query;
002:
003: import java.net.Socket;
004: import java.io.InputStream;
005: import java.io.OutputStream;
006: import java.io.DataInputStream;
007: import java.io.DataOutputStream;
008: import java.io.BufferedOutputStream;
009: import java.io.IOException;
010: import java.util.StringTokenizer;
011: import java.util.Hashtable;
012: import bdd.search.EnginePrefs;
013: import bdd.search.Monitor;
014:
015: /** Written by Tim Macinta 1997 <br>
016: * Distributed under the GNU Public License
017: * (a copy of which is enclosed with the source). <br>
018: * <br>
019: * This class is the server side end of a connection to the web server.
020: */
021: public class QueryConnection extends Thread {
022:
023: Socket sock; // the socket to use for communication
024: EnginePrefs prefs; // preferences
025:
026: public QueryConnection(Socket sock, EnginePrefs prefs) {
027: this .sock = sock;
028: this .prefs = prefs;
029: start();
030: }
031:
032: /** Read a query and respond appropriately. */
033: public void run() {
034:
035: // open streams
036:
037: DataInputStream in = null;
038: DataOutputStream out = null;
039: try {
040: in = new DataInputStream(sock.getInputStream());
041: out = new DataOutputStream(new BufferedOutputStream(sock
042: .getOutputStream()));
043: String line = in.readLine();
044: if (line == null)
045: throw new IOException();
046: String lower_case = line.toLowerCase();
047: boolean found = false;
048: if (lower_case.startsWith("get ")) {
049: StringTokenizer st = new StringTokenizer(line);
050: st.nextToken();
051: String uri = st.nextToken();
052: if (uri.startsWith("/query?")) {
053: Hashtable h = parsePairs(uri.substring(7));
054: String words = (String) h.get("words");
055: if (words != null) {
056: Monitor m = prefs.getMonitor();
057: if (m != null)
058: m.querying(words);
059:
060: // process GET request
061:
062: found = true;
063: if (line.indexOf(' ') != line.lastIndexOf(' ')) {
064: while (line != null
065: && !line.trim().equals("")) {
066: line = in.readLine();
067: }
068: out.writeBytes("HTTP/1.0 200 OK\n");
069: out.writeBytes("MIME-Version: 1.0\n");
070: out.writeBytes("Server: BDDSearchServer\n");
071: out.writeBytes("Content-Type: text/html\n");
072: out.writeBytes("\n");
073: }
074: DBQuery dbq = new DBQuery(words, prefs);
075: dbq.dumpResults(out);
076: }
077: }
078:
079: }
080: if (!found) {
081:
082: // output a missing page response in case of error
083:
084: if (line.indexOf(' ') != line.lastIndexOf(' ')) {
085: while (line != null
086: && !in.readLine().trim().equals("")) {
087: line = in.readLine();
088: }
089: out.writeBytes("HTTP/1.0 404 Not Found\n");
090: out.writeBytes("MIME-Version: 1.0\n");
091: out.writeBytes("Server: BDDSearchServer\n");
092: out.writeBytes("Content-Type: text/html\n");
093: out.writeBytes("\n");
094: }
095: out.writeBytes("<html><head>\n");
096: out.writeBytes("<title>Page not found</title>\n");
097: out.writeBytes("</head><body>\n");
098: out
099: .writeBytes("The page you requested was not found.\n");
100: out.writeBytes("</body></html>\n");
101: }
102: out.flush();
103: } catch (IOException e) {
104: e.printStackTrace();
105: }
106:
107: // Close all connections
108:
109: try {
110: sock.close();
111: in.close();
112: out.close();
113: } catch (IOException e2) {
114: }
115: }
116:
117: /** Takes an url-encoded list of name value pairs as submitted via a
118: * form and decodes all the pairs into a Hashtable keyed by the
119: * names of the pairs.
120: */
121: Hashtable parsePairs(String line) {
122: Hashtable h = new Hashtable(5);
123: StringTokenizer st = new StringTokenizer(line, "&");
124: int i;
125: String s;
126: while (st.hasMoreTokens()) {
127: s = st.nextToken();
128: i = s.indexOf('=');
129: if (i > -1) {
130: h.put(urlDecode(s.substring(0, i)), urlDecode(s
131: .substring(i + 1)));
132: }
133: }
134: return h;
135: }
136:
137: /** Decodes a string that has been url-encoded. */
138: String urlDecode(String encoded) {
139: int targ = encoded.length();
140: StringBuffer decoded = new StringBuffer();
141: char c;
142: try {
143: for (int i = 0; i < targ; i++) {
144: switch (c = encoded.charAt(i)) {
145: case '+':
146: decoded.append(' ');
147: break;
148: case '%':
149: decoded.append((char) (hexValue(encoded
150: .charAt(i + 1)) * 16 + hexValue(encoded
151: .charAt(i + 2))));
152: i += 2;
153: break;
154: default:
155: decoded.append(c);
156: break;
157: }
158: }
159: } catch (IndexOutOfBoundsException e) {
160: }
161: return new String(decoded);
162: }
163:
164: /** Returns the hex value of "c" or -1 if there is no corresponding
165: * hex value.
166: */
167: int hexValue(char c) {
168: if ('0' <= c && c <= '9')
169: return c - '0';
170: if ('A' <= c && c <= 'F')
171: return c - 'A' + 10;
172: if ('a' <= c && c <= 'f')
173: return c - 'a' + 10;
174: return -1;
175: }
176:
177: }
|