741 |
10 Oct 06 |
olle |
1 |
/* |
1652 |
22 May 07 |
gregory |
$Id$ |
741 |
10 Oct 06 |
olle |
3 |
|
1916 |
31 Aug 07 |
jari |
Copyright (C) 2006 Olle Mansson |
1916 |
31 Aug 07 |
jari |
Copyright (C) 2007 Gregory Vincic |
741 |
10 Oct 06 |
olle |
6 |
|
1652 |
22 May 07 |
gregory |
This file is part of Proteios. |
1652 |
22 May 07 |
gregory |
Available at http://www.proteios.org/ |
741 |
10 Oct 06 |
olle |
9 |
|
1652 |
22 May 07 |
gregory |
Proteios is free software; you can redistribute it and/or modify it |
1652 |
22 May 07 |
gregory |
under the terms of the GNU General Public License as published by |
1652 |
22 May 07 |
gregory |
the Free Software Foundation; either version 2 of the License, or |
1652 |
22 May 07 |
gregory |
(at your option) any later version. |
741 |
10 Oct 06 |
olle |
14 |
|
1652 |
22 May 07 |
gregory |
Proteios is distributed in the hope that it will be useful, but |
1652 |
22 May 07 |
gregory |
WITHOUT ANY WARRANTY; without even the implied warranty of |
1652 |
22 May 07 |
gregory |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1652 |
22 May 07 |
gregory |
General Public License for more details. |
741 |
10 Oct 06 |
olle |
19 |
|
1652 |
22 May 07 |
gregory |
You should have received a copy of the GNU General Public License |
1652 |
22 May 07 |
gregory |
along with this program; if not, write to the Free Software |
1652 |
22 May 07 |
gregory |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
1652 |
22 May 07 |
gregory |
02111-1307, USA. |
1652 |
22 May 07 |
gregory |
24 |
*/ |
741 |
10 Oct 06 |
olle |
25 |
|
741 |
10 Oct 06 |
olle |
// Xerver Free Web Server |
741 |
10 Oct 06 |
olle |
// Copyright (C) 2002-2005 Omid Rouhani |
741 |
10 Oct 06 |
olle |
28 |
// |
741 |
10 Oct 06 |
olle |
29 |
// |
741 |
10 Oct 06 |
olle |
// This program is free software; you can redistribute it and/or |
741 |
10 Oct 06 |
olle |
// modify it under the terms of the GNU General Public License |
741 |
10 Oct 06 |
olle |
// as published by the Free Software Foundation; either version 2 |
741 |
10 Oct 06 |
olle |
// of the License, or (at your option) any later version. |
741 |
10 Oct 06 |
olle |
34 |
// |
741 |
10 Oct 06 |
olle |
// This program is distributed in the hope that it will be useful, |
741 |
10 Oct 06 |
olle |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
741 |
10 Oct 06 |
olle |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
741 |
10 Oct 06 |
olle |
// GNU General Public License for more details. |
741 |
10 Oct 06 |
olle |
39 |
// |
741 |
10 Oct 06 |
olle |
// You should have received a copy of the GNU General Public License |
741 |
10 Oct 06 |
olle |
// along with this program; if not, write to the Free Software |
741 |
10 Oct 06 |
olle |
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
741 |
10 Oct 06 |
olle |
43 |
// |
741 |
10 Oct 06 |
olle |
44 |
// |
741 |
10 Oct 06 |
olle |
45 |
// ############################################################# |
741 |
10 Oct 06 |
olle |
// ## YOU CAN CONTACT THE AUTHOR (OMID ROUHANI) AT: ## |
741 |
10 Oct 06 |
olle |
// ## HTTP://WWW.JAVASCRIPT.NU/XERVER/ ## |
741 |
10 Oct 06 |
olle |
48 |
// ## ## |
741 |
10 Oct 06 |
olle |
// ## IF YOUR SOFTWARE IS NOT RELEASED UNDER THE ## |
741 |
10 Oct 06 |
olle |
// ## GNU GENERAL PUBLIC LICENSE (GPL), ## |
741 |
10 Oct 06 |
olle |
// ## PLEASE DO NOT COPY ANYTHING FROM THIS SOURCE CODE!!! ## |
741 |
10 Oct 06 |
olle |
52 |
// ## ## |
741 |
10 Oct 06 |
olle |
// ## FOR FULL LICENSE, PLEASE READ "XERVER LICENSE". ## |
741 |
10 Oct 06 |
olle |
54 |
// ############################################################# |
741 |
10 Oct 06 |
olle |
55 |
|
1652 |
22 May 07 |
gregory |
56 |
package se.lu.thep.coreftpd.webserver; |
741 |
10 Oct 06 |
olle |
57 |
|
791 |
23 Oct 06 |
olle |
58 |
import se.lu.thep.coreftpd.common.DataInputStreamWithReadLine; |
741 |
10 Oct 06 |
olle |
59 |
import java.io.BufferedOutputStream; |
741 |
10 Oct 06 |
olle |
60 |
import java.io.OutputStream; |
741 |
10 Oct 06 |
olle |
61 |
|
741 |
10 Oct 06 |
olle |
62 |
/** |
1652 |
22 May 07 |
gregory |
63 |
* |
1652 |
22 May 07 |
gregory |
* <B>About this class:</B> <BR> |
1652 |
22 May 07 |
gregory |
* This class reads the POST data and sends it as STDIN to the script. <BR> |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
67 |
* |
1652 |
22 May 07 |
gregory |
* <B>How to use:</B> <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>(new ReadInputStreamSTDIN(DataInputStreamWithReadLine argDiswr, |
1652 |
22 May 07 |
gregory |
* OutputStream argOs)).start();</CODE> <BR> |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
72 |
* |
1652 |
22 May 07 |
gregory |
* <B>More info:</B> <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>argDiswr</CODE> = this is the <CODE>DataInputStreamWithReadLine</CODE> |
1652 |
22 May 07 |
gregory |
* containing the data the browser has sent us and that we still have not read |
1652 |
22 May 07 |
gregory |
* (=only the POST data is left in this stream) <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>argOs</CODE> = Everything written to this will be sent to the script |
1652 |
22 May 07 |
gregory |
* (as STDIN). <BR> |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
80 |
* |
1652 |
22 May 07 |
gregory |
* <B>IMPORTANT:</B> <CODE>argOs</CODE> is closed ("<CODE>argOs.close()</CODE>") |
1652 |
22 May 07 |
gregory |
* by <CODE>ReadInputStreamSTDIN</CODE>. |
1652 |
22 May 07 |
gregory |
83 |
* |
741 |
10 Oct 06 |
olle |
* @author <a href="http://www.JavaScript.nu/xerver/" TARGET="_top">Omid Rouhani</a> |
741 |
10 Oct 06 |
olle |
* @version 1.0 |
741 |
10 Oct 06 |
olle |
86 |
*/ |
741 |
10 Oct 06 |
olle |
87 |
|
1652 |
22 May 07 |
gregory |
88 |
final public class ReadInputStreamSTDIN extends ReadInputStream { |
741 |
10 Oct 06 |
olle |
89 |
private DataInputStreamWithReadLine diswr; |
1652 |
22 May 07 |
gregory |
90 |
|
741 |
10 Oct 06 |
olle |
91 |
private BufferedOutputStream bos; |
1652 |
22 May 07 |
gregory |
92 |
|
741 |
10 Oct 06 |
olle |
93 |
RunScript rs_theRunScript; |
741 |
10 Oct 06 |
olle |
94 |
|
741 |
10 Oct 06 |
olle |
95 |
/** |
1652 |
22 May 07 |
gregory |
* About the sleep time (TIME_TO_SLEEP): We want this to be short since this |
1652 |
22 May 07 |
gregory |
* is the minimum time the script has to wait until it gets new data. |
1652 |
22 May 07 |
gregory |
* However, if it is too short this will be like a while(true){}-loop which |
1652 |
22 May 07 |
gregory |
* will eat 100% CPU. So we balance these two factors against each other. |
1652 |
22 May 07 |
gregory |
100 |
*/ |
1652 |
22 May 07 |
gregory |
101 |
private final static int TIME_TO_SLEEP = 50; // See comments below |
741 |
10 Oct 06 |
olle |
102 |
|
1652 |
22 May 07 |
gregory |
103 |
private final static int MAXIMUM_SLEEPS_IN_A_ROW = 100; // See comments |
1652 |
22 May 07 |
gregory |
// below |
741 |
10 Oct 06 |
olle |
105 |
|
1652 |
22 May 07 |
gregory |
106 |
public ReadInputStreamSTDIN() // now we can Extend ReadInputStreamSTDIN |
1652 |
22 May 07 |
gregory |
// without problem |
741 |
10 Oct 06 |
olle |
108 |
{ |
741 |
10 Oct 06 |
olle |
109 |
} |
741 |
10 Oct 06 |
olle |
110 |
|
1652 |
22 May 07 |
gregory |
111 |
public ReadInputStreamSTDIN(DataInputStreamWithReadLine argDiswr, |
1652 |
22 May 07 |
gregory |
112 |
OutputStream argOs, RunScript argTheRunScript) { |
1652 |
22 May 07 |
gregory |
113 |
currentMode = INPUT_MODE; |
1652 |
22 May 07 |
gregory |
114 |
diswr = argDiswr; |
1652 |
22 May 07 |
gregory |
115 |
bos = new BufferedOutputStream(argOs); |
1652 |
22 May 07 |
gregory |
116 |
rs_theRunScript = argTheRunScript; |
741 |
10 Oct 06 |
olle |
117 |
} |
741 |
10 Oct 06 |
olle |
118 |
|
2386 |
14 Nov 07 |
gregory |
119 |
@Override |
1652 |
22 May 07 |
gregory |
120 |
public void sendDataInputMode() { |
1652 |
22 May 07 |
gregory |
121 |
try { |
1652 |
22 May 07 |
gregory |
122 |
/** |
1652 |
22 May 07 |
gregory |
* About the algortihm: We see if we have data to read from "diswr". |
1652 |
22 May 07 |
gregory |
* If we have then we read that and send to script. If we don't have |
1652 |
22 May 07 |
gregory |
* any data we wait for TIME_TO_SLEEP milliseconds and look for new |
1652 |
22 May 07 |
gregory |
* data. However, if we never receive any new data (maybe all data |
1652 |
22 May 07 |
gregory |
* has been sent or there is a long network problem) then we only |
1652 |
22 May 07 |
gregory |
* repeat the procedure MAXIMUM_SLEEPS_IN_A_ROW times. After this we |
1652 |
22 May 07 |
gregory |
* just close the data stream. |
1652 |
22 May 07 |
gregory |
130 |
* |
1652 |
22 May 07 |
gregory |
* However, everytime we get new data we reset the counter |
1652 |
22 May 07 |
gregory |
* (i_timesWeHaveSleept) so that we after this once again go one |
1652 |
22 May 07 |
gregory |
* sleeping a maximum of MAXIMUM_SLEEPS_IN_A_ROW times. So the total |
1652 |
22 May 07 |
gregory |
* number of sleeps (Thread.sleep()) can actually be inifinty (which |
1652 |
22 May 07 |
gregory |
* is what we want). This would occur if we had: get data, sleep, |
1652 |
22 May 07 |
gregory |
* get data, sleep etc. for ever. |
1652 |
22 May 07 |
gregory |
137 |
*/ |
1652 |
22 May 07 |
gregory |
138 |
int n; |
1652 |
22 May 07 |
gregory |
139 |
byte[] buffer = new byte[8192]; // I think 8192 is the largest |
1652 |
22 May 07 |
gregory |
// buffer one of the |
1652 |
22 May 07 |
gregory |
// XXXInputStreamXXX classes uses, |
1652 |
22 May 07 |
gregory |
// so *maybe* it works faster if we |
1652 |
22 May 07 |
gregory |
// read 8192 bytes each time. The |
1652 |
22 May 07 |
gregory |
// value 8192 is showed when you for |
1652 |
22 May 07 |
gregory |
// example check the value of |
1652 |
22 May 07 |
gregory |
// ".available()" and you have more |
1652 |
22 May 07 |
gregory |
// than 8192 bytes in the stream. |
1652 |
22 May 07 |
gregory |
// ".available()" will still return |
1652 |
22 May 07 |
gregory |
// 8192. (You can, however, still |
1652 |
22 May 07 |
gregory |
// read more than 8192 bytes with |
1652 |
22 May 07 |
gregory |
// for example |
1652 |
22 May 07 |
gregory |
// "write(buffer,0,10240)"). Also, |
1652 |
22 May 07 |
gregory |
// 8192 is 10'0000'0000'0000 binary |
1652 |
22 May 07 |
gregory |
// and is the value of some |
1652 |
22 May 07 |
gregory |
// constants, for example: |
1652 |
22 May 07 |
gregory |
// java.util.prefs.Preference.MAX_VALUE_LENGTH, |
1652 |
22 May 07 |
gregory |
// which is the "Maximum length of |
1652 |
22 May 07 |
gregory |
// string allowed as a value". |
1652 |
22 May 07 |
gregory |
159 |
int i_timesWeHaveSleept = 0; |
1652 |
22 May 07 |
gregory |
160 |
while (i_timesWeHaveSleept < MAXIMUM_SLEEPS_IN_A_ROW) { |
1652 |
22 May 07 |
gregory |
161 |
while (diswr.available() > 0 |
1652 |
22 May 07 |
gregory |
162 |
&& (n = diswr.read(buffer, 0, 8192)) != -1)// (br.ready() |
1652 |
22 May 07 |
gregory |
163 |
// && |
1652 |
22 May 07 |
gregory |
// (n=br.read(buffer))!=-1) |
741 |
10 Oct 06 |
olle |
165 |
{ |
1652 |
22 May 07 |
gregory |
166 |
bos.write(buffer, 0, n); |
1652 |
22 May 07 |
gregory |
167 |
i_timesWeHaveSleept = 0; // Everytime we have got new |
1652 |
22 May 07 |
gregory |
// data we reset the counter so |
1652 |
22 May 07 |
gregory |
// that we after this once again |
1652 |
22 May 07 |
gregory |
// go one waiting for a long |
1652 |
22 May 07 |
gregory |
// time. Hence, as long as we |
1652 |
22 May 07 |
gregory |
// once in a while get new data |
1652 |
22 May 07 |
gregory |
// the time we wait |
1652 |
22 May 07 |
gregory |
// (Thread.sleep()) can actually |
1652 |
22 May 07 |
gregory |
// be inifinty. (hence: get |
1652 |
22 May 07 |
gregory |
// data, sleep, get data, sleep |
1652 |
22 May 07 |
gregory |
// etc. for ever; however, each |
1652 |
22 May 07 |
gregory |
// sleep period is of course |
1652 |
22 May 07 |
gregory |
// finite long) |
741 |
10 Oct 06 |
olle |
180 |
} |
741 |
10 Oct 06 |
olle |
181 |
|
1652 |
22 May 07 |
gregory |
182 |
i_timesWeHaveSleept++; |
1652 |
22 May 07 |
gregory |
183 |
Thread.sleep(TIME_TO_SLEEP); |
1652 |
22 May 07 |
gregory |
184 |
} |
741 |
10 Oct 06 |
olle |
185 |
|
1652 |
22 May 07 |
gregory |
186 |
bos.flush(); |
1652 |
22 May 07 |
gregory |
187 |
bos.close(); |
1652 |
22 May 07 |
gregory |
188 |
|
1652 |
22 May 07 |
gregory |
189 |
} catch (Exception e) { |
1652 |
22 May 07 |
gregory |
190 |
exceptionOccured(e); |
1652 |
22 May 07 |
gregory |
191 |
if (b_showErrors) |
1652 |
22 May 07 |
gregory |
192 |
System.out |
1652 |
22 May 07 |
gregory |
193 |
.println("An error has occured @ sendDataInputMode:\n" |
1652 |
22 May 07 |
gregory |
194 |
+ e.getMessage()); |
1652 |
22 May 07 |
gregory |
195 |
} |
741 |
10 Oct 06 |
olle |
196 |
} |
741 |
10 Oct 06 |
olle |
197 |
|
1652 |
22 May 07 |
gregory |
198 |
private void exceptionOccured(Exception e) { |
741 |
10 Oct 06 |
olle |
199 |
rs_theRunScript.killProcess(); |
741 |
10 Oct 06 |
olle |
200 |
} |
741 |
10 Oct 06 |
olle |
201 |
} |