package bdd.search.query;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.Hashtable;
import bdd.search.EnginePrefs;
import bdd.search.Monitor;
/** Written by Tim Macinta 1997 <br>
* Distributed under the GNU Public License
* (a copy of which is enclosed with the source). <br>
* <br>
* This class is the server side end of a connection to the web server.
*/
public class QueryConnection extends Thread {
Socket sock; // the socket to use for communication
EnginePrefs prefs; // preferences
public QueryConnection(Socket sock, EnginePrefs prefs) {
this.sock = sock;
this.prefs = prefs;
start();
}
/** Read a query and respond appropriately. */
public void run() {
// open streams
DataInputStream in = null;
DataOutputStream out = null;
try {
in = new DataInputStream(sock.getInputStream());
out = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
String line = in.readLine();
if (line == null) throw new IOException();
String lower_case = line.toLowerCase();
boolean found = false;
if (lower_case.startsWith("get ")) {
StringTokenizer st = new StringTokenizer(line);
st.nextToken();
String uri = st.nextToken();
if (uri.startsWith("/query?")) {
Hashtable h = parsePairs(uri.substring(7));
String words = (String) h.get("words");
if (words != null) {
Monitor m = prefs.getMonitor();
if (m != null) m.querying(words);
// process GET request
found = true;
if (line.indexOf(' ') != line.lastIndexOf(' ')) {
while (line != null && !line.trim().equals("")) {
line = in.readLine();
}
out.writeBytes("HTTP/1.0 200 OK\n");
out.writeBytes("MIME-Version: 1.0\n");
out.writeBytes("Server: BDDSearchServer\n");
out.writeBytes("Content-Type: text/html\n");
out.writeBytes("\n");
}
DBQuery dbq = new DBQuery(words, prefs);
dbq.dumpResults(out);
}
}
}
if (!found) {
// output a missing page response in case of error
if (line.indexOf(' ') != line.lastIndexOf(' ')) {
while (line != null && !in.readLine().trim().equals("")) {
line = in.readLine();
}
out.writeBytes("HTTP/1.0 404 Not Found\n");
out.writeBytes("MIME-Version: 1.0\n");
out.writeBytes("Server: BDDSearchServer\n");
out.writeBytes("Content-Type: text/html\n");
out.writeBytes("\n");
}
out.writeBytes("<html><head>\n");
out.writeBytes("<title>Page not found</title>\n");
out.writeBytes("</head><body>\n");
out.writeBytes("The page you requested was not found.\n");
out.writeBytes("</body></html>\n");
}
out.flush();
} catch (IOException e) {e.printStackTrace();}
// Close all connections
try {
sock.close();
in.close();
out.close();
} catch (IOException e2) {}
}
/** Takes an url-encoded list of name value pairs as submitted via a
* form and decodes all the pairs into a Hashtable keyed by the
* names of the pairs.
*/
Hashtable parsePairs(String line) {
Hashtable h = new Hashtable(5);
StringTokenizer st = new StringTokenizer(line, "&");
int i;
String s;
while (st.hasMoreTokens()) {
s = st.nextToken();
i = s.indexOf('=');
if (i > -1) {
h.put(urlDecode(s.substring(0, i)), urlDecode(s.substring(i+1)));
}
}
return h;
}
/** Decodes a string that has been url-encoded. */
String urlDecode(String encoded) {
int targ = encoded.length();
StringBuffer decoded = new StringBuffer();
char c;
try {
for (int i = 0; i < targ; i++) {
switch(c = encoded.charAt(i)) {
case '+':
decoded.append(' ');
break;
case '%':
decoded.append((char) (hexValue(encoded.charAt(i+1))*16+
hexValue(encoded.charAt(i+2))));
i += 2;
break;
default:
decoded.append(c);
break;
}
}
} catch (IndexOutOfBoundsException e) {}
return new String(decoded);
}
/** Returns the hex value of "c" or -1 if there is no corresponding
* hex value.
*/
int hexValue(char c) {
if ('0' <= c && c <= '9') return c - '0';
if ('A' <= c && c <= 'F') return c - 'A' + 10;
if ('a' <= c && c <= 'f') return c - 'a' + 10;
return -1;
}
}
|