Advertisement
SpyMomiji

SpyMomiji's HTTPHeaderScanner

Mar 3rd, 2014
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.78 KB | None | 0 0
  1. /*  SpyMomiji's HTTPHeaderScanner
  2.  * 版本 1.0.2
  3.  * 日期 2014/03/04
  4.  * https://plus.google.com/u/0/107057557978482828685/posts
  5.  */
  6.  
  7. import java.io.ByteArrayOutputStream;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.util.ArrayList;
  11. import java.util.TreeMap;
  12.  
  13. public class HTTPHeaderScanner extends Thread{
  14.     public ArrayList<String> header = new ArrayList<String>(); //Header 的內容
  15.     public ArrayList<String> headerKeys = new ArrayList<String>(); //headerValues 所有的鍵值
  16.     public TreeMap<String, String> headerValues = new TreeMap<String, String>(); //以 Header 的項目為鍵值,查詢項目內容
  17.     public byte[] data; //接在 Header 後的資料,以陣列儲存以方便程式解讀
  18.     public String method = null; //HTTP 方法
  19.     public String path = null; //HTTP 要求的路徑 (方法為 HTTP 時此屬性為 null)
  20.     public String stats = null; //HTTP 要求的狀態 ex:"200 OK"
  21.     public boolean headerReady = false; //表示準備完成(Header接收完成)
  22.     public boolean dataReady = false; //表示準備完成(資料接收完成)
  23.     public boolean closeAfterRcev = false; //接收結束後切斷串流
  24.     public boolean alert = true; //發生例外狀況時印出訊息
  25.     public Exception exception = null; //錯誤產生時,例外類別會被放到這
  26.    
  27.    
  28.     //使用方法
  29.     //先建立或取得 Socket 物件
  30.     //建立 HTTPHeaderScanner 物件,參數使用 (Socket)object.getOutputStream()
  31.     //接著 start()
  32.    
  33.     //getData() 直接讀取已經載入的資料
  34.     //waitfor() 可取代直接使用 join()
  35.     //close() 同關閉串流
  36.    
  37.     public HTTPHeaderScanner(InputStream inputStream) {
  38.         is = inputStream;
  39.     }
  40.    
  41.     public HTTPHeaderScanner(InputStream inputStream,boolean closeAfterRcev) {
  42.         is = inputStream;
  43.         this.closeAfterRcev = closeAfterRcev;
  44.     }
  45.    
  46.     ByteArrayOutputStream ba = null;
  47.     InputStream is;
  48.    
  49.     public void run() {
  50.         try{
  51.             try{
  52.                 int ch;
  53.                 int bc = -1;
  54.                
  55.                 while(true){
  56.                    
  57.                     //建立新緩衝區
  58.                     ba = new ByteArrayOutputStream();
  59.                    
  60.                     //若上一圈有不小心掃到下一行的字節,將在這邊先行加入
  61.                     if(bc!=-1){
  62.                         ba.write(bc);
  63.                         bc = -1;
  64.                     }
  65.                    
  66.                     while(true){
  67.                         ch = is.read();
  68.                         if(ch == 13 || ch == 10){
  69.                             ch = is.read();
  70.                             if(ch == 13 || ch == 10){
  71.                                 break;
  72.                             }
  73.                             bc = ch;
  74.                             break;
  75.                         }
  76.                         if(ch<0)throw new Exception("Data truncated");
  77.                        
  78.                         //寫入緩衝
  79.                         ba.write(ch);
  80.                     }
  81.                     if(ba.size()==0){
  82.                         break;
  83.                     }
  84.                     String t = new String(ba.toByteArray(),"UTF-8");
  85.                    
  86. //                  System.out.println(t);
  87.                     header.add(t);
  88.                     try{
  89.                         String[] ts = t.split("\\s*:\\s*");
  90.                         headerValues.put(ts[0], ts[1]);
  91.                         headerKeys.add(ts[0]);
  92.                     }catch(Exception e){
  93. //                      System.out.println("\t" + t);
  94.                         String[] ts = t.split("\\s",3);
  95.                         //求出狀態、路徑和訊息
  96.                         if(ts[0].toLowerCase().matches("[get|post]{1,}")){
  97. //                          System.out.println(ts[0] + "\t" + ts[1] + "\t" + ts[2] + "\t");
  98.                             method = ts[0];
  99.                             path = ts[1];
  100.                             stats = ts[2];
  101.                         }else if(ts[0].toLowerCase().matches("http.*")){
  102.                             method = ts[0];
  103.                             stats = ts[1] + " " + ts[2];
  104.                         }
  105.                     }
  106.                 }
  107.             }catch(IOException e){
  108.                 if(alert)e.printStackTrace();
  109.                 if(ba.size()!=0)
  110.                     header.add(new String(ba.toByteArray(),"UTF-8"));
  111.             }
  112.             headerReady = true;
  113. //          System.out.println(header.size());
  114.            
  115. //          System.out.println(header);
  116. //          for(String i : header){
  117. //              System.out.println(i);
  118. //          }
  119.            
  120. //          System.out.println(headerReady);
  121. //          System.out.println(path);
  122.            
  123.            
  124.             ba = new ByteArrayOutputStream();
  125.             try{
  126.                 int length = Integer.parseInt(headerValues.get("Content-Length"));
  127.                 if(length==0)throw new Exception("EmptyDataException");
  128.                 for(int i=0;i<length;i++){
  129.                     ba.write(is.read());
  130.                 }
  131.                 data = ba.toByteArray();
  132.             }catch(NumberFormatException e){
  133.                 TimeoutTimer tt = new TimeoutTimer(this,1000);
  134.                 tt.start();
  135.                 int bc = 0;
  136.                 do{
  137.                     bc = is.read();
  138.                     ba.write(bc);
  139.                     tt.reset();
  140.                 }while(bc != -1);
  141.             }
  142.             dataReady = true;
  143.             if(closeAfterRcev)close();
  144.            
  145.         }catch(Exception e){
  146.             exception = e;
  147.             if(alert)e.printStackTrace();
  148.         }
  149.     }
  150.    
  151.     public byte[] getData(){
  152.         return ba.toByteArray();
  153.     }
  154.    
  155.     public void waitforData(){
  156.         try {
  157.             while(!dataReady && exception==null){
  158.             Thread.sleep(10);
  159.             }
  160.         } catch (InterruptedException e) {
  161.             e.printStackTrace();
  162.         }
  163.     }
  164.    
  165.     public void waitforHeader(){
  166.         try {
  167.             while(!headerReady && exception==null){
  168.             Thread.sleep(10);
  169.             }
  170.         } catch (InterruptedException e) {
  171.             e.printStackTrace();
  172.         }
  173.     }
  174.    
  175.     public void waitforData(long millis){
  176.         try {
  177.             while(!dataReady && exception==null && millis>=0 ){
  178.                 millis -= 10;
  179.                 Thread.sleep(10);
  180.             }
  181.         } catch (InterruptedException e) {
  182.             e.printStackTrace();
  183.         }
  184.     }
  185.    
  186.     public void waitforHeader(long millis){
  187.         try {
  188.             while(!headerReady && exception==null && millis>=0 ){
  189.                 millis -= 10;
  190.                 Thread.sleep(10);
  191.             }
  192.         } catch (InterruptedException e) {
  193.             e.printStackTrace();
  194.         }
  195.     }
  196.  
  197.     @SuppressWarnings("deprecation")
  198.     public void close() {
  199.         try {
  200.             this.stop();
  201.             is.close();
  202.         } catch (IOException e) {
  203.         }
  204.     }
  205. }
  206.  
  207. class TimeoutTimer extends Thread{
  208.     HTTPHeaderScanner htsc;
  209.     int time1;
  210.     int time2;
  211.     public TimeoutTimer(HTTPHeaderScanner HTTPHeaderScanner,int time) {
  212.         this.htsc = HTTPHeaderScanner;
  213.         this.time1 = time;
  214.         this.time2 = time;
  215.     }
  216.    
  217.     public void run() {
  218.         try {
  219.             while(! (time1<0)){
  220.                 time1-=10;
  221.                 Thread.sleep(10);
  222.             }
  223.             if(htsc.exception == null)
  224.                 htsc.dataReady = true;
  225.         } catch (InterruptedException e) {
  226.             e.printStackTrace();
  227.         }
  228.     }
  229.    
  230.     public void reset(){
  231.         time1 = time2;
  232.     }
  233.    
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement