root/server/Worker.java

Revision 72, 12.9 kB (checked in by kbarnes3, 2 years ago)

Made the server into an Eclipse project and turned off the bit flipping
in the second octet.

Line 
1 import java.io.BufferedReader;
2 import java.io.BufferedWriter;
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.io.OutputStreamWriter;
9 import java.net.InetAddress;
10 import java.net.Socket;
11 import java.net.SocketException;
12 import java.net.UnknownHostException;
13 import java.util.Calendar;
14 import java.util.Date;
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
17
18 class Worker extends WebServer implements HttpConstants, Runnable {
19
20         // client socket
21         private Socket s;
22         private long startTS;
23         int contentLength;
24         boolean clientSupportsOverhaul = false;
25         InetAddress clientIP;
26         int overhaulClientSpeed;
27         int overhaulClientPort;
28         int overhaulNumChunks;
29         int overhaulChunkSize;
30         int overhaulCurrentChunk;
31         String overhaulCurrentMd5List;
32         String overhaulCurrentClientList;
33         private int actualBytesSent = 0;
34         boolean reGet = false;
35         boolean overhaulKnowledge = false;
36         //String requestedChunks = "";
37         String requestedChunks = "";
38         String responseChunks = "";
39         String overhaulChunkBoundary = "----@@@@@@@@@@@@@----";
40         boolean newClient = false;
41
42         Worker(Socket s, long startTS) {
43                 this.s = s;
44                 this.startTS = startTS;
45                
46                 try {
47                         s.setSoTimeout(WebServer.timeout * 1000);
48                 } catch (SocketException e) {
49                         // TODO Auto-generated catch block
50                         e.printStackTrace();
51                 }
52         }
53
54         public synchronized void run() {
55                 try {
56                         handleClient();
57                 } catch (Exception e) {
58                         e.printStackTrace();
59                 }
60         }
61
62         void handleClient() throws IOException {
63                
64                 BufferedReader is = new BufferedReader(new InputStreamReader(s
65                                 .getInputStream()));
66                 BufferedWriter os = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
67                 String requestedFile = null;
68                
69                 try {
70                        
71                         clientIP = toggleModelnetIP(s.getInetAddress());
72
73                         Pattern requestTag = Pattern.compile("^(\\S+)\\s+(.*)\\s+(.*)",
74                                         Pattern.CASE_INSENSITIVE);
75                         Pattern headerTag = Pattern.compile("(\\S+):\\s+(.*)$");
76
77                         Matcher mHeader = null;
78                         boolean firstLine = true;
79
80                         String line = is.readLine();
81                        
82                         while (line != null && line.equals("") != true) {
83                                
84                                 System.out.println(clientIP + ": " + line);
85
86                                 if (firstLine) {
87                                        
88                                         Matcher mRequest = requestTag.matcher(line);                                   
89
90                                         if (mRequest.find()) {
91                                                 reGet = mRequest.group(1).equalsIgnoreCase("REGET");
92                                                 requestedFile = mRequest.group(2);
93                                                 requestedChunks = (mRequest.group(3) != null) ? mRequest.group(3) : "";
94                                                 //reGet = true;
95                                                 overhaulKnowledge = false;
96                                                 if (requestedChunks.equalsIgnoreCase("all")) {
97                                                         // do not blank chunksRequested
98                                                 } else if (!requestedChunks.contains(";")) {
99                                                         requestedChunks = "";
100                                                         reGet = false;
101                                                 } else {
102                                                         overhaulKnowledge = true;
103                                                 }
104                                                 System.out.println("Requested file: " + requestedFile);
105                                         } else {
106                                                 os.write("HTTP/1.0 " + HTTP_BAD_METHOD
107                                                                 + " Unsupported method type.\n");
108                                                 os.flush();
109                                                 s.close();
110                                                 return;
111                                         }
112
113                                         firstLine = false;
114                                 } else {
115
116                                         if (mHeader == null) {
117                                                 mHeader = headerTag.matcher(line);
118                                         } else {
119                                                 mHeader.reset(line);
120                                         }
121
122                                         if (mHeader.find()) {
123                                                 String field = mHeader.group(1);
124                                                 String value = mHeader.group(2);
125                                                
126                                                 if (field.toLowerCase().equals("supports") && value.toLowerCase().startsWith("overhaul")) {
127                                                         //log("here is the value: " + value);
128                                                         //clientSupportsOverhaul = true;
129                                                         // overhaulClientIP = toggleModelnetIP(s.getInetAddress());
130                                                         //String tmp[] = value.split(" ");
131                                                         //overhaulClientSpeed = new Integer(tmp[1]).intValue();
132                                                     //overhaulClientPort = new Integer(tmp[2]).intValue();
133                                                 }       
134                                         }
135                                 }
136
137                                 line = is.readLine();
138                         }
139
140                        
141                         requestedFile.replace('/', File.separatorChar);
142                         if (requestedFile.startsWith(File.separator)) {
143                                 requestedFile = requestedFile.substring(1);
144                         }
145                        
146                         // locate requested file
147                         File target = new File(WebServer.root, requestedFile);
148                         if (target.isDirectory()) {
149                                 File defaultIndex = new File(target, "index.html");
150                                 if (defaultIndex.exists()) {
151                                         target = defaultIndex;
152                                 }
153                         }
154                        
155                         boolean OK = printHeaders(target, os);
156                         if (OK) {
157                                 sendFile(target, os);
158                         } else {
159                                 send404(target, os);
160                         }
161                 } finally {
162                         s.close();
163                 }
164                
165                 long endTS = Calendar.getInstance().getTimeInMillis();
166                 long duration = endTS - startTS;
167                 int startTSinSeconds = (int) (startTS / 1000);
168                
169                 log(startTSinSeconds + " " + duration + " " +
170                                 toggleModelnetIP(s.getInetAddress()).getHostAddress() + " " +
171                                 requestedFile + " " + actualBytesSent + " " + reGet);
172         }
173
174         boolean printHeaders(File target, BufferedWriter ps) throws IOException {
175                 boolean ret = false;
176                 //int rCode = 0;
177
178                 if (!target.exists() || target.isDirectory()) {
179                         //rCode = HTTP_NOT_FOUND;
180                         ps.write("HTTP/1.0 " + HTTP_NOT_FOUND + " Not found\n");
181                         ret = false;
182                 } else {
183                        
184                         // take care of overhaul mode
185                         //if (inOverhaulMode() || topKFilesInclude(target.getName())) {
186                         if (inOverhaulMode() || inTopKMode()) {
187                                 //rCode = HTTP_PARTIAL;
188                                 ps.write("HTTP/1.0 " + HTTP_PARTIAL + " OK\n");
189                                                                
190                                 synchronized (getOverhaulFiles()) {
191                                         if (!isFileInOverhaulProcess(target.getName())) {
192                                        
193                                        
194                                                 //log("New OverhaulFile: " + target + "; Client: " + overhaulClientIP);
195                                         
196                                                 // calculate chunk size and number
197                                                 calculateChunkInfo((int) target.length());
198                                        
199                                                 OverhaulFile of = new OverhaulFile();
200                                                 of.setMaxClients(overhaulMaxClients);
201                                                 of.setNumChunks(overhaulNumChunks);
202                                                 of.setChunkSize(overhaulChunkSize);
203                                                 of.setMd5List(target);                         
204                                                 requestedChunks = "all";
205                                                 //overhaulCurrentChunk = 1;
206                                                 //of.setLastChunk(1);
207                                                 overhaulCurrentMd5List = of.getMd5ListStr();
208                                                 overhaulCurrentClientList = getOverhaulClientsStr();
209                                                 // The first client should get no other client IPs
210                                                 newClient = addOverhaulClient(clientIP);
211                                                
212                                                 //if (requestedChunks.equalsIgnoreCase("all")) {
213                                                         // do not blank chunksRequested
214                                                 //} else if (!requestedChunks.contains(";")) {
215                                                 //      requestedChunks = "";
216                                                 //      reGet = false;
217                                                 //} else {
218                                                 //      overhaulKnowledge = true;
219                                                 //}
220
221                                                 insertFileIntoOverhaulProcess(target.getName(), of);
222                                         } else {
223                                        
224                                                 OverhaulFile of = getOverhaulFile(target.getName());
225                                        
226                                                 //log("File in Overhaul process: " + target + "; Client: " + overhaulClientIP);
227                                         
228                                                 synchronized (of) {
229                                                         overhaulNumChunks = of.getNumChunks();
230                                                         overhaulChunkSize = of.getChunkSize();
231                                                        
232                                                         overhaulCurrentChunk = of.getLastChunk() + 1;
233                                                         if (!reGet || topKFilesInclude(target.getPath())) {     
234                                                                 overhaulNumChunks = of.getNumChunks();
235                                                                 if (overhaulCurrentChunk == overhaulNumChunks + 1) {
236                                                                         overhaulCurrentChunk = 1;
237                                                                 }
238                                                                 of.setLastChunk(overhaulCurrentChunk);
239                                                         } else if (!topKFilesInclude(target.getPath())) {
240                                                                 requestedChunks = "all";
241                                                         }
242                                                         newClient = addOverhaulClient(clientIP);
243                                                         overhaulCurrentMd5List = of.getMd5ListStr();
244                                                         overhaulCurrentClientList = getOverhaulClientsStr();
245                                                 }
246                                         }
247
248                                         if (!requestedChunks.equals("")) {
249                                                 if (requestedChunks.equalsIgnoreCase("all")) {
250                                                         for (int i = 0; i < overhaulNumChunks; i++) {
251                                                                 responseChunks += (i + 1) + ";";
252                                                         }
253                                                 } else {
254                                                         for (String str:requestedChunks.split(";")) {
255                                                                int chunkIndex = new Integer(str).intValue() - 1;
256                                                                if (chunkIndex < overhaulNumChunks) {
257                                                                         responseChunks += str + ";";
258                                                                }
259                                                         }
260                                                 }
261                                         } else {
262                                                 responseChunks += overhaulCurrentChunk;
263                                         }
264                                 }
265                                
266                                 ps.write("Overhaul-Chunk-Boundary: " + overhaulChunkBoundary + "\n");
267                                 log("Overhaul-Chunk-Boundary: " + overhaulChunkBoundary);
268                                
269                                 ps.write("Overhaul-Chunks: " + responseChunks + "\n");
270                                 log("Overhaul-Chunk: " + responseChunks);
271
272                                 //if (!overhaulKnowledge) {
273                                         ps.write("Overhaul-md5sum: " + overhaulCurrentMd5List + "\n");
274                                         log("Overhaul-md5sum: " + overhaulCurrentMd5List);
275                                 //}
276
277                                 // COMMENTING OUT: check for newClient [Andres' Bug Report -- Apr 8, 2006]
278                                 // MY NOTE: why was this here in the first place?
279                                 //if (newClient) {
280                                         ps.write("Overhaul-hosts: " + overhaulCurrentClientList + "\n");
281                                         log("Overhaul-hosts: " + overhaulCurrentClientList);
282                                 //}
283                                 
284                                 int responseNumChunks = 1;
285                                 if (responseChunks.contains(";")) {
286                                         responseNumChunks = responseChunks.split(";").length;
287                                 }
288                                 contentLength = (overhaulChunkSize + overhaulChunkBoundary.length() + 10 ) * responseNumChunks;
289                                 //if (overhaulCurrentChunk == overhaulNumChunks) {
290                                 //      int startByte = (overhaulCurrentChunk - 1) * overhaulChunkSize;
291                                 //      int endByte = Math.min(overhaulCurrentChunk * overhaulChunkSize - 1, (int) target.length());
292                                 //      contentLength = endByte - startByte;
293                                 //}
294
295                                 ps.write("Content-length: " + contentLength + "\n");
296                                 log("Content-length: " + contentLength);
297                                                                                                
298                         } else {
299                        
300                                 //rCode = HTTP_OK;
301                                 contentLength = (int) target.length();
302                                 ps.write("HTTP/1.0 " + HTTP_OK + " OK\n");
303                                 ps.write("Content-length: " + contentLength + "\n");
304                                
305                                 /*** I DON'T THINK THE BELOW DOES ANYTHING -- POSTSCRIPT, COMMENT *******/
306                                 if (topK > 0) {
307                                         overhaulCurrentClientList = getOverhaulClientsStr();
308                                         // seed the overhaul network
309                                         newClient = addOverhaulClient(clientIP);
310                                         if (newClient) {
311                                                 ps.write("Overhaul-hosts: " + overhaulCurrentClientList + "\n");
312                                                 log("Overhaul-hosts: " + overhaulCurrentClientList);
313                                         }
314                                 }
315                         }
316                        
317                         // output the topK files if we're in p2p-izer mode (both for overhaul hits and regular hits)
318                         if (topK > 0) {
319                                 ps.write("Overhaul-topK: " + getTopKFiles() + "\n");
320                                 log("Overhaul-topK: " + getTopKFiles());
321                         }
322                        
323                         ret = true;
324                 }
325                
326                 ps.write("Server: Simple java\n");
327                 ps.write("Date: " + (new Date()) + "\n");
328
329                 if (ret) {
330                         ps.write("Last Modified: " + (new Date(target.lastModified())) + "\n");
331                         ps.write("Content-type: text/plain\n");
332                 }
333                
334                 ps.write("\n");
335
336                 return ret;
337         }
338
339         void send404(File targ, BufferedWriter ps) throws IOException {
340                 ps.write("Not Found.\n" + "The requested resource was not found.\n");
341         }
342
343         void sendFile(File target, BufferedWriter ps) throws IOException {
344                
345                 InputStream is = new FileInputStream(target.getAbsolutePath());
346
347                 try {
348
349                         System.out.println("responseChunks = " + responseChunks);
350                         // if (reGet || inOverhaulMode()) {
351                         if (responseChunks.length() > 0) {
352                          
353                                 int prevChunkNumber = 0;
354                                 System.out.println("responseChunks: " + responseChunks);
355                                 for (String str:responseChunks.split(";")) {
356                                         int chunkNumber = new Integer(str).intValue();
357                                         int extraBytes = 0;
358
359                                         if (prevChunkNumber == 0) {
360                                                 extraBytes = (chunkNumber - 1) * overhaulChunkSize;
361                                         } else {
362                                                 extraBytes = (chunkNumber - prevChunkNumber - 1) * overhaulChunkSize;
363                                         }
364
365                                         int realBytes = overhaulChunkSize;
366                        
367                                         byte[] buf;
368                                         int n;
369
370                                         if (extraBytes > 0) {   
371                                                 buf = new byte[extraBytes];
372                                                 n = is.read(buf);
373                                
374                                                 if (n != extraBytes) {
375                                                         // oops
376                                                      &