6b7acffe612c14098105c0ab83e9f2dce8012865
[phpeclipse.git] /
1 package net.sourceforge.phpeclipse.wiki.actions.mediawiki.connect;
2 //Parts of this sources are copied and modified from the jEdit Wikipedia plugin:
3 //http://www.djini.de/software/wikipedia/index.html
4 //
5 //The modified sources are available under the "Common Public License"
6 //with permission from the original author: Daniel Wunsch
7
8 import java.io.BufferedReader;
9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.io.OutputStreamWriter;
12 import java.io.Writer;
13 import java.net.InetAddress;
14 import java.net.ServerSocket;
15 import java.net.Socket;
16 import java.net.SocketException;
17 import java.net.UnknownHostException;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import net.sourceforge.phpeclipse.wiki.actions.OpenWikiLinkEditorAction;
22
23 public class BookmarkletServer implements Runnable {
24   // configuration
25   private InetAddress ADDRESS;
26
27   int PORT = 8009;
28
29   ServerSocket serverSocket = null;
30
31   Thread thread = null;
32
33   public BookmarkletServer() {
34     try {
35       ADDRESS = InetAddress.getByName("127.0.0.1");
36     } catch (UnknownHostException e) {
37       e.printStackTrace();
38     }
39   }
40
41   /** set the port the server listens on - must be called before start() */
42   public void setPort(int port) {
43     PORT = port;
44   }
45
46   /** starts the server Thread */
47   public void start() {
48     //          Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "listening on " + ADDRESS.CanonicalHostName + ":" + PORT);
49     thread = new Thread(this);
50     thread.start();
51   }
52
53   /** stops the server Thread */
54   public void stop() throws IOException {
55     thread.interrupt();
56     serverSocket.close();
57     //          Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "stopped");
58   }
59
60   /** the server loop */
61   public void run() {
62     try {
63     serverSocket = new ServerSocket(PORT, 2, ADDRESS);
64     for (;;) {
65       Socket clientSocket = null;
66       try {
67         if (thread.isInterrupted())
68           break;
69         clientSocket = serverSocket.accept();
70         clientSocket.setSoTimeout(1000);
71         if (thread.isInterrupted())
72           break;
73         handleClient(clientSocket);
74       } catch (SocketException e) {
75         //Log.Log(Log.NOTICE, plugin, "BookmarkletServerSocket closed");
76         System.err.println("WikipediaPlugin: BookmarkletServer: Socket closed");
77       } catch (Exception e) {
78         //                              Log.log(Log.ERROR, plugin, BshUtil.extractDescription(e));
79       } finally {
80         if (clientSocket != null)
81           clientSocket.close();
82       }
83     }
84     serverSocket.close();
85     } catch (IOException e) {
86       
87     }
88   }
89
90   /** called when an incoming Connection is accepted */
91   private void handleClient(Socket clientSocket) throws IOException {
92     if (!clientSocket.getInetAddress().equals(ADDRESS)) {
93       //                        Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "illegal remote address: " + clientSocket.InetAddress);
94       return;
95     }
96
97     BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
98     String line = reader.readLine();
99     if (line == null) {
100       //                        Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "illegal request: " + line);
101       return;
102     }
103
104     /*
105      * javascript:window.location.href='http://127.0.0.1:8009/open' Pattern pattern = Pattern.compile("^GET /(.*?) HTTP/1.[0-9]$",
106      * Pattern.DOTALL);
107      */
108
109     Pattern pattern = Pattern.compile("^GET /(.*?)/\\?(.*) HTTP/1.[0-9]$", Pattern.DOTALL);
110     Matcher matcher = pattern.matcher(line);
111     if (!matcher.matches()) {
112       //                        Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "illegal request: " + line);
113       return;
114     }
115     String action = matcher.group(1);
116     String url = matcher.group(2);
117
118     /*
119      * BookmarkletServer.bsh: Host: 127.0.0.1:8009 User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040810
120      * Debian/1.7.2-2 User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90) Referer:
121      * http://kamelopedia.mormo.org/index.php/V%F6geln
122      */
123     boolean respond = true;
124     for (;;) {
125       line = reader.readLine();
126       if (line == null)
127         break;
128       if (line.length() == 0)
129         break;
130       String lower = line.toLowerCase();
131
132       /*
133        * // find out referer if (lower.startsWith("referer: ")) { url = line.substring("referer: ".length()); Log.log(Log.NOTICE,
134        * plugin, "BookmarkletServer: " + "got URL: " + url); }
135        */
136
137       // find out user-agent
138       if (lower.startsWith("user-agent: ") && lower.indexOf("mozilla") >= 0 && lower.indexOf("gecko") >= 0
139           && lower.indexOf("msie") < 0 && lower.indexOf("opera") < 0 && lower.indexOf("safari") < 0) {
140         respond = false;
141         //                              Log.log(Log.DEBUG, plugin, "BookmarkletServer: " + "mozilla detected: skipping response");
142       }
143     }
144
145     /*
146      * if (url == null) { Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "missing referer header"); return; }
147      */
148
149     handleAction(action, url);
150
151     if (respond) {
152       Writer writer = new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8");
153
154       writer.write("HTTP/1.0 301 Moved Permanently\r\n");
155       writer.write("Cache-Control: no-cache\r\n");
156       writer.write("Pragma: no-cache\r\n");
157       writer.write("Expires: -1\r\n");
158       writer.write("Location: " + url + "\r\n");
159       writer.write("\r\n");
160
161       writer.write("<html><body>");
162       writer.write("goto <a href=\"" + url + "\">" + url + "</a>");
163       writer.write("</body></html>");
164       writer.write("\r\n");
165
166       writer.flush();
167       writer.close();
168     }
169
170     reader.close();
171   }
172
173   /** called when the Connection sent a Command */
174   private void handleAction(String action, String url) {
175     if (!"open".equals(action)) {
176       //                        Log.log(Log.NOTICE, plugin, "BookmarkletServer: " + "unknown action: " + action);
177       return;
178     }
179     // TODO determine the global project and open editor for URL
180     OpenWikiLinkEditorAction.openWikiUrl(null, url);
181     //          wikipedia.openURL(jEdit.getActiveView(), new URL(url), true);
182   }
183
184 }