http协议上传文件.docx
《http协议上传文件.docx》由会员分享,可在线阅读,更多相关《http协议上传文件.docx(10页珍藏版)》请在冰点文库上搜索。
http协议上传文件
竭诚为您提供优质文档/双击可除
http协议上传文件
篇一:
http以post方式上传一个文件
http以post方式上传一个文件,构造其请求头和消息报文
本篇文章主要介绍了"http以post方式上传一个文件,构造其请求头和消息报文(转载)",主要涉及到http以post方式上传一个文件,构造其请求头和消息报文(转载)方面的内容,对于http以post方式上传一个文件,构造其请求头和消息报文(转载)感兴趣的同学可以参考一下。
假设接受文件的网页程序位于http:
//192.168.24.56/logsys/home/uploadispeedlog!
dodefault.html.假设我们要发送一个图片文件,文件名为“kn.jpg”,
首先客户端链接192.168.24.56后,应该发送如下http请求:
post/logsys/home/uploadispeedlog!
dodefault.htmlhttp/1.1accept:
text/plain,*/*accept-language:
zh-cnhost:
192.168.24.56content-type:
multipart/form-data;boundary=-----------------------------7db372eb000e2user-agent:
winhttpclientcontent-length:
3693connection:
keep-alive-------------------------------7db372eb000e2content-disposition:
form-data;name="file";filename="kn.jpg"content-type:
image/jpeg
(此处省略jpeg文件二进制数据...)
-------------------------------7db372eb000e2--
此内容必须一字不差,包括最后的回车,红色字体部分就是协议的头。
给服务器上传数据时,并非协议头每个字段都得说明,其中,content-type是必须的,它包括一个类似标志性质的名为boundary的标志,它可以是随便输入的字符串。
对后面的具体内容也是必须的。
它用来分辨一段内容的开始。
content-length:
3693,这里的3693是要上传文件的总长度。
绿色字体部分就是需要上传的数据,可以是文本,也可以是图片等。
数据内容前面需要有content-disposition,content-type以及content-transfer-encoding等说明字段。
最后的紫色部分就是协议的结尾了。
注意这一行:
content-type:
multipart/form-data;boundary=---------------------------7db372eb000e2
根据rfc1867,multipart/form-data是必须的.
---------------------------7db372eb000e2是分隔符,分隔多个文件、表单项。
其中b372eb000e2是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。
Form每个部分用分隔符分割,分隔符之前必须加上"--"着两个字符(即--{boundary})才能被http协议认为是Form的分隔符,表示结束的话用在正确的分隔符后面添加"--"表示结束。
前面的---------------------------7d是ie特有的标志,mozila为---------------------------71.
每个分隔的数据的都可以用content-type来表示下面数据的类型,可以参考rfc1341(http:
//www.ietf.org/rfc/rfc1341.txt)
例如:
contect-type:
image/jpeg表示下面的数据是jpeg文件数据
============================================================================
[转]通过http协议上传文件
20xx-04-3023:
55
1、概述
在最初的http协议中,没有上传文件方面的功能。
rfc1867(http:
//www.ietf.org/rfc/rfc1867.txt)为http协议添加了这个功能。
客户端的浏览器,如microsoftie,mozila,opera等,按照此规范将用户指定的文件发送到服务器。
服务器端的网页程序,如php,asp,jsp等,可以按照此规范,解析出用户发送来的文件。
microsoftie,mozila,opera已经支持此协议,在网页中使用一个特殊的form就可以发送文件。
绝大部分httpserver,包括tomcat,已经支持此协议,可接受发送来的文件。
各种网页程序,如php,asp,jsp中,对于上传文件已经做了很好的封装。
2、上传文件的实例:
用servelet实现(httpserver为tomcat4.1.24)
1.在一个html网页中,写一个如下的form:
loadmultifiles:
textfield:
2.服务端servelet的编写
现在第三方的httpuploadfile工具库很多。
jarkata项目本身就提供了fileupload包http:
//jakarta.apache.org/commons/fileupload/。
文件上传、表单项处理、效率问题基本上都考虑到了。
在struts中就使用了这个包,不过是用struts的方式另行封装了一次。
这里我们直接使用fileupload包。
至于struts中的用法,请参阅struts相关文档。
这个处理文件上传的servelet主要代码如下:
publicvoiddopost(httpservletRequestrequest,httpservletResponseresponse){
diskFileuploaddiskFileupload=newdiskFileupload();
//允许文件最大长度
diskFileupload.setsizemax(100*1024*1024);
//设置内存缓冲大小
diskFileupload.setsizethreshold(4096);
//设置临时目录
diskFileupload.setRepositorypath("c:
/tmp");
listfileitems=diskFileupload.parseRequest(request);
iteratoriter=fileitems.iterator();
for(;iter.hasnext();){
Fileitemfileitem=(Fileitem)iter.next();
if(fileitem.isFormField()){
//当前是一个表单项
out.println("formfield:
"+fileitem.getFieldname()+","+fileitem.getstring());}else{
//当前是一个上传的文件
stringfilename=fileitem.getname();
fileitem.write(newFile("c:
/uploads/"+filename));
}
}
}
为简略起见,异常处理,文件重命名等细节没有写出。
3、客户端发送内容构造
假设接受文件的网页程序位于http:
//192.168.29.65/upload_file/uploadFile.
假设我们要发送一个二进制文件、一个文本框表单项、一个密码框表单项。
文件名为e:
\s,其内容如下:
(其中的xxx代表二进制数据,如010203)
a
bb
xxx
ccc
客户端应该向192.168.29.65发送如下内容:
post/upload_file/uploadFilehttp/1.1
accept:
text/plain,*/*
accept-language:
zh-cn
host:
192.168.29.65:
80
content-type:
multipart/form-data;boundary=---------------------------7d33a816d302b6
user-agent:
mozilla/4.0(compatible;openoffice.org)
content-length:
424
connection:
keep-alive
-----------------------------7d33a816d302b6
content-disposition:
form-data;name="userfile1";filename="e:
\s"
content-type:
application/octet-stream
a
bb
xxx
ccc
-----------------------------7d33a816d302b6
content-disposition:
form-data;name="text1"
foo
-----------------------------7d33a816d302b6
content-disposition:
form-data;name="password1"
bar
-----------------------------7d33a816d302b6--
此内容必须一字不差,包括最后的回车。
注意:
content-length:
424这里的424是红色内容的总长度(包括最后的回车)注意这一行:
content-type:
multipart/form-data;boundary=---------------------------7d33a816d302b6根据rfc1867,multipart/form-data是必须的.
---------------------------7d33a816d302b6是分隔符,分隔多个文件、表单项。
其中33a816d302b6是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。
前面的---------------------------7d是ie特有的标志。
mozila为---------------------------71
用手工发送这个例子,在上述的servlet中检验通过。
(上面有一个回车)用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给http:
//192.168.29.65/upload_file/uploadFile这是一个servelet程序
注意enctype="multipart/
form-data",method=post,type="file"。
根据rfc1867,这三个属性是必须的。
multipart/form-data是新增的编码类型,以提高二进制文件的传输效率。
具体的解释请参阅rfc1867
篇二:
使用http协议上传比较大的文件档案
使用http协议上传比较大的文件档案,比如通过web方式在邮箱里发送包含交大附件的邮件,附件上传的时间往往会拖很久。
微软表示这与带宽无关,而是因为系统winsock默认的传送缓冲区太小了(只有8kb)。
只要修改一下缓冲区大小,http龟速上传的情况就可以大大改观。
修改的方法很简单,打开注册表后,定位分支〔hkey_cuRRent_useR\software\microsoft\windows\currentVersion\internetsettings〕
然后在右侧窗口里的空白处,右键单击,新建一名为"socketsendbufferlength"的dwoRd值,然后“数值数据”输入“4000”(十六进制,即16kb),点击确认保存修改。
最后重启电脑即可将winsock默认的传送缓冲区设置为16kb。
篇三:
http服务器实现文件上传与下载
http服务器实现文件上传与下载
(一)
一、引言
大家都知道web编程的协议就是http协议,称为超文本传输协议。
在j2ee中我们可以很快的实现一个web工程,但在c++中就不是非常的迅速,原因无非就是底层的socket网络编写需要自己完成,上层的http协议需要我们自己完成,用户接口需要我们自己完成,如何高效和设计一个框架都是非常困难的一件事情。
但这些事情java已经在底层为我们封装好了,而我们仅仅只是在做业务层上的事情吧了。
在本http服务器实现中,利用c++库和socket原套接字编程和pthread线程编写。
拒绝使用第三方库。
因为主要是让大家知道基本的实现方式,除去一些安全、高效等特性,但是不管怎么样,第三方商业库的基本原理还是一致的,只是他们对其进行了优化而已。
在开始的编写时,我不会全部的简介http的协议的内容,这样太枯燥了,我仅仅解释一些下面需要用到的协议字段。
在写本文的时候,之前也有些迷惑,c++到底能干啥,到网上一搜,无非就是能开发游戏,嵌入式编程,写服务器等等。
接着如果问如何编写一个服务器的话,那么这些网络水人又会告诉你,你先把基础学好,看看什么书,之后你就知道了,我只能呵呵了,在无目的的学习中,尽管看了你也不知道如何写的,因为尽管你知道一些大概,但是没有一个人领导你入门,我们还是无法编写一个我们自己想要的东西,我写这篇博客主要是做一个小小的敲门砖吧,尽管网上有许多博客,关于如何编写http服务器的,但是要不是第三方库acl,要么就是短短的几行代码,要么就是加入了微软的一些c#内容或者mFc,这些在我看来只是一些无关紧要的东西,加入后或许界面上你很舒服,但是大大增加了我们的学习成本,因为这些界面上的代码改变了我们所知道的程序流程走向,还有一些界面代码和核心代码的混合,非常不利于学习。
二、http协议
在大家在浏览器的url输入栏上输入http:
//10.1.18.4/doing时。
浏览器向10.1.18.4服务器80端口的进程发送了如下的一个协议头,它是一个文本字符串。
每行以\r\n结束。
表示回车换行。
1get/doinghttp/1.1
2host:
10.1.18.4
3user-agent:
mozilla/5.0(windowsnt6.2;rv:
40.0)gecko/20xx0101Firefox/40.0
4accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.85accept-language:
zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
6accept-encoding:
gzip,deflate
7Referer:
http:
//10.1.18.4/
8connection:
keep-alive
所以知道其实我们发送了一个uRl请求,其实被转化为了一个如上的一些字符串。
在这里我简单的解释一下这个协议头表示什么,因为在网上你可以找到非常多的信息来解释它们。
1)第一行中get/doinghttp1.1表示请求的方式是get,uRl是/doing,http协议的版本是1.1
2)第二行中host就是服务器的ip
3)第三行中user-agent代表着你使用的是什么浏览器在什么系统上运行的。
从上本可以这条信息显示是window上火狐浏览器发出的请求头
4)第四行中accept代表着该浏览器可以接受的信息格式,可以是文本,html,或者应用文件(二进制文件)。
其中q代表权重,表示更愿意接受前面的信息。
还有一些其他的内容,读者
可以自己XX。
5)以下的一些信息中,没有什么用到,我就不解释,看文本意义也大概知道一些信息。
详细的请搜索网络。
在最重要的是一本请求头什么时候表示结束呢,那就是一个空行表示结束。
其实就是"\r\n"结束。
说了这么多可能大家还是有点迷糊,知道这些那么在程序中又是怎么实现的呢。
当初我也迷惑,现在我提出一个最简单的一种实现,就是直接连接一个字符串即可。
在实际实现中我对其进行了分解,但是现在,我解释为如下编写程序:
1char*str="get/doinghttp/1.1\r\n\
2host:
10.1.18.4\r\n\
3user-agent:
mozilla/5.0(windowsnt6.2;rv:
40.0)gecko/20xx0101Firefox/40.0\r\n\
4accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*//*;q=0.8\r\n\
5accept-language:
zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n\6accept-encoding:
gzip,deflate\r\n\
7Referer:
http:
//10.1.18.4/\r\n\
8connection:
keep-alive\r\n\
9Range:
bytes=14584264-\r\n\r\n";
可能上面的协议内容跟之前的有点不一样,没关系,我只是截取了一些内容进行输入。
很简单就是c语言的char*字符串。
在没一行的的结尾都都有一个\,表示表示换行输入,去掉也行,需要把器内容写到一行上,是c语言语法,不懂的读者可以自己查阅c语言的字符串。
我想说的是在每行的结尾都有一个\r\n。
这两个转义字符就是代表回车换行。
并且在第9行有2个\r\n,最后一个代表着空行,意思是说告诉服务器我的协议头到此位置。
为什么需要一个空行呢,这里就有一个网络编程的小小信息。
在sockettcp流编程中,比如你调用了write或read函数,内部不是一次性接受或者发送所有的信息。
所以当我们发送上述的str的时候,不一定一次全部的发送,那么服务端就不知道什么时候结尾了。
所以我们需要http规定以空行作为结尾代表着协议头的结束。
接下面了来就是我们编写的服务器接受到这个字符串。
并且以空行表示接受到整个协议头,然后对其进行解析。
下面就是解析这段字符串的代码,在工程中我对其封装,但是现在我们只要知道实现解析功能即可。
1#include
2#include
3#include
4#include
5#include
6usingnamespacestd;
7
8char*str="get/download/jbpm4s.tthttp/1.1\r\n\
9host:
10.1.18.4\r\n\
10user-agent:
mozilla/5.0(windowsnt6.2;rv:
40.0)gecko/20xx0101Firefox/40.0\r\n\
11accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*//*;q=0.8\r\n\
12accept-language:
zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n\13accept-encoding:
gzip,deflate\r\n\
14Referer:
http:
http:
//10.1.18.4/\r\n\
15connection:
keep-alive\r\n\
16Range:
bytes=14584264-\r\n\r\n";
17
18string
21returnstr;
22}
23
24string
26str.erase(p.base(),str.end());
27returnstr;
28}
29
30string
32returnstr;
33}
34stringgetcontent(string
36intlen=str.size();
37while(i
38i++;
39}
40pos=i;
41returnstr.substr(start,i-start);
42}
43map
44intlen=strlen(str);
45vectorvs;
46inti=0;
47while(i
48if(str[i]!
=\r){
49intj=i;
50while(i
51i++;
52vs.push_back(string(str+j,str+i));
53}else{
54i+=2;
55}
56}
57intpos;
58stringmethod=getcontent(vs[0],0,,pos);
59stringurl=getcontent(vs[0],method.size()+1,,pos);
60map
61mp["method"]=method;
62mp["url"]=url;
63for(inti=1;i
64stringkey=getcontent(vs[i],0,:
pos);
65stringvalue=vs[i].substr(pos+1);
66mp[key]=trim(value);
67}
68returnmp;
69}
70
71intmain(intargc,char**argv)
72{
73map
74for(map
75cout 76}
77return0;
78}
把一些信息解析都放到了一个map里面。
这里的解析是先处理每一行,然后再对每一行进行解析。
可能这样的处理方式有点慢,但是没什么关系,原因是字符串反正比较短,在大并发下效率不会影响太大,如果大家有什么更好的解析方式,可以回复我。
在服务端解析头信息后,我们可以得到/doing这个url,这样我们服务请就可以把客户端需要的内容返回给客户端了,这里就有浏览器请求的内容是否合法是否存在这些信息。
就要在相应的响应头中说明,在《http服务器实现文件上传与下载
(二)》中会进行说明。
欢迎大家一起探讨这些问题。
有什么想法的人给我回复,我们一起学习,一起进步哦。
【编辑推荐】
http网络协议中的httpclienthints技术
一些安全相关的http响应头
漫谈:
http网络协议中Vary响应头
漫谈:
http网络协议中的proxy-connection
漫谈:
http网络协议中的x-Forwarded-For