HTTP消息是由普通ASCII文本组成。消息包括消息头和数据体部分。消息头以行为单位,每行以CRLF(回车和换行)结束,消息头结束后,额外增加一个CRLF,之后内容就是数据体部分了。
格式如图:
http协议格式
那么如果给了一段文本 http文本 我们是否有能力用java解析呢:
GET /doaction?p=123&k=3343 HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: name=jackey;
Host: localhost:12345
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: name=jackey;
下面是我用java解析这段的http协议的一段代码
import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; /** * http协议解析 * @author Mic * */ public class HttpOperator { /** * 协议流 */ private InputStream source; private byte[] buf;//缓存结果 private int pos;//偏移 private int start;//开始 private int end;//结束 private int capacity;//缓存容量 private int lastValid;//每次取数据buf中最有一位字节的下标 private Request request=new Request(); public enum METHOD{ GET,HEAD,POST,OPTIONS,PUT,Delete,TRACE,CONNECT } public HttpOperator(int capacity) { pos=0; start=0; end=0; lastValid=-1; this.capacity=capacity; buf=new byte[capacity]; } public HttpOperator() { this(4096); } /** *填充缓存 */ public boolean fill(){ return fill(buf, 0, capacity); } public boolean fill(byte[] buf,int offset,int length){ int len=-1; try { len=source.read(buf, offset, length); }catch (IOException e) { System.out.println("read source failed"); return false; } start=0; end=0; lastValid=len==-1?-1:len-1; return len!=-1; } public void skipSpace(){ do{ if(pos>=lastValid){ fill(); pos=-1; } pos++; }while(buf[pos]==Constant.SP||buf[pos]==Constant.HT); } public void copy(byte[] src ,int srcOff,byte[] dest,int destOff,int len){ //扩容 if((dest.length-destOff)<len){ byte[] newDest=new byte[dest.length*2]; System.arraycopy(dest, 0, newDest, 0, dest.length); dest=newDest; } System.arraycopy(src, srcOff, dest, destOff, len); } public void parseRequestLine(){ boolean quit=false; while(!quit){ skipSpace(); //Method byte[] v_buf=new byte[1024]; int v_pos=0; int v_len=0; start=pos; while(true){ if(buf[pos]==Constant.SP||buf[pos]==Constant.HT){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); break; } end=pos; pos++; //判断是否用完 if(pos>=lastValid){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); start=pos=end=0; fill(); } } try { request.setMethod(new String(v_buf,0,v_len,"UTF-8")); } catch (UnsupportedEncodingException e) { System.out.println("set method failed"); throw new RuntimeException(e); } //URI v_buf=new byte[1024]; v_pos=0; pos--; skipSpace(); start=pos; v_len=0; while(true){ if(buf[pos]==Constant.SP||buf[pos]==Constant.HT){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); break; } end=pos; pos++; //判断是否用完 if(pos>=lastValid){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); start=pos=end=0; fill(); } } try { request.setUri(new String(v_buf,0,v_len,"UTF-8")); } catch (UnsupportedEncodingException e) { System.out.println("set URI failed"); throw new RuntimeException(e); } //协议版本如HTTP/1.1 v_buf=new byte[1024]; v_pos=0; pos--; skipSpace(); start=pos; v_len=0; while(true){ if(buf[pos]==Constant.LF||buf[end]==Constant.CR){ copy(buf, start,v_buf,v_pos,end-start); v_pos+=(pos-start); v_len+=(end-start); quit=true; break; }else if(buf[pos]==Constant.HT||buf[pos]==Constant.SP){ skipSpace(); continue; } end=pos; pos++; //判断是否用完 if(pos>=lastValid){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); start=pos=end=0; fill(); } } try { request.setHttpVersion(new String(v_buf,0,v_len,"UTF-8")); } catch (UnsupportedEncodingException e) { System.out.println("set HttpVersion failed"); throw new RuntimeException(e); } } } public void parseRequestHeaders(){ while(parseRequestHeader()){ } } private boolean parseRequestHeader(){ boolean quit=true; skipSpace(); //Method byte[] v_buf=new byte[1024]; int v_pos=0; int v_len=0; start=pos; //name HttpHeader httpHeader=null; while(true){ if(buf[pos]==Constant.COLON){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); break; } end=pos; pos++; //判断是否用完 if(pos>=lastValid){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); start=pos=end=0; fill(); } } try { httpHeader=HttpHeader.addHeaderName(new String(v_buf,0,v_len,"UTF-8")); } catch (UnsupportedEncodingException e1) { return false; } //Value v_buf=new byte[1024]; v_pos=0; skipSpace(); start=pos; v_len=0; while(true){ if(buf[pos]==Constant.LF||buf[end]==Constant.CR){ copy(buf, start,v_buf,v_pos,end-start); v_pos+=(pos-start); v_len+=(end-start); break; }else if(buf[pos]==Constant.HT||buf[pos]==Constant.SP){ skipSpace(); continue; } end=pos; pos++; //判断是否用完 if(pos>=lastValid){ copy(buf, start,v_buf,v_pos,pos-start); v_pos+=(pos-start); v_len+=(pos-start); start=pos=end=0; fill(); } } try { httpHeader.setValue(new String(v_buf,0,v_len,"UTF-8")); } catch (UnsupportedEncodingException e) { System.out.println("set HttpVersion failed"); throw new RuntimeException(e); } request.addHeader(httpHeader); //是否完成 if(pos>=lastValid){ start=pos=end=0; fill(); } if(buf[pos+1]==Constant.CR||buf[pos+2]==Constant.LF){ quit=false; pos+=3; } return quit; } public void parseRequestBody(){ if(pos<=lastValid){ byte[] body=new byte[1024]; copy(buf, pos,body,0,lastValid-pos+1); while(fill(buf, 0, capacity)){ copy(buf, 0,body,0,lastValid+1); } request.setBody(body); } } public InputStream getSource() { return source; } public void setSource(InputStream source) { this.source = source; } public Request getRequest() { return request; } public void setRequest(Request request) { this.request = request; } }
HttpOperator 用来来解析http协议的一个类,其中三个关键方法:parseRequestLine 请求行的解析,parseRequestHeaders 请求头解析,parseRequestBody请求包体解析
而解析后的内容用Request来封装
import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * 所获得的请求 * @author Mic * */ public class Request implements Serializable{ //请求方法 private String method; //协议版本 private String httpVersion; //uri private String uri; //域头 private List<HttpHeader> httpheaders; //body private byte[] body; public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String getHttpVersion() { return httpVersion; } public void setHttpVersion(String httpVersion) { this.httpVersion = httpVersion; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public List<HttpHeader> getHttpheaders() { return httpheaders; } public void setHttpheaders(List<HttpHeader> httpheaders) { this.httpheaders = httpheaders; } public byte[] getBody() { return body; } public void setBody(byte[] body) { this.body = body; } public void addHeader(HttpHeader header){ if(httpheaders==null) httpheaders=new ArrayList<HttpHeader>(); httpheaders.add(header); } public void addHeader(String name,Object value){ if(httpheaders==null) httpheaders=new ArrayList<HttpHeader>(); httpheaders.add(new HttpHeader(name,value)); } }
下面是其他的一些附加类
public class Constant { /** * CRLF. */ public final static String CRLF="\r\n"; /** * CR. */ public final static byte CR=(byte)'\r'; /** * LF */ public final static byte LF=(byte) '\n'; /** * SP. */ public final static byte SP=(byte) ' '; /** * HT. */ public final static byte HT=(byte) '\t'; /** * COLON. */ public final static byte COLON=(byte) ':'; /** * SEMI_COLON */ public final static byte SEMI_COLON=(byte) ';'; /** * 'A'. */ public static final byte A = (byte) 'A'; /** * 'a'. */ public static final byte a = (byte) 'a'; /** * 'Z'. */ public static final byte Z = (byte) 'Z';
public class HttpHeader { private String name;//域头名 private Object value;//域头值 public String getName() { return name; } public HttpHeader(String name, Object value) { super(); this.name = name; this.value = value; } public HttpHeader(String name) { super(); this.name = name; } public void setName(String name) { this.name = name; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public static HttpHeader addHeaderName(String name){ return new HttpHeader(name); } @Override public String toString() { return "HttpHeader [name=" + name + ", value=" + value + "]"; } }
通过上述类我做了一段测试代码如下:
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.List; import org.junit.Before; import org.junit.Test; public class HttpOperatorTest { HttpOperator operator; @Before public void setup() throws FileNotFoundException{ operator=new HttpOperator(1024); FileInputStream fis=new FileInputStream(new File(System.getProperty("user.dir"),"resource/httpRequest.txt")); operator.setSource(fis); } @Test public void test() { operator.parseRequestLine(); Request request=operator.getRequest(); System.out.println("Method:"+request.getMethod()); System.out.println("URI:"+request.getUri()); System.out.println("HttpVersion:"+request.getHttpVersion()); System.out.println("=====================parseHeaders====="); operator.parseRequestHeaders(); List<HttpHeader> httpHeaders=request.getHttpheaders(); if(httpHeaders!=null&&! httpHeaders.isEmpty()){ for(HttpHeader header:httpHeaders) System.out.println(header.getName()+":"+header.getValue()); } operator.parseRequestBody(); System.out.println("=====================parseBody====="); System.out.println(Arrays.toString(request.getBody())); } }
测试结果如下:
测试结果 写道
Method:GET
URI:/doaction?p=123&k=3343
HttpVersion:HTTP/1.1
=====================parseHeaders=====
Host:localhost:12345
Connection:keep-alive
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie:name=jackey;
=====================parseBody=====
null
URI:/doaction?p=123&k=3343
HttpVersion:HTTP/1.1
=====================parseHeaders=====
Host:localhost:12345
Connection:keep-alive
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie:name=jackey;
=====================parseBody=====
null
相关推荐
**HTTP协议解析** HTTP(Hypertext Transfer Protocol)超文本传输协议是互联网上应用最广泛的一种网络协议。它是Web浏览器和服务器之间通信的基础,用于在万维网上传输数据。HTTP协议是基于TCP/IP协议之上的应用层...
本主题将深入解析HTTP协议,包括GET和POST两种主要的请求方法。 首先,HTTP(超文本传输协议)基于TCP/IP协议栈,工作在应用层。它的基本工作流程是客户端向服务器发送一个请求,请求中包含要执行的动作和所需资源...
**HTTP协议解析器详解** HTTP(HyperText Transfer Protocol)协议是互联网上应用最为广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器的传输协议。它是一个基于请求与响应模型的、无状态的、应用层...
在这个“http协议解析软件C源码”中,我们主要可以学习以下几个关键知识点: 1. **HTTP协议基础**:理解HTTP的基本工作原理,包括请求方法(GET、POST等)、状态码(200、400、500等)、头信息(如User-Agent、...
《全面解析HTTP协议》 HTTP(Hypertext Transfer Protocol)协议是互联网上应用最广泛的一种网络协议,用于在客户端和服务器之间传输超文本信息。它最初设计时是为了解决分布式、合作式的多媒体信息系统的需求,...
HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,用于从万维网服务器传输超媒体文档至客户端。当涉及到文件上传时,HTTP 协议提供了一种方法,允许用户通过Web浏览器将文件从本地系统传送到远程服务器...
HTTP协议的解析涉及到URL解码、编码,状态码的处理,请求头和响应头的理解,以及数据的序列化和反序列化。在Java中,这些可以通过各种库或者自定义解析逻辑来实现。例如,对于JSON格式的数据,可以使用Jackson或Gson...
- **无状态**:HTTP协议本身是无状态的,即每次请求都是独立的,不保存历史信息。 - **简单**:HTTP的设计简洁明了,易于实现。 - **可扩展性**:可以通过添加新的字段来扩展协议的功能。 - **支持多种媒体类型**:...
HTTP协议的工作原理: 1. 请求过程:当用户在浏览器中输入URL并按下回车键时,浏览器作为客户端(Client)构造一个HTTP请求报文,包括方法(GET、POST等)、URL、协议版本、头部信息和请求主体(如果有的话)。然后...
在协议解析的上下文中,ASCII(美国标准信息交换代码)通常是指纯文本文件,它使用7位的ASCII码来表示字符,是网络通信中最基础的数据形式之一。 协议解析工具的核心功能包括: 1. **捕获网络流量**:工具通过监听...
HTML文档通过HTTP协议在浏览器和服务器之间传递,浏览器解析这些文档并呈现给用户。 在实际应用中,HTTP不仅用于Web浏览,还被广泛应用于其他服务,如API接口、文件下载、流媒体等。随着互联网的发展,HTTP协议不断...
本文将深入探讨基于HTTP协议的自定义协议封装,特别是在使用XML作为数据载体时如何进行设计和实现。HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,它允许客户端(如浏览器)和服务器之间交换数据。...
1.网页打不开的post不了,不存在的属性post不了,属性不区分大小写 2.post模式下内容格式要对,=赋值不能少 3.get模式下url=不能少 4.header 200表示响应成功,post 的内容要用web services readpostdata,两个VI...
### 超文本传输协议(HTTP)实验报告关键...通过这些实验和分析,学生不仅能够深入理解HTTP协议的核心概念和技术细节,还能掌握如何在实际网络环境中应用这些知识,为进一步学习高级网络技术和网络安全打下坚实的基础。
6. **HTTP协议解析**:HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于客户端(浏览器)和服务器之间的通信。解析HTTP协议涉及理解请求和响应的结构、状态码、头信息等,这对于开发Web应用、网络...
《C语言实现HTTP解析器详解》 ...提供了一个用C语言实现的HTTP解析器,适用于开发需要处理HTTP协议的系统。通过深入理解和使用这个解析器,开发者可以更好地驾驭HTTP通信,提升应用系统的稳定性和效率。
在IT行业中,尤其是在软件开发领域,使用HTTP协议与Web服务进行通信是常见的操作。本教程主要探讨如何在C++环境下,利用Wininet库通过HTTP GET和POST方法与WebService交互,并解析返回的JSON数据。让我们深入了解...
在协议解析中,这可能用于显示和处理协议中的文本数据,尤其是涉及多语言或特殊字符的情况。 3. 八学研究协会解mavlink.exe:这可能是一个专门用来解析Mavlink协议的工具,由"八学研究协会"开发。Mavlink是一种轻量...
- **HTTPS**:为了提高安全性,HTTP协议可以通过加入SSL/TLS加密层升级为HTTPS协议,这样可以保护数据的完整性和机密性,防止中间人攻击。 #### 七、HTTP与其他网络协议的关系 尽管TCP/IP协议是互联网上最常用的...
通过这种方式,Winpcap结合对TCP和HTTP协议的理解,可以帮助我们深入洞察网络流量,对HTTP应用的行为进行监控、调试或分析。对于网络开发者、安全专家和系统管理员来说,这是一项非常有价值的技能。在实际操作中,...