模拟POST上传文件

原文地址:http://www.faceye.net/search/96957.html


上传下载文件在浏览器里面都非常简单,上传文件在浏览器里就是几个标签,中间到底发生了什么我们全然不知,而下载文件更是简单——下载文件只需获得文件的地址以二进制的方式写出来就好。最近有个同学想在安卓里面做一个上传功能的App,最简单的莫过于HTTP的POST方法了(fork this  )。



  可以先观察下上传文件的HTTP Header:


可以看到Request Header后面多了一个没有见过的 Request Payload, 这个Request Payload 正是上传文件的关键,我的理解主要参考 ,这篇文章详细的介绍了他在后台抓取到的POST的信息的格式,对,POST传送文件的时候格式一定要严格,否则就上传不了(我已经做过多次试验),文章里抓到的数据和 Request Payload里的数据差不多,知识Payload里面没有文件的二进制流。


  总结一下,POST上传文件的要点:   


  一、boundary是浏览器随机生成的分隔符(请求头里面有),请求头里面的boundary前面是四个"-",而Payload里面的是六个,多的两个叫做 prefix(前缀),然后就是结束的地方又有两个prefix(怎么感觉应该叫做后缀)


  二、换行都是"\r\n"


  三、只有最后结束的地方才会多一个前缀,如果是多个文件上传,前面的都一样只有最后一个会多一个前缀


附java实现代码(照着网上的改的):


 import java.io.ByteArrayOutputStream;
  import java.io.File;
   import java.io.FileInputStream;
   import java.io.FileNotFoundException;
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.OutputStream;
   import java.net.HttpURLConnection;
   import java.net.MalformedURLException;
  import java.net.URL;
  
  public class Poster
  {
    static String boundary = "--------------7d226f700d0";
    static String prefix = "--";
    static String newLine = "\r\n";
    public static void main(String args[])
    {
      test();
    }
    private static void test()
    {
      try
      {
        
        URL url = new URL("http://1.crackme.sinaapp.com/scripts/upload.php");//post address
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
  
        connection.setRequestProperty("Content-type","multipart/form-data;boundary="+boundary); 
        AssemblyHttp(connection.getOutputStream());
        InputStream ins = connection.getInputStream();
        byte[] b = readBuffer(ins);
        System.out.println(new String(b));
      } catch (MalformedURLException e)
      {
        System.out.println(" URL address error ");
      } catch (IOException e)
      {
        System.out.println(" URL open error ");
      }
    }
    private static void AssemblyHttp(OutputStream out)
    {
      StringBuffer params = new StringBuffer();
        
      params.append(prefix+boundary + newLine);
                                                    //name is the the key "name"'s value in the upload form
      params.append("Content-Disposition: form-data; name=\"myfile[]\";filename="+"\"20140821182141.jpg\"");
      params.append(newLine);       
      params.append("Content-Type: image/jpeg");
      params.append(newLine+newLine);
      
      StringBuffer params2 = new StringBuffer();
        
      params2.append(prefix+boundary + newLine);
                                                                  
      params2.append("Content-Disposition: form-data; name=\"myfile[]\";filename="+"\"6b68a43308f198a375d9369a39c7ee1e.jpg\"");
      params2.append(newLine);       
      params2.append("Content-Type: image/jpeg");
      params2.append(newLine+newLine);
  
  
      File file = new File("C:\\Users\\KL\\Pictures\\20140821182141.jpg");
      File file2 = new File("C:\\Users\\KL\\Pictures\\6b68a43308f198a375d9369a39c7ee1e.jpg");
      try
      {
        InputStream in = new FileInputStream(file);
        out.write(params.toString().getBytes());                   
        out.write(readBuffer(in));
        out.write(newLine.getBytes());           
        out.write((prefix+boundary+newLine).getBytes());
  
  
        InputStream in2 = new FileInputStream(file2);
        out.write(params2.toString().getBytes());                   
        out.write(readBuffer(in2));
        out.write(newLine.getBytes());
  
        out.write((prefix+boundary + prefix).getBytes());
        out.flush();
        out.close();         
      } catch (FileNotFoundException e)
      {
        System.out.println(" file not found  ");
      } catch (IOException e)
      {
        System.out.println(" IO Error ");
      }
    }

  
    public static byte[] readBuffer(InputStream ins) throws IOException
    {
      byte b[] = new byte[1024];
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      int len = 0;
      while((len=ins.read(b))!= -1)
     {
       stream.write(b, 0, len);
     }
     return stream.toByteArray();
   }
 }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值