xitiomet / placebohttp (http://openstatic.org/)
Embeded Http server for gcj/java applications. PlaceboHttp uses an automatic session management system, Treating each session as a HttpRequest queue.
| commit 18: | 00cf4ae79f6b |
| parent 17: | 8b48faa4e88d |
| branch: | default |
Changed (Δ13.2 KB):
Makefile (8 lines added, 1 lines removed)
src/PlaceboBase.java (13 lines added, 140 lines removed)
src/org/openstatic/placebo/ControlPanel.java (34 lines added, 10 lines removed)
src/org/openstatic/placebo/CoreServer.java (144 lines added, 0 lines removed)
| … | … | @@ -15,6 +15,7 @@ all: placebohttp |
15 |
15 |
jvm: |
16 |
16 |
mkdir jvm-build |
17 |
17 |
$(JAVAC) src/*.java src/org/openstatic/http/*.java -d jvm-build |
18 |
$(JAVAC) src/*.java src/org/openstatic/placebo/*.java -d jvm-build |
|
18 |
19 |
$(JAR) -cvmf manifest.mf placebohttp.jar -C jvm-build org -C jvm-build PlaceboBase.class www |
19 |
20 |
|
20 |
21 |
# Executable Rule for GCJ |
| … | … | @@ -44,10 +45,16 @@ build/org/openstatic/http/HttpResponse.c |
44 |
45 |
build/org/openstatic/http/HttpRequestThread.class: src/org/openstatic/http/HttpRequestThread.java |
45 |
46 |
$(JC) $(JC_FLAGS) --classpath=$(CLASS_PATH) -C $< |
46 |
47 |
|
48 |
build/org/openstatic/placebo/ControlPanel.class: src/org/openstatic/placebo/ControlPanel.java |
|
49 |
$(JC) $(JC_FLAGS) --classpath=$(CLASS_PATH) -C $< |
|
50 |
||
51 |
build/org/openstatic/placebo/CoreServer.class: src/org/openstatic/placebo/CoreServer.java |
|
52 |
$(JC) $(JC_FLAGS) --classpath=$(CLASS_PATH) -C $< |
|
53 |
||
47 |
54 |
# Main Builds |
48 |
55 |
# ------------------------------------------------------------------------------- |
49 |
56 |
|
50 |
placebohttp.jar: build/org/openstatic/http/PlaceboHttpServer.class build/org/openstatic/http/PlaceboSession.class build/org/openstatic/http/HttpRequest.class build/org/openstatic/http/HttpRequestThread.class build/org/openstatic/http/HttpResponse.class build/PlaceboBase.class |
|
57 |
placebohttp.jar: build/org/openstatic/http/PlaceboHttpServer.class build/org/openstatic/http/PlaceboSession.class build/org/openstatic/http/HttpRequest.class build/org/openstatic/http/HttpRequestThread.class build/org/openstatic/http/HttpResponse.class build/PlaceboBase.class build/org/openstatic/placebo/ControlPanel.class build/org/openstatic/placebo/CoreServer.class |
|
51 |
58 |
$(JAR) -cvmf manifest.mf $@ -C build org -C build PlaceboBase.class www |
52 |
59 |
|
53 |
60 |
clean: |
Up to file-list src/PlaceboBase.java:
1 |
import org.openstatic.http.PlaceboHttpServer; |
|
2 |
import org.openstatic.http.HttpRequest; |
|
3 |
import org.openstatic.http.HttpResponse; |
|
4 |
import java.io.File; |
|
5 |
import java.io.InputStream; |
|
6 |
import java.io.FileInputStream; |
|
7 |
import java.net.URL; |
|
8 |
import java.util.zip.ZipFile; |
|
9 |
import java.util.zip.ZipEntry; |
|
10 |
import java.util.StringTokenizer; |
|
11 |
import |
|
1 |
import org.openstatic.placebo.CoreServer; |
|
2 |
import org.openstatic.placebo.ControlPanel; |
|
12 |
3 |
|
13 |
4 |
public class PlaceboBase |
14 |
5 |
{ |
| … | … | @@ -24,139 +15,12 @@ public class PlaceboBase |
24 |
15 |
System.err.println(""); |
25 |
16 |
} |
26 |
17 |
|
27 |
public static void web_engine(int http_port, String web_root) |
|
28 |
{ |
|
29 |
// Create new server object |
|
30 |
PlaceboHttpServer server = new PlaceboHttpServer(http_port); |
|
31 |
server.setDebug(debug); |
|
32 |
||
33 |
// Launch thread. |
|
34 |
server.start(); |
|
35 |
||
36 |
while (true) |
|
37 |
{ |
|
38 |
// Blocks until request is made to http server. |
|
39 |
HttpRequest request = server.getNextRequest(); |
|
40 |
||
41 |
// create new response object |
|
42 |
HttpResponse response = new HttpResponse(); |
|
43 |
String path = web_root + request.getPath(); |
|
44 |
||
45 |
// add index to the path if needed |
|
46 |
if (path.endsWith("/")) |
|
47 |
{ |
|
48 |
path += "index.html"; |
|
49 |
} |
|
50 |
||
51 |
// this wacky thing is for finding out if we are inside a zip |
|
52 |
// and retrieving the proper content. |
|
53 |
StringTokenizer path_tokens = new StringTokenizer(path, "/"); |
|
54 |
boolean in_file = false; |
|
55 |
String in_file_path = ""; |
|
56 |
String in_file_type = ""; |
|
57 |
StringBuffer new_path = new StringBuffer(); |
|
58 |
StringBuffer path_inside_file = new StringBuffer(); |
|
59 |
||
60 |
// fix for beginning "/" |
|
61 |
if (path.startsWith("/")) |
|
62 |
new_path.append("/"); |
|
63 |
||
64 |
while (path_tokens.hasMoreTokens()) |
|
65 |
{ |
|
66 |
String token = path_tokens.nextToken(); |
|
67 |
new_path.append(token); |
|
68 |
||
69 |
||
70 |
if (in_file) |
|
71 |
{ |
|
72 |
path_inside_file.append(token); |
|
73 |
} |
|
74 |
||
75 |
// files can act like directories sorta |
|
76 |
String lc_token = token.toLowerCase(); |
|
77 |
int dot_loc = lc_token.indexOf("."); |
|
78 |
if (dot_loc > -1 && lc_token.length() > 2 && !in_file) |
|
79 |
{ |
|
80 |
in_file_path = new_path.toString(); |
|
81 |
in_file_type = lc_token.substring(dot_loc+1).toLowerCase(); |
|
82 |
in_file = true; |
|
83 |
} |
|
84 |
||
85 |
// are we done traveling the path |
|
86 |
if (!path_tokens.hasMoreTokens()) |
|
87 |
{ |
|
88 |
try |
|
89 |
{ |
|
90 |
String file_internal_path = path_inside_file.toString(); |
|
91 |
if (in_file && !"".equals(file_internal_path)) |
|
92 |
{ // we are in a path that requires special processing |
|
93 |
||
94 |
// handle paths with zip files |
|
95 |
if (in_file_type.equals("zip") || in_file_type.equals("jar") || in_file_type.equals("war")) |
|
96 |
{ |
|
97 |
String ftype_upper = in_file_type.toUpperCase(); |
|
98 |
server.logln(ftype_upper + " File: " + in_file_path); |
|
99 |
server.logln(ftype_upper + " Resource: " + file_internal_path); |
|
100 |
ZipFile zipfile = new ZipFile(new File(in_file_path)); |
|
101 |
ZipEntry ze = zipfile.getEntry(file_internal_path); |
|
102 |
InputStream zeis = zipfile.getInputStream(ze); |
|
103 |
response.setBufferedData(zeis, HttpResponse.getContentTypeFor(file_internal_path)); |
|
104 |
} |
|
105 |
||
106 |
// handle ini files |
|
107 |
if (in_file_type.equals("ini")) |
|
108 |
{ |
|
109 |
server.logln("INI File: " + in_file_path); |
|
110 |
server.logln("INI Resource: " + file_internal_path); |
|
111 |
Properties pini = new Properties(); |
|
112 |
pini.load(new FileInputStream(new File(in_file_path))); |
|
113 |
String proxy_url = pini.getProperty("proxy_url"); |
|
114 |
String buffered_proxy_url = pini.getProperty("buffered_proxy_url"); |
|
115 |
||
116 |
if (proxy_url != null) |
|
117 |
{ |
|
118 |
||
119 |
String proxy_path = proxy_url + file_internal_path; |
|
120 |
server.logln("Proxy Path: " + proxy_path); |
|
121 |
response.setData(new URL(proxy_path)); |
|
122 |
||
123 |
} else if (buffered_proxy_url != null) { |
|
124 |
||
125 |
String proxy_path = buffered_proxy_url + file_internal_path; |
|
126 |
server.logln("Buffered Proxy Path: " + proxy_path); |
|
127 |
response.setBufferedData(new URL(proxy_path)); |
|
128 |
||
129 |
} |
|
130 |
} |
|
131 |
||
132 |
} else { // we just have a normal file to serve |
|
133 |
String file_final_path = new_path.toString(); |
|
134 |
server.logln("File: " + file_final_path); |
|
135 |
response.setData(new File(file_final_path)); |
|
136 |
} |
|
137 |
} catch (Exception n) { |
|
138 |
System.err.println(n.getMessage()); |
|
139 |
n.printStackTrace(System.err); |
|
140 |
} |
|
141 |
} else { |
|
142 |
new_path.append("/"); |
|
143 |
if (in_file && path_inside_file.length() > 0) |
|
144 |
{ |
|
145 |
path_inside_file.append("/"); |
|
146 |
} |
|
147 |
} |
|
148 |
} |
|
149 |
||
150 |
// deliver response to request |
|
151 |
request.sendResponse(response); |
|
152 |
} |
|
153 |
} |
|
154 |
||
155 |
18 |
public static void main(String[] args) |
156 |
19 |
{ |
157 |
20 |
int http_port = 80; |
158 |
21 |
boolean debug = false; |
159 |
22 |
String web_root = "placebohttp.jar/www"; |
23 |
boolean start_engine = true; |
|
160 |
24 |
|
161 |
25 |
for (int i = 0; i < args.length; i++) |
162 |
26 |
{ |
| … | … | @@ -189,8 +53,17 @@ public class PlaceboBase |
189 |
53 |
System.err.println("----------------------------------"); |
190 |
54 |
debug = true; |
191 |
55 |
} |
56 |
||
57 |
if (arg.equals("--swing")) |
|
58 |
{ |
|
59 |
ControlPanel cp = new ControlPanel(); |
|
60 |
} |
|
192 |
61 |
} |
193 |
|
|
62 |
||
63 |
if (start_engine) |
|
64 |
{ |
|
65 |
CoreServer.web_engine(http_port, web_root, debug); |
|
66 |
} |
|
194 |
67 |
} |
195 |
68 |
|
196 |
69 |
} |
Up to file-list src/org/openstatic/placebo/ControlPanel.java:
1 |
package org.openstatic.placebo; |
|
2 |
||
3 |
import org.openstatic.placebo.CoreServer; |
|
1 |
4 |
import javax.swing.JFrame; |
2 |
5 |
import javax.swing.JLabel; |
3 |
6 |
import javax.swing.JPanel; |
| … | … | @@ -11,15 +14,15 @@ import java.awt.GridLayout; |
11 |
14 |
import java.awt.FlowLayout; |
12 |
15 |
import java.awt.Toolkit; |
13 |
16 |
import java.awt.Dimension; |
17 |
import java.awt.event.ActionEvent; |
|
18 |
import java.awt.event.ActionListener; |
|
14 |
19 |
import javax.swing.JTabbedPane; |
15 |
20 |
|
16 |
public class ControlPanel extends JFrame |
|
21 |
public class ControlPanel extends JFrame implements ActionListener |
|
17 |
22 |
{ |
18 |
public static void main(String[] args) |
|
19 |
{ |
|
20 |
ControlPanel x = new ControlPanel(); |
|
21 |
} |
|
22 |
||
23 |
private JButton start_btn; |
|
24 |
private JButton stop_btn; |
|
25 |
||
23 |
26 |
public void centerWindow() |
24 |
27 |
{ |
25 |
28 |
Toolkit tk = Toolkit.getDefaultToolkit(); |
| … | … | @@ -33,7 +36,8 @@ public class ControlPanel extends JFrame |
33 |
36 |
public ControlPanel() |
34 |
37 |
{ |
35 |
38 |
super("Placebo Web Server"); |
36 |
||
39 |
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
40 |
||
37 |
41 |
JTabbedPane tabbed = new JTabbedPane(); |
38 |
42 |
|
39 |
43 |
JPanel main_pane = new JPanel(); |
| … | … | @@ -46,9 +50,15 @@ public class ControlPanel extends JFrame |
46 |
50 |
JLabel root_label = new JLabel("Web Root:", JLabel.TRAILING); |
47 |
51 |
JTextField root_field = new JTextField(10); |
48 |
52 |
|
49 |
JButton start_btn = new JButton("Start Server"); |
|
50 |
JButton stop_btn = new JButton("Stop Server"); |
|
51 |
||
53 |
start_btn = new JButton("Start Server"); |
|
54 |
start_btn.setActionCommand("start"); |
|
55 |
start_btn.addActionListener(this); |
|
56 |
||
57 |
stop_btn = new JButton("Stop Server"); |
|
58 |
stop_btn.setActionCommand("stop"); |
|
59 |
stop_btn.addActionListener(this); |
|
60 |
stop_btn.setEnabled(false); |
|
61 |
||
52 |
62 |
pane.add(port_label); |
53 |
63 |
pane.add(port_field); |
54 |
64 |
pane.add(root_label); |
| … | … | @@ -74,4 +84,18 @@ public class ControlPanel extends JFrame |
74 |
84 |
centerWindow(); |
75 |
85 |
this.setVisible(true); |
76 |
86 |
} |
87 |
||
88 |
public void actionPerformed(ActionEvent e) |
|
89 |
{ |
|
90 |
if ("start".equals(e.getActionCommand())) |
|
91 |
{ |
|
92 |
start_btn.setEnabled(false); |
|
93 |
stop_btn.setEnabled(true); |
|
94 |
} |
|
95 |
if ("stop".equals(e.getActionCommand())) |
|
96 |
{ |
|
97 |
start_btn.setEnabled(true); |
|
98 |
stop_btn.setEnabled(false); |
|
99 |
} |
|
100 |
} |
|
77 |
101 |
} |
Up to file-list src/org/openstatic/placebo/CoreServer.java:
1 |
package org.openstatic.placebo; |
|
2 |
||
3 |
import org.openstatic.http.PlaceboHttpServer; |
|
4 |
import org.openstatic.http.HttpResponse; |
|
5 |
import org.openstatic.http.HttpRequest; |
|
6 |
import java.io.File; |
|
7 |
import java.io.InputStream; |
|
8 |
import java.io.FileInputStream; |
|
9 |
import java.net.URL; |
|
10 |
import java.util.zip.ZipFile; |
|
11 |
import java.util.zip.ZipEntry; |
|
12 |
import java.util.StringTokenizer; |
|
13 |
import java.util.Properties; |
|
14 |
||
15 |
public class CoreServer |
|
16 |
{ |
|
17 |
public static void web_engine(int http_port, String web_root, boolean debug) |
|
18 |
{ |
|
19 |
// Create new server object |
|
20 |
PlaceboHttpServer server = new PlaceboHttpServer(http_port); |
|
21 |
server.setDebug(debug); |
|
22 |
||
23 |
// Launch thread. |
|
24 |
server.start(); |
|
25 |
||
26 |
while (true) |
|
27 |
{ |
|
28 |
// Blocks until request is made to http server. |
|
29 |
HttpRequest request = server.getNextRequest(); |
|
30 |
||
31 |
// create new response object |
|
32 |
HttpResponse response = new HttpResponse(); |
|
33 |
String path = web_root + request.getPath(); |
|
34 |
||
35 |
// add index to the path if needed |
|
36 |
if (path.endsWith("/")) |
|
37 |
{ |
|
38 |
path += "index.html"; |
|
39 |
} |
|
40 |
||
41 |
// this wacky thing is for finding out if we are inside a zip |
|
42 |
// and retrieving the proper content. |
|
43 |
StringTokenizer path_tokens = new StringTokenizer(path, "/"); |
|
44 |
boolean in_file = false; |
|
45 |
String in_file_path = ""; |
|
46 |
String in_file_type = ""; |
|
47 |
StringBuffer new_path = new StringBuffer(); |
|
48 |
StringBuffer path_inside_file = new StringBuffer(); |
|
49 |
||
50 |
// fix for beginning "/" |
|
51 |
if (path.startsWith("/")) |
|
52 |
new_path.append("/"); |
|
53 |
||
54 |
while (path_tokens.hasMoreTokens()) |
|
55 |
{ |
|
56 |
String token = path_tokens.nextToken(); |
|
57 |
new_path.append(token); |
|
58 |
||
59 |
||
60 |
if (in_file) |
|
61 |
{ |
|
62 |
path_inside_file.append(token); |
|
63 |
} |
|
64 |
||
65 |
// files can act like directories sorta |
|
66 |
String lc_token = token.toLowerCase(); |
|
67 |
int dot_loc = lc_token.indexOf("."); |
|
68 |
if (dot_loc > -1 && lc_token.length() > 2 && !in_file) |
|
69 |
{ |
|
70 |
in_file_path = new_path.toString(); |
|
71 |
in_file_type = lc_token.substring(dot_loc+1).toLowerCase(); |
|
72 |
in_file = true; |
|
73 |
} |
|
74 |
||
75 |
// are we done traveling the path |
|
76 |
if (!path_tokens.hasMoreTokens()) |
|
77 |
{ |
|
78 |
try |
|
79 |
{ |
|
80 |
String file_internal_path = path_inside_file.toString(); |
|
81 |
if (in_file && !"".equals(file_internal_path)) |
|
82 |
{ // we are in a path that requires special processing |
|
83 |
||
84 |
// handle paths with zip files |
|
85 |
if (in_file_type.equals("zip") || in_file_type.equals("jar") || in_file_type.equals("war")) |
|
86 |
{ |
|
87 |
String ftype_upper = in_file_type.toUpperCase(); |
|
88 |
server.logln(ftype_upper + " File: " + in_file_path); |
|
89 |
server.logln(ftype_upper + " Resource: " + file_internal_path); |
|
90 |
ZipFile zipfile = new ZipFile(new File(in_file_path)); |
|
91 |
ZipEntry ze = zipfile.getEntry(file_internal_path); |
|
92 |
InputStream zeis = zipfile.getInputStream(ze); |
|
93 |
response.setBufferedData(zeis, HttpResponse.getContentTypeFor(file_internal_path)); |
|
94 |
} |
|
95 |
||
96 |
// handle ini files |
|
97 |
if (in_file_type.equals("ini")) |
|
98 |
{ |
|
99 |
server.logln("INI File: " + in_file_path); |
|
100 |
server.logln("INI Resource: " + file_internal_path); |
|
101 |
Properties pini = new Properties(); |
|
102 |
pini.load(new FileInputStream(new File(in_file_path))); |
|
103 |
String proxy_url = pini.getProperty("proxy_url"); |
|
104 |
String buffered_proxy_url = pini.getProperty("buffered_proxy_url"); |
|
105 |
||
106 |
if (proxy_url != null) |
|
107 |
{ |
|
108 |
||
109 |
String proxy_path = proxy_url + file_internal_path; |
|
110 |
server.logln("Proxy Path: " + proxy_path); |
|
111 |
response.setData(new URL(proxy_path)); |
|
112 |
||
113 |
} else if (buffered_proxy_url != null) { |
|
114 |
||
115 |
String proxy_path = buffered_proxy_url + file_internal_path; |
|
116 |
server.logln("Buffered Proxy Path: " + proxy_path); |
|
117 |
response.setBufferedData(new URL(proxy_path)); |
|
118 |
||
119 |
} |
|
120 |
} |
|
121 |
||
122 |
} else { // we just have a normal file to serve |
|
123 |
String file_final_path = new_path.toString(); |
|
124 |
server.logln("File: " + file_final_path); |
|
125 |
response.setData(new File(file_final_path)); |
|
126 |
} |
|
127 |
} catch (Exception n) { |
|
128 |
System.err.println(n.getMessage()); |
|
129 |
n.printStackTrace(System.err); |
|
130 |
} |
|
131 |
} else { |
|
132 |
new_path.append("/"); |
|
133 |
if (in_file && path_inside_file.length() > 0) |
|
134 |
{ |
|
135 |
path_inside_file.append("/"); |
|
136 |
} |
|
137 |
} |
|
138 |
} |
|
139 |
||
140 |
// deliver response to request |
|
141 |
request.sendResponse(response); |
|
142 |
} |
|
143 |
} |
|
144 |
} |
