]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/IO.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / util / IO.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.util;
20 import java.io.ByteArrayOutputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.OutputStream;
28 import java.io.PrintWriter;
29 import java.io.Reader;
30 import java.io.StringWriter;
31 import java.io.Writer;
32 import java.nio.ByteBuffer;
33 import java.nio.channels.FileChannel;
34 import java.nio.channels.GatheringByteChannel;
35 import java.nio.charset.Charset;
36
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.log.Logger;
39
40 /* ======================================================================== */
41 /** IO Utilities.
42  * Provides stream handling utilities in
43  * singleton Threadpool implementation accessed by static members.
44  */
45 public class IO 
46 {
47     private static final Logger LOG = Log.getLogger(IO.class);
48     
49     /* ------------------------------------------------------------------- */
50     public final static String
51         CRLF      = "\015\012";
52
53     /* ------------------------------------------------------------------- */
54     public final static byte[]
55         CRLF_BYTES    = {(byte)'\015',(byte)'\012'};
56
57     /* ------------------------------------------------------------------- */
58     public static final int bufferSize = 64*1024;
59
60     /* ------------------------------------------------------------------- */
61     static class Job implements Runnable
62     {
63         InputStream in;
64         OutputStream out;
65         Reader read;
66         Writer write;
67
68         Job(InputStream in,OutputStream out)
69         {
70             this.in=in;
71             this.out=out;
72             this.read=null;
73             this.write=null;
74         }
75         Job(Reader read,Writer write)
76         {
77             this.in=null;
78             this.out=null;
79             this.read=read;
80             this.write=write;
81         }
82         
83         /* ------------------------------------------------------------ */
84         /* 
85          * @see java.lang.Runnable#run()
86          */
87         public void run()
88         {
89             try {
90                 if (in!=null)
91                     copy(in,out,-1);
92                 else
93                     copy(read,write,-1);
94             }
95             catch(IOException e)
96             {
97                 LOG.ignore(e);
98                 try{
99                     if (out!=null)
100                         out.close();
101                     if (write!=null)
102                         write.close();
103                 }
104                 catch(IOException e2)
105                 {
106                     LOG.ignore(e2);
107                 }
108             }
109         }
110     }
111     
112     /* ------------------------------------------------------------------- */
113     /** Copy Stream in to Stream out until EOF or exception.
114      */
115     public static void copy(InputStream in, OutputStream out)
116          throws IOException
117     {
118         copy(in,out,-1);
119     }
120     
121     /* ------------------------------------------------------------------- */
122     /** Copy Reader to Writer out until EOF or exception.
123      */
124     public static void copy(Reader in, Writer out)
125          throws IOException
126     {
127         copy(in,out,-1);
128     }
129     
130     /* ------------------------------------------------------------------- */
131     /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
132      */
133     public static void copy(InputStream in,
134                             OutputStream out,
135                             long byteCount)
136          throws IOException
137     {     
138         byte buffer[] = new byte[bufferSize];
139         int len=bufferSize;
140         
141         if (byteCount>=0)
142         {
143             while (byteCount>0)
144             {
145                 int max = byteCount<bufferSize?(int)byteCount:bufferSize;
146                 len=in.read(buffer,0,max);
147                 
148                 if (len==-1)
149                     break;
150                 
151                 byteCount -= len;
152                 out.write(buffer,0,len);
153             }
154         }
155         else
156         {
157             while (true)
158             {
159                 len=in.read(buffer,0,bufferSize);
160                 if (len<0 )
161                     break;
162                 out.write(buffer,0,len);
163             }
164         }
165     }  
166     
167     /* ------------------------------------------------------------------- */
168     /** Copy Reader to Writer for byteCount bytes or until EOF or exception.
169      */
170     public static void copy(Reader in,
171                             Writer out,
172                             long byteCount)
173          throws IOException
174     {  
175         char buffer[] = new char[bufferSize];
176         int len=bufferSize;
177         
178         if (byteCount>=0)
179         {
180             while (byteCount>0)
181             {
182                 if (byteCount<bufferSize)
183                     len=in.read(buffer,0,(int)byteCount);
184                 else
185                     len=in.read(buffer,0,bufferSize);                   
186                 
187                 if (len==-1)
188                     break;
189                 
190                 byteCount -= len;
191                 out.write(buffer,0,len);
192             }
193         }
194         else if (out instanceof PrintWriter)
195         {
196             PrintWriter pout=(PrintWriter)out;
197             while (!pout.checkError())
198             {
199                 len=in.read(buffer,0,bufferSize);
200                 if (len==-1)
201                     break;
202                 out.write(buffer,0,len);
203             }
204         }
205         else
206         {
207             while (true)
208             {
209                 len=in.read(buffer,0,bufferSize);
210                 if (len==-1)
211                     break;
212                 out.write(buffer,0,len);
213             }
214         }
215     }
216
217     /* ------------------------------------------------------------ */
218     /** Copy files or directories
219      * @param from
220      * @param to
221      * @throws IOException
222      */
223     public static void copy(File from,File to) throws IOException
224     {
225         if (from.isDirectory())
226             copyDir(from,to);
227         else
228             copyFile(from,to);
229     }
230
231     /* ------------------------------------------------------------ */
232     public static void copyDir(File from,File to) throws IOException
233     {
234         if (to.exists())
235         {
236             if (!to.isDirectory())
237                 throw new IllegalArgumentException(to.toString());
238         }
239         else
240             to.mkdirs();
241         
242         File[] files = from.listFiles();
243         if (files!=null)
244         {
245             for (int i=0;i<files.length;i++)
246             {
247                 String name = files[i].getName();
248                 if (".".equals(name) || "..".equals(name))
249                     continue;
250                 copy(files[i],new File(to,name));
251             }
252         }
253     }
254     
255     /* ------------------------------------------------------------ */
256     public static void copyFile(File from,File to) throws IOException
257     {
258         try (InputStream in=new FileInputStream(from);
259                 OutputStream out=new FileOutputStream(to))
260         {
261             copy(in,out);
262         }
263     }
264     
265     /* ------------------------------------------------------------ */
266     /** Read input stream to string.
267      */
268     public static String toString(InputStream in)
269         throws IOException
270     {
271         return toString(in,(Charset)null);
272     }
273     
274     /* ------------------------------------------------------------ */
275     /** Read input stream to string.
276      */
277     public static String toString(InputStream in,String encoding)
278         throws IOException
279     {
280         return toString(in, encoding==null?null:Charset.forName(encoding));
281     }
282
283     /** Read input stream to string.
284      */
285     public static String toString(InputStream in, Charset encoding)
286             throws IOException
287     {
288         StringWriter writer=new StringWriter();
289         InputStreamReader reader = encoding==null?new InputStreamReader(in):new InputStreamReader(in,encoding);
290
291         copy(reader,writer);
292         return writer.toString();
293     }
294
295     /* ------------------------------------------------------------ */
296     /** Read input stream to string.
297      */
298     public static String toString(Reader in)
299         throws IOException
300     {
301         StringWriter writer=new StringWriter();
302         copy(in,writer);
303         return writer.toString();
304     }
305
306
307     /* ------------------------------------------------------------ */
308     /** Delete File.
309      * This delete will recursively delete directories - BE CAREFULL
310      * @param file The file to be deleted.
311      */
312     public static boolean delete(File file)
313     {
314         if (!file.exists())
315             return false;
316         if (file.isDirectory())
317         {
318             File[] files = file.listFiles();
319             for (int i=0;files!=null && i<files.length;i++)
320                 delete(files[i]);
321         }
322         return file.delete();
323     }
324
325     /* ------------------------------------------------------------ */
326     /**
327      * closes an input stream, and logs exceptions
328      *
329      * @param is the input stream to close
330      */
331     public static void close(InputStream is)
332     {
333         try
334         {
335             if (is != null)
336                 is.close();
337         }
338         catch (IOException e)
339         {
340             LOG.ignore(e);
341         }
342     }
343
344     /**
345      * closes a reader, and logs exceptions
346      * 
347      * @param reader the reader to close
348      */
349     public static void close(Reader reader)
350     {
351         try
352         {
353             if (reader != null)
354                 reader.close();
355         } catch (IOException e)
356         {
357             LOG.ignore(e);
358         }
359     }
360
361     /**
362      * closes a writer, and logs exceptions
363      * 
364      * @param writer the writer to close
365      */
366     public static void close(Writer writer)
367     {
368         try
369         {
370             if (writer != null)
371                 writer.close();
372         } 
373         catch (IOException e)
374         {
375             LOG.ignore(e);
376         }
377     }
378     
379     /* ------------------------------------------------------------ */
380     public static byte[] readBytes(InputStream in)
381         throws IOException
382     {
383         ByteArrayOutputStream bout = new ByteArrayOutputStream();
384         copy(in,bout);
385         return bout.toByteArray();
386     }
387
388     /* ------------------------------------------------------------ */
389     /**
390      * A gathering write utility wrapper.
391      * <p>This method wraps a gather write with a loop that handles the limitations of some operating systems that
392      * have a limit on the number of buffers written.  The method loops on the write until either all the content
393      * is written or no progress is made.
394      * @param out The GatheringgByteChannel to write to
395      * @param buffers The buffers to write
396      * @param offset The offset into the buffers array
397      * @param length The length in buffers to write
398      * @return The total bytes written
399      * @throws IOException
400      */
401     public static long write(GatheringByteChannel out, ByteBuffer[] buffers, int offset, int length) throws IOException
402     {
403         long total=0;
404         write: while (length>0)
405         {
406             // Write as much as we can
407             long wrote=out.write(buffers,offset,length);
408             
409             // If we can't write any more, give up
410             if (wrote==0)
411                 break;
412             
413             // count the total
414             total+=wrote;
415             
416             // Look for unwritten content
417             for (int i=offset;i<buffers.length;i++)
418             {
419                 if (buffers[i].hasRemaining())
420                 {
421                     // loop with new offset and length;
422                     length=length-(i-offset);
423                     offset=i;
424                     continue write;
425                 }
426             }
427             length=0;
428         }
429         
430         return total;
431     }
432     
433     
434     /* ------------------------------------------------------------ */
435     /**
436      * closes an output stream, and logs exceptions
437      *
438      * @param os the output stream to close
439      */
440     public static void close(OutputStream os)
441     {
442         try
443         {
444             if (os != null)
445                 os.close();
446         }
447         catch (IOException e)
448         {
449             LOG.ignore(e);
450         }
451     }
452
453     /* ------------------------------------------------------------ */
454     /** 
455      * @return An outputstream to nowhere
456      */
457     public static OutputStream getNullStream()
458     {
459         return __nullStream;
460     }
461
462     /* ------------------------------------------------------------ */
463     /** 
464      * @return An outputstream to nowhere
465      */
466     public static InputStream getClosedStream()
467     {
468         return __closedStream;
469     }
470     
471     /* ------------------------------------------------------------ */
472     /* ------------------------------------------------------------ */
473     private static class NullOS extends OutputStream                                    
474     {
475         @Override
476         public void close(){}
477         @Override
478         public void flush(){}
479         @Override
480         public void write(byte[]b){}
481         @Override
482         public void write(byte[]b,int i,int l){}
483         @Override
484         public void write(int b){}
485     }
486     private static NullOS __nullStream = new NullOS();
487
488     
489     /* ------------------------------------------------------------ */
490     /* ------------------------------------------------------------ */
491     private static class ClosedIS extends InputStream                                    
492     {
493         @Override
494         public int read() throws IOException
495         {
496             return -1;
497         }
498     }
499     private static ClosedIS __closedStream = new ClosedIS();
500     
501     /* ------------------------------------------------------------ */
502     /** 
503      * @return An writer to nowhere
504      */
505     public static Writer getNullWriter()
506     {
507         return __nullWriter;
508     }
509     
510     /* ------------------------------------------------------------ */
511     /** 
512      * @return An writer to nowhere
513      */
514     public static PrintWriter getNullPrintWriter()
515     {
516         return __nullPrintWriter;
517     }
518     
519     /* ------------------------------------------------------------ */
520     /* ------------------------------------------------------------ */
521     private static class NullWrite extends Writer                                    
522     {
523         @Override
524         public void close(){}
525         @Override
526         public void flush(){}
527         @Override
528         public void write(char[]b){}
529         @Override
530         public void write(char[]b,int o,int l){}
531         @Override
532         public void write(int b){}
533         @Override
534         public void write(String s){}
535         @Override
536         public void write(String s,int o,int l){}
537     }
538     private static NullWrite __nullWriter = new NullWrite();
539     private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
540
541 }
542
543
544
545
546
547
548
549
550