Webserver to Xiao Li. The core functions are socket management, URL processing, HTTP protocol processing, business DLL management, and so on; Here's a brief introduction to the HTTP protocol: Hypertext Transfer Protocol (HTTP) is a communication protocol, which is a TCP-based protocol designed for Web transport. Based on this literal understanding, it can be simple to say that TCP is used to transfer text, data, a codec format. The transport protocol generally includes setting a length + content, or a carriage return as the end of the method. HTTP protocol is a text transfer protocol, so it also uses a carriage return to the end of the way to implement the encoding transmission parsing; Here's an analysis tool to briefly analyze the basic HTTP format:
从可以看出http的基本格式一般大体为成header和body,header的第一行是固定的status line,header与body之间用回车符+空行+回车符来分隔的
GET
Webserver generally receives a GET request as follows:
Copy Code
1 get/yswenli/p/8858669.html http/1.1
2 Host
3 user-agent mozilla/5.0 (Windows NT 10.0; WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/51.0.2704.106 safari/537.36 Accept image/webp,image/,/*; q=0.8
4 Referer
5 accept-encoding gzip, deflate, SDCH
6 Accept-language zh-cn,zh;q=0.8
Copy Code
In other words, if a GET request is initiated, webserver just receives an HTTP header, which is directly charged and parsed.
POST
What if it's a POST request? Viewing HTML-related content, you can see the post there are many ways, generally divided into three kinds, one is the default application/x-www-form-urlencoded:
1 POST http/1.1
2 Content-type:application/x-www-form-urlencoded;charset=utf-8
3
4 title=test&sub%5b%5d=1&sub%5b%5d=2&sub%5b%5d=3
This format is Guangxi happy very source download dashengba.com "Holy Source Forum" Enterprise E 3266397597 "Apple Source Forum" Bbsapple.com with the header and body two parts of the content, when parsing can first press get to receive the head, and then take body,body inside parameters to value is first UrlDecode again htmldecode on it.
第二种就是json、xml、plaine等:
1 POST http/1.1
2 Content-type:application/json;charset=utf-8
3
4 {"title": "Test", "Sub": [[i]}
This is similar to the above, but when the body is taken to read directly on the line ~
还有第三种multipart/form-data,这种模式格式比较复杂,它支持多键值对、多文件的方式,使用特定的boundary来分隔body
Copy Code
1 posthttp/1.1
2 content-type:multipart/form-data boundary=----Webkitformboundaryrgkcby7qhfd3trwa
3
4------Webkitformboundaryrgkcby7qhfd3trwa
5 content-disposition:form-data; name= "Name"
6
7 Yswenli
8------Webkitformboundaryrgkcby7qhfd3trwa
9 content-disposition:form-data; name= "file"; Filename= " Chrome.png "
Ten content-type:image/png
one
png ... Content of chrome.png ...
------Webkitformboundaryrgkcby7qhfd3trwa
Content-disposition:form-data; name= "text"
------Webkitformboundaryrgkcby7qhfd3trwa
Content-disposition:form-data; name= "file"; Filename= " Chrome2.png "
Content-type:image/png
png ... Content of chrome.png ...
------webkitformboundaryrgkcby7qhfd3trwa--
Copy Code
This format is also with the header and body two parts of the content, when the resolution first press get to receive the head, and then take the body, The contents of the body are split by Boundry first, and then the contents of the file are taken out according to Content-type.
TCP to HTTP
Then get the relevant data format, and research and analysis of the HTTP encoding format, the following can start decoding. First use a data to receive the TCP packet of the socket, and then uniformly parse the header of the HTTP packet until the \r\n+ "" +\r\n is intercepted.
Copy Code
1 using (MemoryStream ms = new MemoryStream (buffer))
2 {
3 Ms. Position = 0;
4
5 using (SAEA.Common.StreamReader StreamReader = new SAEA.Common.StreamReader (ms))
4 9
7 while (true)
8 {
9 var str = streamreader.readline ();
if (str = = string. Empty)
11 {
this. Headerstr = _stringbuilder.tostring ();
_stringbuilder.clear ();
break;
15}
+ else if (str = = null && string. IsNullOrEmpty (this. HEADERSTR))
17 {
return false;
19
20}
+ Else
_stringbuilder.appendline (str);
23}
24}
25}
Copy Code
The above uses a custom StreamReader, because of the position that cannot locate the stream, and if the header of HTTP has been successfully parsed, then the header can be used to determine whether the commit is a get or post.
Copy Code
1//<summary>
2///parsing data for HTTP requests
3//</summary>
4//<param name= "Data" ></param>
5//<param name= "Onunpackage" ></param>
6 public void Getrequest (byte[] data, action<requestdatareader> onunpackage)
7 {
8 Lock (_locker)
9 {
Ten _cache. AddRange (data);
11
var buffer = _cache. ToArray ();
13
if (!isanalysis)
15 {
Isanalysis = _httpstringreader.analysis (buffer);
17}
if (isanalysis)
19 {
//post need to process body
if (_httpstringreader.method = = conststring.poststr)
22 {
var contentlen = _httpstringreader.contentlength;
var positon = _httpstringreader.position;
var Totlallen = Contentlen + positon;
if (buffer. Length = = Totlallen)
27 {
_httpstringreader.analysisbody (buffer);
Onunpackage.invoke (_httpstringreader);
Array.clear (buffer, 0, buffer. Length);
buffer = NULL;
_cache. Clear ();
_cache = null;
34}
35}
$ else
37 {
Onunpackage.invoke (_httpstringreader);
Array.clear (buffer, 0, buffer. Length);
buffer = NULL;
_cache. Clear ();
_cache = null;
43}
44}
45}
46}
Copy Code
If the header is parsed, the body can be parsed according to the HTTP data format of the relevant post.
Copy Code
1 switch (this. ContentType)
2 {
3 Case CONSTSTRING.FORMENCTYPE1:
4 this. Forms = Getrequestforms (Encoding.UTF8.GetString (this. Body));
5 break;
6 Case CONSTSTRING.FORMENCTYPE2:
7//todo
8 using (MemoryStream ms = new MemoryStream (this. Body))
9 {
Ten Ms. Position = 0;
One using (var sr = new SAEA.Common.StreamReader (ms))
12 {
StringBuilder sb = new StringBuilder ();
var str = string. Empty;
The
16 {
+ str = Sr. ReadLine ();
if (str = = null)
19 {
break;
21}
All else
23 {
SB. Appendline (str);
if (str. IndexOf (CT) >-1)
26 {
var Filepart = Getrequestformswithmultipart (sb.) ToString ());
28
if (Filepart! = null)
30 {
Sr. ReadLine ();
32
Filepart.data = Sr. ReadData (Sr. Position, this. boundary);
if (filepart.data! = null)
35 {
Filepart.data = FilePart.Data.Take (filepart.data.length-2). ToArray ();
37}
if (this. Postfiles = = null)
this. Postfiles = new list<filepart> ();
. Postfiles.add (Filepart);
41}
The SB. Clear ();
Sr. ReadLine ();
44}
45}
46}
(true);
48
49}
50}
a break;
Default:
this. Json = Encoding.UTF8.GetString (this. Body);
The break;
55}
Copy Code
At this point, the relevant parsing of HTTP is complete, the detailed code can be see:
1.HCode主要功能收取tcp包、 2.RequestDataReader主要功能是收到的tcp包近http协议转成webrequest、 3.HttpRequest主要功能是将转换的数据进行model赋值、 4.HttpContext主要功能是映射到处理业务并返回http数据
To do Guangxi happy very source download the core of the HTTP parsing