Http协议

http协议

1 uri uniform resource identifider,统一资源标识符,用来唯一的标识一个资源

访问资源的命名机制 + 存放资源的主机名 + 资源本身的名称(路径) 着重强调于资源

URL locator, 一种具体的uri,他用来标示一个资源,还指明了如何locate这个资源。

协议 + IP + 资源的具体地址,强调的是路径

特点 : 简单快速 ,无连接(每次连接只处理一个请求,server 端 response 之后就会断开链接)

无状态:对已经处理的事务没有记忆的,后续如果继续处理网络请求的话,需要重新request。

Request Header

Referer

当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。

If-Modified-Since

作用: 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中.

例如:Mon, 17 Aug 2015 12:03:33 GMT

If-None-Match

作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag.  使用这样的机制将提高网站的性能

例如: If-None-Match: W/"3119-1437038474000"

Response

http状态码

200 - 请求成功

301 - 资源(网页等)被永久转移到其它URL

404 - 请求的资源(网页等)不存在

500 - 内部服务器错误

Connection:连接方式。值有keep-alive和close

ETag:(Entity-Tag的缩写)资源的一个标识,类似于key-value pair(键值对)中的key。ETag通常用于校验一个资源实体有没有被修改过。在数据缓存和PUT方法更新资源时候有用处。例如:ETag: “737060cd8c284d8af7ad3082f209582d”

Expires:告诉客户端该响应数据会在指定的时间过期,通常用于给客户端缓存作为参考。例如:Expires: Thu, 01 Dec 1994 16:00:00 GMT

Last-Modified:客户端所请求的资源的最后修改时间。

http1.0/1.1

基于tcp协议,tcp协议建立连接需要有三次握手,断开链接时需要4次挥手

1.1 长连接(Persistent Connection)

       HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。

1.2 节约带宽

       HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。

1.3 HOST域

       在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。

1.4缓存处理

       在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

Get post

Cookie/Session

 首先一种场景, 在一个网站上面, 我发起一次请求,那服务器怎么知道我是谁?是谁发起的这次请求呢,  HTTP协议是无状态的协议, 浏览器的每一次请求,服务器都当做一次新请求, 但是在实际应用中我们需要知道这个请求来自于谁,需要查找哪些信息返回给访问者,

这个时候就引入了COOKIE机制, COOKIE机制是什么呢? 其实就是服务器给客户端返回数据的时候,中间加了一个标识, 然后客户端再次请求数据的时候,数据中带上这个标识, 那么服务器接收到请求消息时就知道这个请求来自于谁了(相当于服务器接收到请求时,如果没有带识别码,生成一个识别码给客户端, 如果有识别码,就把这个识别码需要的对应内容返回给客户端)

cookie保存在客户端,比较不安全;session保存在服务器端,比较安全。

cookie目的可以跟踪会话,也可以保存用户喜好或者保存用户名密码,session用来跟踪会话。

建议用户名,密码保存在session,其它信息可保存在cookie。

1. cookie的工作机制

1、服务器向客户端响应请求的时候,会在响应头中设置set-cookie的值,其值的格式通常是name = value的格式

2、浏览器将 cookie 保存下来

3、每次请求浏览器都会自动将 cookie 发向服务器

4、cookie最初是在客户端用于存储会话信息的。

2. session的工作机制

1、当客户端第一次请求session对象时,服务器会创建一个session,并通过特殊算法算出一个session的ID,用来标识该session对象,然后将这个session序列放置到set-cookie中发送给浏览器

2、浏览器下次发请求的时候,这个sessionID会被放置在请求头中,和cookie一起发送回来

3、服务器再通过内存中保存的sessionID跟cookie中保存的sessionID进行比较,并根据ID在内存中找到之前创建的session对象,提供给请求使用,也就是服务器会通过session保存一个状态记录,浏览器会通过cookie保存状态记录,服务器通过两者的对比实现跟踪状态,这样的做,也极大的避免了cookie被篡改而带来的安全性问题

4、由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面

https

|

|

HTTPS是身披SSL外壳的HTTP。通过在tcp和http之间加入tls(transport layer security)来加密,HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。

PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。

Tls 协议 之上的握手协议,加密协议,警告协议 加上http 协议 组成了https协议。

Https = http + 加密+ 认证 + 数据的完整性保护。

tls握手阶段是非对称加密,数据传输阶段是对称加密

加密

密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥

对称加密:加密数据用的密钥,跟解密数据用的密钥时一样的 des aes

不对称加密: 私有密钥:一方保管,公有密钥:双方共有

RSA加密过程:

1 服务端会生产一对密钥,一个私钥仅顿房在server端,仅自己知道

2 另一个是公钥要,公钥可以自由发布供任何人使用,发送给client

3 client 使用公钥加密明文传输给server

4 server使用私钥解密密文得到明文

发送密文的一方,先获得对方的共有密钥,通过加密算法进行加密,对方收到加密信息,是由自己的私有密钥进行解密。

数字证书CA:包含了很多真实服务器的公钥

是互联网通讯中标志通讯各方身份信息的一串数字。

为什么需要证书:1 对请求方来说,怎么确定自己得到的公钥是它期望的目标主机发送过来的,而没有经过第三方篡改过,需要权威机构颁发证书

数字签名:1用于验证传输的内容是不是真实的server发送的数据,2 发送的数据有没有被篡改过。是非对称加密的一种应用场景,不过他是法诺来用私钥加密,公钥解密

数字签名过程:

|

|

tls握手过程

|

|

Tcp

arp协议:可以从IP地址得到MAC地址

DNS:将主机名和域名转化成IP

okHttp

|

implementation 'com.squareup.okhttp3:okhttp:3.8.1'

implementation 'com.squareup.okio:okio:1.7.0'

OkHttpClient client = new OkHttpClient().newBuilder().readTimeout(5, TimeUnit.SECONDS).build();

public void sysRequest() {

    Request request = new Request.Builder().url("http://www.baidu.com").get().build();

    Call call = client.newCall(request);//Call 相当于 request 和 response 的桥梁


    Response response = call.execute();// 同步方法,Call 是个借口,实际调用的是RealCall的方法

            response.body();

}

public void asysRequest () {

    Request request = new Request.Builder().url("http://www.baidu.com").get().build();

    Call call = client.newCall(request);

    call.enqueue(new Callback() {

        @Override

        public void onFailure(Call call, IOException e) {//都是在子线程中执行的

        }

        @Override

        public void onResponse(Call call, Response response) throws IOException {

            response.body();

        }

    });

}

方法小结:

1 创建OkHttpClient 和 Request对象

2 将Request封装成call对象 // client的newcall

3 调用call的execute/enqueue发送同步/异步请求。// 当前线程如果发送请求后,就会进入阻塞状态,知道收到响应。

同步请求源码分析:

public Builder newBuilder() {

  return new Builder(this);

}

public static final class Builder {

  Dispatcher dispatcher;

  @Nullable Proxy proxy;

  List<Protocol> protocols;

  List<ConnectionSpec> connectionSpecs;

  final List<Interceptor> interceptors = new ArrayList<>();

  final List<Interceptor> networkInterceptors = new ArrayList<>();

  EventListener.Factory eventListenerFactory;

  ProxySelector proxySelector;

  CookieJar cookieJar;

  @Nullable Cache cache;

  @Nullable InternalCache internalCache;

  SocketFactory socketFactory;

  @Nullable SSLSocketFactory sslSocketFactory;

  @Nullable CertificateChainCleaner certificateChainCleaner;

  HostnameVerifier hostnameVerifier;

  CertificatePinner certificatePinner;

  Authenticator proxyAuthenticator;

  Authenticator authenticator;

  ConnectionPool connectionPool;

  Dns dns;

  boolean followSslRedirects;

  boolean followRedirects;

  boolean retryOnConnectionFailure;

  int connectTimeout;

  int readTimeout;

  int writeTimeout;

  int pingInterval;

Requst build方法

public Builder() {

  this.method = "GET";

  this.headers = new Headers.Builder();

}

Builder(Request request) {

  this.url = request.url;

  this.method = request.method;

  this.body = request.body;

  this.tag = request.tag;

  this.headers = request.headers.newBuilder();

}

RealCall的构造方法中,构造出重定向拦截器

RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {

  final EventListener.Factory eventListenerFactory = client.eventListenerFactory();

  this.client = client;

  this.originalRequest = originalRequest;

  this.forWebSocket = forWebSocket;

  this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);

  // TODO(jwilson): this is unsafe publication and not threadsafe.

  this.eventListener = eventListenerFactory.create(this);

}

execute方法

@Override public Response execute() throws IOException {

  synchronized (this) {

    if (executed) throw new IllegalStateException("Already Executed");

    executed = true;

  }

  captureCallStackTrace();

  try {

    client.dispatcher().executed(this);

    Response result = getResponseWithInterceptorChain();

    if (result == null) throw new IOException("Canceled");

    return result;

  } finally {

    client.dispatcher().finished(this);

  }

}

synchronized void executed(RealCall call) {

  runningSyncCalls.add(call);

}

Response getResponseWithInterceptorChain() throws IOException {

  // Build a full stack of interceptors.

  List<Interceptor> interceptors = new ArrayList<>();

  interceptors.addAll(client.interceptors());

  interceptors.add(retryAndFollowUpInterceptor);

  interceptors.add(new BridgeInterceptor(client.cookieJar()));

  interceptors.add(new CacheInterceptor(client.internalCache()));

  interceptors.add(new ConnectInterceptor(client));

  if (!forWebSocket) {

    interceptors.addAll(client.networkInterceptors());

  }

  interceptors.add(new CallServerInterceptor(forWebSocket));

  Interceptor.Chain chain = new RealInterceptorChain(

      interceptors, null, null, null, 0, originalRequest);

  return chain.proceed(originalRequest);

}

Enqueue 方法

@Override public void enqueue(Callback responseCallback) {

  synchronized (this) {

    if (executed) throw new IllegalStateException("Already Executed");

    executed = true;

  }

  captureCallStackTrace();

  client.dispatcher().enqueue(new AsyncCall(responseCallback));

}

synchronized void enqueue(AsyncCall call) {

  if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {

    runningAsyncCalls.add(call);

    executorService().execute(call);

  } else {

    readyAsyncCalls.add(call);

  }

}

// 1 判断当前call 是否执行过了

// 2 封装成一个AsyncCall 对象

// 3 client。dispather。enqueue

抓包

charles/postman

// tcpflow -cp -i eth0 host 10.227.160.34  ?????

1 手机的网络需要和电脑的网络一样: 手机wifi 高级设置代理: 主机名${ifconfig} 端口:8888

2 charles  proxy--proxy settings --http proxy 端口:8888

Postman new request 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343