搜索词>>https 耗时0.0020
  • HTTP协议2.0_HTTP2.0新特性

    HTTP协议2.0,HTTP 2.0如何升级_HTTP2.0新特性_HTTP2.0详解。<h2>引用</h2>   本文主要讲述HTTP协议2.0版本,以及<a rel="external nofollow" target="_blank" id="http2.0" name="http2.0">HTTP协议2.0</a>的新特性说明 <h2>一.开篇HTTP发展的心路历程</h2> <br /> <img alt="开篇HTTP发展的心路历程,1" class="img-thumbnail" src="/assist/images/blog/76f5c3db6d6843809b1f42d62f0f8a6d.png" /><br /> 上图:连接无法复用<br /> <img alt="HTTP 协议 订单流程" class="img-thumbnail" src="/assist/images/blog/e77a5ee7ca904be584f248722782ccfb.png" /><br /> 上图:设置Connection:Keep-Alive,保持连接在一段时间内不断开。<br /> <img alt="HTTP协议多个订单" class="img-thumbnail" src="/assist/images/blog/f260aa472f694465ba83da7498272ade.png" /><br /> 上图:HTTPpipelining:建立多个连接<br /> <img alt="HTTP多路复用" class="img-thumbnail" src="/assist/images/blog/af6c10458a3146fdb9bc4b8b0254deed.png" /><br /> 上图:多路复用 <h2>二.先对HTTP协议进行简单介绍</h2> <p>   1. HTTP协议 :Hyper Text Transfer Protocol(超文本传输协议),是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。</p> <p>    2. HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。</p> <p>   3. HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。</p> <p>   4. HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。<br /> <img alt="Http协议客户端和服务端" class="img-thumbnail" src="/assist/images/blog/bd2f47f787154d74a164ca4cdc3cb381.png" /></p> <h2>三.HTTP 协议的版本</h2> <ul> <li>HTTP 0.9作为HTTP协议的第一个版本。是非常弱的。请求(Request)只有一行,比如: GET www.leautolink.com</li> <li>HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上。</li> <li>HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。</li> </ul> <img alt="HTTP协议版本" class="img-thumbnail" src="/assist/images/blog/be03a1e810d5455483dd40e6c644428e.png" /><br />   <p><strong>HTTP 1.1 做了哪些升级:</strong></p> <p> </p> <ul> <li> <p><strong>缓存处理</strong>,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。</p> </li> <li> <p><strong>带宽优化及网络连接的使用</strong>,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。</p> </li> <li> <p><strong>错误通知的管理</strong>,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。</p> </li> <li> <p><strong>Host头处理</strong>,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。</p> </li> <li> <p><strong>长连接</strong>,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。</p> </li> </ul> <p><strong>如何建立连接(三次握手)</strong></p> <p>    HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。</p> <ul> <li> <p><strong>第一次</strong><strong>握手:</strong>建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。</p> </li> <li> <p><strong>第二次握手:</strong>服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;</p> </li> <li> <p><strong>第三次握手:</strong>客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。</p> </li> </ul> <p><strong>完成三次握手,客户端与服务器开始传送数据。</strong></p> <img alt="HTTP协议三次握手流程图" class="img-thumbnail" src="/assist/images/blog/5891e7762d3843e8aaf04edf552f6930.png" /> <p><strong>如何关闭连接(四次挥手):</strong></p> <p> </p> <p>    由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。</p> <p> </p> <p>     TCP的连接的拆除需要发送四个包,因此称为<strong>四次挥手(four-way handshake)</strong>。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。</p> <p> </p> <ol> <li> <p>客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。 </p> </li> <li> <p>服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。 </p> </li> <li> <p>服务器B关闭与客户端A的连接,发送一个FIN给客户端A。 </p> </li> <li> <p>客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。 <br /> <img alt="HTTP 第三次和第四次握手" class="img-thumbnail" src="/assist/images/blog/7314195885b54567bac1275375c419fe.png" /><br />  </p> </li> </ol> <p><strong>浏览器阻塞(HOL blocking):</strong></p> <p>   浏览器对于同一个域名,一般PC端浏览器会针对单个域名的server同时建立6~8个连接,手机端的连接数则一般控制在4~6个(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。</p> <h2>三.在讲HTTP/2之前我们先来说说SPDY</h2> <p>  SPDY协议是Google提出的基于传输控制协议(TCP)的应用层协议,通过压缩、多路复用和优先级来缩短加载时间。该协议是一种更加快速的内容传输协议,于2009 年年中发布。</p> <p>  GoogleChrome、MozillaFirefox以及Opera已默认开启SPDY。Google曾经称它的测试显示,页面载入提高了一倍。该协议是一种更加快速的内容传输协议。</p> <p><strong>SPDY协议设定的目标</strong></p> <p>    1. 页面加载时间(PLT,Page • Load Time)降低 50%;</p> <p>    2. 无需网站作者修改任何内容;</p> <p>    3. 最小化配置复杂度,无需变更网络基础设施;</p> <p>注:为了达到降低50% 页面加载时间的目标,SPDY 引入了一个新的二进制分帧数据层,以实现多向请求和响应、优先次序、最小化及消除不必要的网络延迟,目的是更有效地利用底层TCP 连接;</p> <h2>四.HTTP/2:SPDY的升级版</h2> <ul> <li> <p>HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了议事日程,吸取SPDY 的经验教训,并在此基础上制定官方标准。</p> </li> <li> <p>HTTP/2 的主要目标是改进传输性能,更有效地利用网络资源,实现低延迟和高吞吐量。从另一方面看,HTTP 的高层协议语义并不会因为这次版本升级而受影响。所有HTTP 首部、值,以及它们的使用场景都不会变。</p> </li> <li> <p>HTTP/2 致力于突破上一代标准众所周知的性能限制,但它也是对之前1.x 标准的扩展,而非替代。之所以要递增一个大版本到2.0,主要是因为它改变了客户端与服务器之间交换数据的方式</p> </li> </ul> <p><strong>HTTP/2 是如何提高效率呢?</strong></p> <p><strong>  二进制分帧:HTTP 2.0 的所有帧都采用二进制编码</strong></p> <ul> <li> <p><strong>帧</strong>:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。</p> </li> <li> <p><strong>消息</strong>:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。</p> </li> <li> <p><strong>流</strong>:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2…N);</p> </li> </ul> <img alt="HTTP 2.0连接" class="img-thumbnail" src="/assist/images/blog/f3e1405c2a1f43c3a8ef78325d360f3b.png" /> <p><strong>多路复用 (Multiplexing)</strong></p> <p>    多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。有了新的分帧机制后,HTTP/2 不再依赖多个TCP 连接去实现多流并行了。每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级。最后再在另一端把它们重新组合起来。HTTP 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(<strong>每个域名一个连接</strong>)即可。 </p> <p> </p> <p><strong>请求优先级</strong></p> <ul> <li> <p>把HTTP 消息分解为很多独立的帧之后,就可以通过优化这些帧的交错和传输顺序,每个流都可以带有一个31 比特的优先值:0 表示最高优先级;2的31次方-1 表示最低优先级。</p> </li> <li> <p>服务器可以根据流的优先级,控制资源分配(CPU、内存、带宽),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。</p> </li> <li> <p>HTTP 2.0 一举解决了所有这些低效的问题:浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不必排队了,既节省了时间,也最大限度地利用了每个连接。</p> </li> </ul> <p> </p> <p><strong>header压缩</strong></p> <p>    HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP/2使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。</p> <p> </p> <p><strong>服务端推送</strong></p> <ul> <li> <p>服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确地请求。</p> </li> <li> <p>HTTP 2.0 连接后,客户端与服务器交换SETTINGS 帧,借此可以限定双向并发的流的最大数量。</p> </li> <li> <p>所有推送的资源都遵守同源策略。换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方确认才行。</p> </li> <li> <p>服务器必须遵循请求- 响应的循环,只能借着对请求的响应推送资源</p> </li> </ul> <p> </p> <p><strong>服务器推送到底是什么?</strong></p> <p>    服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。</p> <p> </p> <p>普通的客户端请求过程:<br /> <img alt="普通客户端请求HTTP协议过程" class="img-thumbnail" src="/assist/images/blog/98d6549c4dfe4180a51242a61353286a.png" /><br />  </p> 服务端推送的过程:<br /> <img alt="服务端推送的过程" class="img-thumbnail" src="/assist/images/blog/b1ca4e63108a42b8a7f49454b948416f.png" /> <p><strong>HTTP/2的多路复用和HTTP1.1中的长连接复用有什么区别?</strong></p> <ul> <li> <p>HTTP/1.0 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;</p> </li> <li> <p>HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;</p> </li> <li> <p>HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;<br /> <img alt="HTTP" class="img-thumbnail" src="/assist/images/blog/ab81f47df21b4aa7941fec0556dcb814.png" /><br />  </p> </li> </ul> <h2>五.如何应用到自己的项目里</h2> <p>  现有的任何网站和应用,无需做任何修改都可以在HTTP 2.0 上跑起来。不用为了利用HTTP 2.0 的好处而修改标记。HTTP 服务器必须运行HTTP 2.0 协议,但大部分用户都不会因此而受到影响。</p> <p>  如果你使用NGINX,只要在配置文件中启动相应的协议就可以了,可以参考NGINX白皮书,NGINX配置HTTP2.0官方指南。</p> <p>  使用了HTTP2.0那么,原本的HTTP1.x怎么办,这个问题其实不用担心,HTTP2.0完全兼容HTTP1.x的语义,对于不支持HTTP2.0的浏览器,NGINX会自动向下兼容的。</p>
  • tomcat如何配置SSL或者说HTTPS

    tomcat如何配置SSL或者说HTTPS,tomcat,https,SSL<h2>一、SSL是什么?HTTPS是什么?为何需要使用SSL</h2>   安全套接字层(SSL)是一种安全传输协议,用于在Internet上使用加密方法进行通信。SSL协议的主要目的是保证没有人能够篡改浏览器和web应用程序部署的服务器之间的通信。安全通信的另一个目的是根据SSL信息对服务器及其所有者进行身份验证,这样用户就可以确定正在访问的服务器是它正在访问的服务器。在常见的SSL场景中,当用户第一次访问web服务器时,服务器将其SSL证书或公钥发送给客户机。SSL证书包含关于服务器的信息,它的所有者、公司和它的有效期。如果用户不相信证书的真实性,就可以拒绝证书,从而有效地终止连接。如果用户接受该证书,证书本身就存储在浏览器中,并用于启动与发布服务器的安全连接。<br /> <br />    HTTP协议上的SSL协议通信称为HTTPS(安全HTTP)。例如,使用SSL加密连接的web站点在浏览器的地址栏中显示https作为协议名称。称为证书颁发机构(CA)的组织可以对SSL证书的详细信息进行身份验证,因此,如果用户信任CA,他们可以确保安全的web站点得到了认证,并且其详细信息是正确的。有许多ca可以颁发经过认证的SSL证书。现代浏览器自动识别最大和最知名的ca,并允许连接到提供这些组织认证的SSL证书的站点。如果SSL证书不是由CA认证的,或者由CA认证,但是没有被用户的浏览器识别,那么用户将会出现一个警告屏幕,在那里他或她可以决定是否信任该证书。 <p>tomcat配置SSL步骤包含</p> <p>1)生成密钥存储库</p> <p>2)在server.xml中更新连接器</p> <p>3)更新应用程序的web。xml与安全的网址<br />  </p> <h2>二、生成密钥对</h2>   SSL证书是JKS文件。JKS的格式代表Java密钥库,这是一个特定于Java的密钥存储库格式。JKS密钥库可以使用keytool实用程序创建和操作,从版本1.4发布它作为Java SDK的一部分。我们将使用Keytool创建一个自签名的SSL证书,它位于javahome/bin/目录中。 <pre> <code>//GOTO JAVA HOME c:\ > cd %JAVA_HOME%/bin //TYPE GENKEY COMMAND C:\BAML\DFCCUI\installs\jdk1.6\bin>keytool -genkey -alias tomcat -keyalg RSA Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: lokesh What is the name of your organizational unit? [Unknown]: boa What is the name of your organization? [Unknown]: boa What is the name of your City or Locality? [Unknown]: delhi What is the name of your State or Province? [Unknown]: delhi What is the two-letter country code for this unit? [Unknown]: 91 Is CN=lokesh, OU=boa, O=boa, L=delhi, ST=delhi, C=91 correct? [no]: yes Enter key password for <tomcat> (RETURN if same as keystore password): Re-enter new password: C:\installs\jdk1.6\bin></code></pre> 将会创建一个<code>.keystore</code> 文件在你的用户主目录中. 在windows 7系统中, 存放位置 <code>C:\Users\lokesh</code>.<br /> <em>也可以通过参数-keystore d:/leadsec指定创建的文件存放路径</em> <pre> <code>keytool -genkey -alias tomcat -keyalg RSA -keystore d:/mySSLKeystore</code></pre> <br /> <strong>提示:</strong><em>您只能为一个IP地址提供一个SSL证书。如果您在同一个IP上驻留多个域,那么只有一个主机名可以有一个与它的域名匹配的有效的SSL证书。如果您尝试在同一IP上使用SSL,那么浏览器将显示一个警告,即域名与证书不匹配。这是一个已知的SSL限制,因为SSL协议握手必须在从HTTP请求中提取主机名之前发生。</em> <h2>三、更新server.xml配置文件中的Connector</h2> <br /> Tomcat 能够使用两种 SSL 实现: <ul> <li>JSSE 实现,它是Java 运行时(从 1.4 版本起)的一部分。</li> <li>APR 实现,默认使用 OpenSSL 引擎。</li> </ul> 3.1JSSE 实现,它是Java 运行时(从 1.4 版本起)的一部分。 <p>打开你的tomcat安装位置,进入conf目录。在这个目录中你可以找到server.xml配置文件。打开这个配置文件并且找到下面的声明:<br />  </p> <pre> <code class="language-xml"><!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> --></code></pre> 修改这个信息,取消注释。并且配置刚才生成的密码和秘钥的路径。 <pre> <code class="language-xml"><Connector SSLEnabled="true" acceptCount="100" clientAuth="false" disableUploadTimeout="true" enableLookups="false" maxThreads="25" port="8443" keystoreFile="C:/Users/lokesh/.keystore" keystorePass="password" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS" /> </code></pre> 完成之后看看应用的变化。<br /> 配置ssl后需要将之前的8080注释掉 <pre> <code class="language-xml"> <!-- <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> --></code></pre> <br /> <br /> 访问https的地址为:http://ip:8443/projectname<br /> <strong><span style="color:#cc0000">注意:</span>直接输入ip:8443/projectname浏览器会默认http协议,必须手动输入https://</strong><br /> <br /> 3.2APR 实现,默认使用 OpenSSL 引擎。<br /> 指定 APR 连接器(APR 库必须可用),则使用: <pre> <code class="language-xml"><!-- Define a HTTP/1.1 Connector on port 8443, APR implementation --> <Connector protocol="org.apache.coyote.http11.Http11AprProtocol" port="8443" .../></code></pre> 如果使用 APR,则会出现一个选项,从而可以配置另一种 OpenSSL 引擎。 <pre> <code class="language-xml"><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="someengine" SSLRandomSeed="somedevice" /></code></pre> 默认值为: <pre> <code class="language-xml"><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" SSLRandomSeed="builtin" /></code></pre> 所以要想使用 APR 实现,一定要确保 <code>SSLEngine</code> 属性值不能为 <code>off</code>。该属性值默认为 <code>on</code>,如果指定的是其他值,它也会成为一个有效的引擎名称。<br /> 最后一步是在 <code>$CATALINA_BASE/conf/server.xml</code> 中配置连接器,<code>$CATALINA_BASE</code> 表示的是 Tomcat 实例的基本目录。Tomcat 安装的默认 <code>server.xml</code> 文件中包含一个用于 SSL 连接器的 <code><Connector></code> 元素的范例。APR 连接器会使用很多不同的属性来设置 SSL,特别是密钥和证书。 APR 配置范例如下: <pre> <code class="language-xml"><!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> <Connector protocol="org.apache.coyote.http11.Http11AprProtocol" port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" SSLCertificateFile="/usr/local/ssl/server.crt" SSLCertificateKeyFile="/usr/local/ssl/server.pem" SSLVerifyClient="optional" SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"/></code></pre>   <h2>四、修改应用中的web.xml配置文件使用安全URL</h2> 修改你的应用中的web.xml配置文件,如下: <pre> <code class="language-xml"><security-constraint> <web-resource-collection> <web-resource-name>application-one</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint></code></pre> <p>url模式被设置为/*因此,来自您的应用程序的任何页面/资源都是安全的(只能通过https访问)。传输保证标签被设置为机密,以确保你的应用能在SSL上运行。</p> <p>现在尝试访问该应用程序使用 <code>https://localhost:8443/application-one/</code>.这将在浏览器中显示证书信息。<br /> <img alt="证书" class="img-thumbnail" src="/assist/images/blog/9fc81441a2824b80a825bf843945352a.png" /><br /> 只有在您接受证书之后,它才会显示页面。<br /> <img alt="页面" class="img-thumbnail" src="/assist/images/blog/a92a483bfa3b46118c89af60a7af3f84.png" /><br /> 如果你没有在网络上设置“安全限制”。xml然后你将能够访问您的应用程序直接使用http://localhost:8080/application-one/.<br /> <img alt="未使用安全" class="img-thumbnail" src="/assist/images/blog/92ab402b9e65482dba2e943cfc75b226.png" /><br /> 这就是关于在tomcat服务器中实现SSL支持的简单而又重要的概念<br />  </p> <h2>五.使用场景</h2>   一定要注意的是,通常只有当 Tomcat 是独立运行的 Web 服务器时,才有必要去配置 Tomcat 以便利用加密套接字。具体细节可参看 <a href="http://tomcat.apache.org/tomcat-8.0-doc/security-howto.html" rel="external nofollow" target="_blank">Security Considerations Document</a>。当 Tomcat 以 Servlet/JSP 容器的形式在其他 Web 服务器(比如 Apache 或 Microsoft IIS)背后运行时,通常需要配置的是主 Web 服务器,用主服务器来处理与用户的 SSL 连接。主服务器一般会利用所有的 SSL 相关功能,将任何只有 Tomcat 才能处理的请求进行解密后再传给 Tomcat。同样,Tomcat 会返回明文形式的响应,这些响应在被传输到用户浏览器之前会被主服务器进行加密处理。在这种情境下,Tomcat 知道主服务器与客户端的所有通信都是通过安全连接进行的(因为应用要求),但 Tomcat 自身无法参与到加密与解密的过程中。 <h2>六.证书支持类型</h2> <p>  Tomcat 目前只能操作 <code>JKS</code>、<code>PKCS11</code>、<code>PKCS12</code> 格式的密钥存储库。<code>JKS</code> 是 Java 标准的“Java 密钥存储库”格式,是通过 <code>keytool</code> 命令行工具创建的。该工具包含在 JDK 中。<code>PKCS12</code> 格式一种互联网标准,可以通过 OpenSSL 和 Microsoft 的 Key-Manager 来。</p> <p>密钥存储库中的每一项都通过一个别名字符串来标识。尽管许多密码存储库实现都在处理别名时不区分大小写,但区分大小写的实现也是允许的。比如,<code>PKCS11</code> 规范需要别名是区分大小写的。为了避免别名大小写敏感的问题,不建议使用只有大小写不同的别名。</p> <p>为了将现有的证书导入 <code>JKS</code> 密码存储库,请查阅关于 <code>keytool</code> 的相关文档(位于 JDK 文档包里)。注意,OpenSSL 经常会在密码前加上易于理解的注释,但 <code>keytool</code> 并不支持这一点。所以如果证书里的密码数据前面有注释的话,在利用 <code>keytool</code> 导入证书前,一定要清除它们。</p> <p>要想把一个已有的由你自己的 CA 所签名的证书导入使用 OpenSSL 的 <code>PKCS12</code> 密码存储库,应该执行如下命令:</p> <pre> <code>openssl pkcs12 -export -in mycert.crt -inkey mykey.key -out mycert.p12 -name tomcat -CAfile myCA.crt -caname root -chain </code></pre>
  • nodejs中http模块使用简单demo

    nodejs中http模块使用简单demo<h2>1.编写一个见得server.js</h2> server.js内容: <pre> <code class="language-javascript"> var http = require('http') ; var server = http.createServer(function(req,res){ res.writeHeader(200,{ 'Content-Type' : 'text/plain;charset=utf-8', // 添加charset=utf-8, 'Access-Control-Allow-Origin':'*',//跨域支持 'Access-Control-Allow-Methods':'*'//跨域支持 }) ; res.end("Hello,NodeJS!") ; }) ; server.listen(8888) ; console.log("http server running on port 8888 ...") ;</code></pre> <h2>2.启动server.js</h2> <br /> cmd命令: <pre> <code>node server.js</code></pre> <h2><img alt="cmd" class="img-thumbnail" src="/assist/images/blog/302e7f1e7eb6492abf071383856352a4.png" /><br /> 3.编写一个简单的HTML,通过ajax请求访问</h2> <pre> <code class="language-html"><!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <button class="btn-test">点击请求nodejs接口</button> <script src="jquery.min.js"></script> <script type="text/javascript"> $(function(){ $('.btn-test').click(function(){ $.ajax({ url:'http://localhost:8888',//刚才的server.js提供的简单服务http接口 type:'GET', success:function(result){ alert("接口返回数据内容:"+result); } }); }); }); </script> </body> </html></code></pre> <br /> 执行结果:<br /> <img alt="node http" class="img-thumbnail" src="/assist/images/blog/ebdbf804a3194213b13610e9ff0a1cec.png" />
  • acme.sh 获取let's encrypt免费ssl证书https

    acme.sh 获取let's encrypt免费ssl证书httpsacme.sh 获取let's encrypt免费ssl证书https
  • MIME 参考手册/HTTP文件上传格式过滤

    MIME 参考手册/HTTP文件上传格式过滤MIME 参考手册/HTTP文件上传格式过滤​​​​​​​
  • HttpClient 使用SSL访问HTTPS(提高篇)

    本文将展示如何使用“接受所有”SSL支持来配置Apache HttpClient 4。目标很简单 - 使用没有有效证书的HTTPS URL。<h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>1.概述</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">本文将展示如何<strong>使用“接受所有”SSL支持</strong>来<strong>配置Apache HttpClient 4</strong>。目标很简单 - 使用没有有效证书的HTTPS URL。</span></span></span><br /> <br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2. <em>SSLPeerUnverifiedException</em></strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在没有使用<em>HttpClient</em>配置SSL的情况下,以下测试(使用HTTPS URL)将失败:</span></span></span></p> <pre> <code class="language-java">public class HttpLiveTest { @Test(expected = SSLPeerUnverifiedException.class) public void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException { DefaultHttpClient httpClient = new DefaultHttpClient(); String urlOverHttps = "https://localhost:8080/spring-security-rest-basic-auth"; HttpGet getMethod = new HttpGet(urlOverHttps); HttpResponse response = httpClient.execute(getMethod); assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">确切的失败是:</p> <pre> <code class="language-java">javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126) ...</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">该<a href="http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLPeerUnverifiedException.html" rel="external nofollow" style="box-sizing:border-box; background-color:#ffffff; color:#63b175; text-decoration:none; font-family:raleway; font-size:18px; font-style:normal; font-variant-ligatures:normal; font-variant-caps:normal; font-weight:normal; letter-spacing:normal; orphans:2; text-align:start; text-transform:none; white-space:normal; widows:2; word-spacing:0px; -webkit-text-stroke-width:0px" target="_blank" title="Java SE 7中的SSLPeerUnverifiedException javadoc"><em>javax.net.ssl.SSLPeerUnverifiedException</em>例外</a>,只要有效信任链无法为URL建立发生。<br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.配置SSL - 全部接受(HttpClient <4.3)</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">现在让我们将HTTP客户端配置为信任所有证书链,而不管它们的有效性如何:</span></span></span></p> <pre> <code class="language-java">@Test public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() throws IOException, GeneralSecurityException { TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; SSLSocketFactory sf = new SSLSocketFactory( acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 8443, sf)); ClientConnectionManager ccm = new PoolingClientConnectionManager(registry); DefaultHttpClient httpClient = new DefaultHttpClient(ccm); String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1"; HttpGet getMethod = new HttpGet(urlOverHttps); HttpResponse response = httpClient.execute(getMethod); assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">随着新的<em>TrustStrategy</em>现在<strong>覆盖标准证书验证过程</strong>(应该咨询配置的信任管理器) - 测试现在通过,<strong>客户端可以使用HTTPS URL</strong>。<br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>4. 带SSL 的Spring <em>RestTemplate</em>(HttpClient <4.3)</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">现在我们已经看到了如何配置一个支持SSL 的原始<em>HttpClient</em>,让我们来看看更高级别的客户端<em>--Spring RestTemplate</em>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">未配置SSL,以下测试将按预期失败:</span></span></span></p> <pre> <code class="language-java">@Test(expected = ResourceAccessException.class) public void whenHttpsUrlIsConsumed_thenException() { String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1"; ResponseEntity<String> response = new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">那么让我们来配置SSL:<br />  </p> <pre> <code class="language-java">import static org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.DefaultHttpClient; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.RestTemplate; ... @Test public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() throws GeneralSecurityException { HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); DefaultHttpClient httpClient = (DefaultHttpClient) requestFactory.getHttpClient(); TrustStrategy acceptingTrustStrategy = (cert, authType) -> true SSLSocketFactory sf = new SSLSocketFactory( acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager().getSchemeRegistry() .register(new Scheme("https", 8443, sf)); String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1"; ResponseEntity<String> response = new RestTemplate(requestFactory). exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">如您所见,这<strong>与我们为原始HttpClient配置SSL的方式非常相似</strong> - 我们使用SSL支持配置请求工厂,然后实例化通过此预配置工厂的模板。<br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>5.配置SSL - 全部接受(HttpClient 4.4)</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在HttpClient 4.4版本中,现在不推荐使用<em>SSLSocketFactory</em>,我们可以简单地配置我们的<em>HttpClient</em>,如下所示:</span></span></span></p> <pre> <code class="language-java">@Test public void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() throws Exception { SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, (certificate, authType) -> true).build(); CloseableHttpClient client = HttpClients.custom() .setSSLContext(sslContext) .setSSLHostnameVerifier(new NoopHostnameVerifier()) .build(); HttpGet httpGet = new HttpGet(HOST_WITH_SSL); httpGet.setHeader("Accept", "application/xml"); HttpResponse response = client.execute(httpGet); assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); }</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>6. 带SSL 的Spring <em>RestTemplate</em>(HttpClient 4.4)</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们可以用同样的方法来配置我们的<em>RestTemplate</em>:</span></span></span></p> <pre> <code class="language-java">@Test public void givenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect() throws ClientProtocolException, IOException { CloseableHttpClient httpClient = HttpClients.custom() .setSSLHostnameVerifier(new NoopHostnameVerifier()) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); ResponseEntity<String> response = new RestTemplate(requestFactory).exchange( urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); }</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>7.总结</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">本教程讨论了如何为Apache HttpClient配置SSL,以便它能够使用任何HTTPS URL,而不考虑证书。还展示了Spring <em>RestTemplate</em>的相同配置。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">然而,要理解的重要一点是,<strong>这种策略完全忽略了证书检查</strong> - 这使得它不安全,只能在有意义的地方使用。</span></span></span></p>
  • httpclient4.5使用详解 httpclient 4.5 post传递json参数

    httpclient4.5使用详解 httpclient 4.5 post传递json参数httpclient4.5使用详解 httpclient 4.5 post传递json参数 <pre> <code class="language-java">import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; /** * 工具类 httpclient4.5 * * @author xq * */ public class HttpclientUtils { /** * post请求 json参数 * * @param url * @param bodyJsonParams * @param headers * @return * @throws IOException */ public static String doPost(String url, String bodyJsonParams, Map<String, String> headers) throws IOException { HttpPost httpPost = new HttpPost(url); httpPost.addHeader("Content-Type", "application/json"); httpPost.setEntity(new StringEntity(bodyJsonParams)); if (headers != null && headers.keySet().isEmpty()) { Set<String> keySet = headers.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = headers.get(key); httpPost.addHeader(key, value); } } return execute(httpPost); } /** * post k-v参数 * * @param url * @param params * @param headers * @return * @throws IOException */ public static String doPost(String url, Map<String, String> params, Map<String, String> headers) throws IOException { HttpPost httpPost = new HttpPost(url); if (params != null && params.keySet().isEmpty()) { List<NameValuePair> list = new ArrayList<>(); Set<String> keySet = headers.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = headers.get(key); list.add(new BasicNameValuePair(key, value)); } httpPost.setEntity(new UrlEncodedFormEntity(list)); } if (headers != null && headers.keySet().isEmpty()) { Set<String> keySet = headers.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = headers.get(key); httpPost.addHeader(key, value); } } return execute(httpPost); } /** * get请求 * * @param url * @param params * @param headers * @return * @throws IOException * @throws ClientProtocolException */ public static String doGet(String url, Map<String, String> params, Map<String, String> headers) throws IOException { // 参数 StringBuilder paramsBuilder = new StringBuilder(url); if (params != null && params.keySet().isEmpty()) { if (url.indexOf("?") == -1) { paramsBuilder.append("?"); } List<NameValuePair> list = new ArrayList<>(); Set<String> keySet = headers.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = headers.get(key); list.add(new BasicNameValuePair(key, value)); } String paramsStr = EntityUtils.toString(new UrlEncodedFormEntity(list)); paramsBuilder.append(paramsStr); } HttpGet httpGet = new HttpGet(paramsBuilder.toString()); // 头 if (headers != null && headers.keySet().isEmpty()) { Set<String> keySet = headers.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = headers.get(key); httpGet.addHeader(key, value); } } return execute(httpGet); } /** * 执行请求并返回string值 * * @param httpUriRequest * @return * @throws IOException */ private static String execute(HttpUriRequest httpUriRequest) throws IOException { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { CloseableHttpResponse response = httpClient.execute(httpUriRequest); if (response.getStatusLine().getStatusCode() == 200) {// 请求成功状态 try (BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(response.getEntity().getContent()))) { String result=""; String tmp=null; while((tmp=bufferedReader.readLine())!=null){ result+=tmp; } return result; } } } return null; } } </code></pre>  
  • retrofit2使用详解之入门

    前言       在本教程中,我们将了解Retrofit 的基础知识以和创建一个android HTTP client请求REST API前言       在本教程中,我们将了解Retrofit 的基础知识以和创建一个android HTTP client请求REST API。 1. Retrofit是什么?Retrofit是一个类型安全的REST客户端,适用于android和Java开发应用。Retrofit可将HTTP 网络接口转换为Java接口。Retrofit android 版使用非常简单。它本质上允许我们将API调用视为简单的Java方法调用,因此我们只定义要访问的URL和请求/响应参数的类型作为Java类。整个网络调用+ JSON / XML解析完全由Retrofit处理(例如Gson用于JSON解析)。它允许向远程Web服务器发出同步或异步HTTP请求。2. Retrofit 安装 我们的项目中要使用Retrofit 2,我们将在构建文件中包含以下依赖项。在本教程中,我们将以JSON格式发送和接收数据,因此我们也添加了converter-gson依赖项。maven 方式:$title(pom.xml) <dependency> <groupId>com.squareup.retrofit2</groupId> <artifactId>retrofit</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>com.squareup.retrofit2</groupId> <artifactId>converter-gson</artifactId> <version>2.6.1</version> </dependency> gradle 方式:$title(build.gradle) dependencies { compile 'com.squareup.retrofit2:retrofit:2.6.1' compile 'com.squareup.retrofit2:converter-gson:2.6.1' } 在Android应用程序中,我们必须启用Internet权限,因为Retrofit会对Internet上某个服务器上运行的API执行HTTP请求。$title(AndroidManifest.xml) <uses-permission android:name="android.permission.INTERNET"></uses-permission>3. REST API建模3.1. REST API 接口 使用Retrofit的下一步是对REST API建模,我们将会在应用程序中使用它。下面举例说明有一个这样的API可以免费使用HTTP GET https://reqres.in/api/users/2 Response: { "data": { "id": 2, "email": "janet.weaver@reqres.in", "first_name": "Janet", "last_name": "Weaver", "avatar": "https://s3.amazonaws.com/uifaces /faces/twitter/josephstein/128.jpg" } }3.2. 业务数据模型假设我们只需要消费id,姓名和电子邮件字段,而不想使用头像字段。字段数量不匹配,Gson转换器并不会报错,他会解析我们模型中指定的字段。(国内的fastjson也一样效果)$title(UserApiResponse.java) public class UserApiResponse { private User data; //Setters and getters public String toString() { return "UserApiResponse [data=" + data + "]"; } }$title(User.java) public class User { private long id; private String first_name; private String last_name; private String email; //Setters and getters @Override public String toString() { return "User [id=" + id + ", " + "first_name=" + first_name + ", " + "last_name=" + last_name + ", " + "email=" + email + "]"; } }3.3. 业务接口 现在,我们可以使用Retrofit注解来创建具有所需映射信息和请求/响应类的服务接口。$title(UserService.java) import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Path; public interface UserService { @GET("/api/users/{id}") public Call<UserApiResponse> getUser(@Path("id") long id); }我们可以使用适当的改造注释为每个HTTP方法:@GET,@POST,@PUT,@DELETE,@PATCH或@HEAD。在方法注释中,我们应该指定REST资源的相对端点URL。在这种情况下,它是 - "/api/users/{id}"。在方法声明中,我们必须将服务器所期望的数据返回到一个类型化的Retrofit Call< >类中。在方法参数中,我们可以传递路径和查询参数,并在PUT / POST请求中请求正文。4. Retrofit 2 实际使用 现在是时候使用create Retrofit REST客户端并进行实际的API调用。在这个例子中,我们使用流畅的API与Retrofit.Builder和OkHttpClient来创建Retrofit实例。我们提供API和转换器类型的基本URL。$title(UserServiceClient.java) import okhttp3.OkHttpClient; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; $title(UserServiceClient.java) public class UserServiceClient { public static void main(String[] args) { OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://reqres.in/") .addConverterFactory(GsonConverterFactory.create()) .client(httpClient.build()) .build(); UserService service = retrofit.create(UserService.class); // Calling '/api/users/2' Call<UserApiResponse> callSync = service.getUser(2); try { Response<UserApiResponse> response = callSync.execute(); UserApiResponse apiResponse = response.body(); System.out.println(apiResponse); } catch (Exception ex) { ex.printStackTrace(); } } } 运行上面的程序,观察控制台中打印的输出。$title(out) UserApiResponse [data=User [ id=2, first_name=Janet, last_name=Weaver, email=janet.weaver@reqres.in]] 在上面的例子中,我们已经进行了同步请求。我们将在接下来的教程中会讲解异步请求。总结在本教程中,我们了解了Retrofit 2并为REST客户端构建了一个使用JSON有效负载的hello world应用程序。我们还了解了Retrofit库的基础知识。
  • Cannot open URL. Please check this URL is correct Idea报错

    问题描述:Cannot open URL. Please check this URL is correct: http://localhost:8080/解决办法​检查上方两个地方得端口是否一致问题描述:Cannot open URL. Please check this URL is correct: http://localhost:8080/解决办法​检查上方两个地方得端口是否一致。不一致就会导致idea报错Cannot open URL. Please check this URL is correct: http://localhost:8080/
  • Python教程-Python httplib2 HTTP GET和POST使用详解

    Python httplib2 简介学习使用Python httplib2模块Python httplib2 简介学习使用Python httplib2模块。的超文本传输协议(HTTP)是用于分布式,协作,超媒体信息系统的应用协议。HTTP是万维网数据通信的基础。Python httplib2模块提供了用于通过HTTP访问Web资源的方法。它支持许多功能,例如HTTP和HTTPS,身份验证,缓存,重定向和压缩。检查httplib2库版本第一个程序打印库的版本,其版权和文档字符串。import httplib2 print(httplib2.__version__) print(httplib2.__copyright__) print(httplib2.__doc__)在httplib2.__version__给出的版本httplib2库中,httplib2.__copyright__给出了其版权,以及httplib2.__doc__它的文档字符串。执行上方的代码可能遇到模块未找到错误,如下图:​如果出现上方问题,我们进行安装该模块即可,以下为Python 3.x版本的安装命令pip3 install httplib2 --upgrade 安装过程如下:​httplib2 安装 安装完成后我们再次执行版本检查的代码:​httplib2信息查看  使用httplib2读取网页 在下面的示例中,我们展示了如何从名为http://www.baidu.com的网站获取HTML内容。import httplib2 http = httplib2.Http() content = http.request("http://www.baidu.com")[1] print(content.decode()) 使用创建一个HTTP客户端httplib2.HTTP()。使用该request()方法创建一个新的HTTP请求。默认情况下,它是一个GET请求。返回值是响应和内容的元组。响应部分内容展示:​剥离HTML标签 以下程序获取一个小型网页,并剥离其HTML标签。import httplib2 import re http = httplib2.Http() content = http.request("http://www.baidu.com")[1] stripped = re.sub('<[^<]+?>', '', content.decode()) print(stripped) 一个简单的正则表达式用于剥离HTML标记。请注意,我们正在剥离数据,我们没有对其进行清理。(这是两总不同的情况。)​检查响应状态 响应对象包含一个status给出响应状态代码的属性。import httplib2 http = httplib2.Http() resp = http.request("http://www.baidu.com")[0] print(resp.status) resp = http.request("http://www.leftso.com/blog/0.html")[0] print(resp.status) 我们使用request()方法执行两个HTTP请求,并检查返回的状态。​200是成功HTTP请求的标准响应,而404则表明找不到所请求的资源。发送HTTP HEAD请求 HTTP HEAD方法检索文档标题。标头由字段组成,包括日期,服务器,内容类型或上次修改时间。import httplib2 http = httplib2.Http() resp = http.request("http://www.leftso.com/assist/images/carousel/855892C7F4734F3CB0721835573BAD07.jpg", "HEAD")[0] print("Server: " + resp['server']) print("Last modified: " + resp['last-modified']) print("Content type: " + resp['content-type']) print("Content length: " + resp['content-length']) ​这是程序的输出。从输出中,我们可以看到该网页是由FreeBSD托管的Apache Web服务器交付的。该文档的最后修改时间是1999年。网页是HTML文档,其长度为72个字节。发送HTTP GET请求 HTTP GET方法请求指定资源的表示形式。对于此示例,我们还将使用greet.php脚本:<?php echo "Hello " . htmlspecialchars($_GET['name']); ?> 在/usr/share/nginx/html/目录中,我们有此greet.php文件。该脚本返回name变量的值,该值是从客户端检索到的。该htmlspecialchars()函数将特殊字符转换为HTML实体;例如&到&amp.。import httplib2 http = httplib2.Http() content = http.request("http://localhost/greet.php?name=Peter", method="GET")[1] print(content.decode()) 该脚本将带有值的变量发送到服务器上的PHP脚本。该变量直接在URL中指定。Hello Peter 这是示例的输出。127.0.0.1 - - [21/Aug/2016:17:32:31 +0200] "GET /greet.php?name=Peter HTTP/1.1" 200 42 "-" "Python-httplib2/0.8 (gzip)" 我们检查了nginx访问日志。发送HTTP POST请求 POST请求方法请求Web服务器接受并存储请求消息正文中包含的数据。上载文件或提交完整的Web表单时经常使用它。<?php echo "Hello " . htmlspecialchars($_POST['name']); ?> 在本地Web服务器上,我们有此target.php文件。它只是将过帐的值打印回客户。import httplib2 import urllib http = httplib2.Http() body = {'name': 'Peter'} content = http.request("http://localhost/target.php", method="POST", headers={'Content-type': 'application/x-www-form-urlencoded'}, body=urllib.parse.urlencode(body) )[1] print(content.decode()) 脚本发送name带有Peter值的键的请求。数据使用urllib.parse.urlencode()方法进行编码,并在请求的正文中发送。Hello Peter 这是mpost.py脚本的输出。 127.0.0.1 - - [23/Aug/2016:12:21:07 +0200] "POST /target.php HTTP/1.1" 200 37 "-" "Python-httplib2/0.8 (gzip)" 使用POST方法时,不会在请求URL中发送该值。发送用户代理信息 在本节中,我们指定用户代理的名称。<?php echo $_SERVER['HTTP_USER_AGENT']; ?> 在nginx文档根目录下,我们有agent.php文件。它返回用户代理的名称。import httplib2 http = httplib2.Http() content = http.request("http://localhost/agent.php", method="GET", headers={'user-agent': 'Python script'})[1] print(content.decode()) 该脚本向脚本创建一个简单的GET请求agent.php。在headers字典中,我们指定用户代理。这可以通过PHP脚本读取,并返回给客户端。Python script 服务器使用我们随请求发送的代理名称进行了响应。将用户名/密码添加到请求 客户端的add_credentials()方法设置用于领域的名称和密码。安全领域是一种用于保护Web应用程序资源的机制。$ sudo apt-get install apache2-utils $ sudo htpasswd -c /etc/nginx/.htpasswd user7 New password: Re-type new password: Adding password for user user7 我们使用该htpasswd工具创建用于基本HTTP身份验证的用户名和密码。location /secure { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; } 在nginx /etc/nginx/sites-available/default配置文件中,我们创建一个安全页面。领域的名称是“禁区”。<!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html> 在/usr/share/nginx/html/secure目录中,我们有上面的HTML文件。import httplib2 user = 'user7' passwd = '7user' http = httplib2.Http() http.add_credentials(user, passwd) content = http.request("http://localhost/secure/")[1] print(content.decode()) 该脚本连接到安全网页;它提供访问该页面所需的用户名和密码。<!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html> 使用正确的凭据,脚本将返回受保护的页面。在本教程中,我们探索了Python httplib2模块。