Source code: infranet/EmbeddedDataStream.java
1 /* Copyright (c) 2003, Massachusetts Institute of Technology
2 * All rights reserved.
3 *
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose, without fee, and without written agreement is
6 * hereby granted, provided that the above copyright notice and the following
7 * paragraph appears in all copies of this software.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
14 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
15 * IN THE SOFTWARE.
16 *
17 * Author: Winston Wang
18 *
19 */
20
21 package infranet;
22
23 import javax.servlet.*;
24 import javax.servlet.http.*;
25 import java.io.*;
26 import java.util.*;
27
28 public class EmbeddedDataStream extends ServletOutputStream {
29
30 private static Collection cmdList;
31 private static String program, workDir;
32 private static File stegOut;
33
34 public static void init(String shell, String program) {
35
36 workDir = System.getProperty("java.io.tmpdir");
37 if (!workDir.endsWith(File.separator)) {
38 workDir += File.separator;
39 }
40
41 cmdList = new ArrayList(3);
42 StringTokenizer st = new StringTokenizer(shell);
43 while(st.hasMoreTokens()) {
44 cmdList.add(st.nextToken());
45 }
46 cmdList.add(null);
47
48 EmbeddedDataStream.program = program;
49 EmbeddedDataStream.stegOut = new File(workDir + "steg_out.txt");
50 stegOut.deleteOnExit();
51 }
52
53 private boolean success;
54 private boolean closed;
55
56 private OutputStream in, out;
57 private HttpServletResponse response;
58 private File messageFile;
59 private String key;
60 private int id;
61 private File inFile;
62 private int bytesWritten;
63
64 public EmbeddedDataStream(HttpServletResponse res, String key, byte[] message) throws IOException {
65 this.success = true;
66 this.response = res;
67 this.out = res.getOutputStream();
68 this.key = key;
69 this.id = getNewId();
70 this.messageFile = new File(workDir+"message-" + id + ".dat");
71 this.inFile = new File(workDir+"in-" + id + ".jpg");
72 this.bytesWritten = 0;
73 try {
74 OutputStream o = new BufferedOutputStream(new FileOutputStream(messageFile));
75 o.write(message);
76 o.close();
77
78 this.in = new BufferedOutputStream(new FileOutputStream(inFile));
79 }
80 catch (FileNotFoundException e) {
81 success = false;
82 throw new RuntimeException(e);
83 }
84 catch (IOException e) {
85 success = false;
86 throw new RuntimeException(e);
87 }
88 }
89
90 private static int globalCount = 0;
91
92 private static synchronized int getNewId() {
93 globalCount++;
94 return globalCount;
95 }
96
97 public void close() throws IOException {
98 if (closed) return;
99
100 closed = true;
101 in.close();
102
103 long startTime = new Date().getTime();
104 File outFile = new File(workDir+"out-" + id + ".jpg");
105
106 String[] cmdArray = (String[])cmdList.toArray(new String[0]);
107 cmdArray[cmdArray.length-1] = program+" -i 1 -k "+key+" -d "+
108 messageFile+" "+inFile+" "+outFile+" 2> "+stegOut;
109
110 Process p = Runtime.getRuntime().exec(cmdArray);
111
112 try {
113 success = p.waitFor() == 0;
114 }
115 catch (InterruptedException e) {
116 System.out.println(e);
117 success = false;
118 }
119
120 InputStream i = null;
121 try {
122 File f = success ? outFile : inFile;
123 i = new BufferedInputStream(new FileInputStream(f));
124 }
125 catch (FileNotFoundException e) {
126 throw new RuntimeException(e);
127 }
128
129 byte[] temp = new byte[i.available()];
130 response.setIntHeader("Content-length", temp.length);
131
132 i.read(temp);
133 out.write(temp);
134 i.close();
135 out.close();
136
137 messageFile.delete();
138 inFile.delete();
139 outFile.delete();
140 }
141
142 public void flush() throws IOException {
143 if (closed) return;
144 in.flush();
145 }
146
147 public void write(int b) throws IOException {
148 in.write(b);
149 }
150
151 public boolean success() {
152 return success;
153 }
154
155 public int bytesWritten() {
156 return bytesWritten;
157 }
158 }