这不是讲http协议的
很多的东西是知其意而忘其形?, 趁着过年这段时间把很多的知识都review下, 把形找回来, 写代码并不是全部
tools
request
telnet
curl
chrome
postman
capture
fiddler/wireshark
http
http属于应用层的协议
http是无状态的(cookie和session的作用就体现出来了)
cookie and session
我这里画了一张图
https://www.processon.com/vie...
下面是我的php.ini的部分配置
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.save_path=F:\www\tmp\session
注意session.name = PHPSESSID
URL
http://www.test.com:80/index.php/kill?d=1&a=x
以这个为例
description | value | commet |
---|---|---|
scheme | http | http代表使用http协议/https |
host | www.test.com | |
port | 80 | http默认80/https默认443 |
uri | /index.php/kill?d=1&a=x | |
args | d=1&a=x | 就是query_string |
chrome demo
我使用虚拟机的, 把虚拟机的80端口映射到本机的8000端口, so下面的host是127.0.0.1:8000
完整的是在chrome里面打开http://127.0.0.1:8000/index/index/test2
request
GET /index/index/test2 HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Cookie: XDEBUG_SESSION=PHPSTORM
response
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 23 Jan 2017 02:29:09 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.22
Proxy-Connection: keep-alive
body
test
curl demo
[xsu@localhost ~]$ curl -v "http://127.0.0.1/index/index/test2"
* About to connect() to 127.0.0.1 port 80 (#0)
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /index/index/test2 HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 23 Jan 2017 02:20:23 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Vary: Accept-Encoding
< X-Powered-By: PHP/5.6.22
<
* Connection #0 to host 127.0.0.1 left intact
test
telnet demo
[xsu@localhost ~]$ telnet 127.0.0.1 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
^]
telnet>
GET /index/index/test2 HTTP/1.1
Host: 127.0.0.1
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 23 Jan 2017 02:14:36 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.22
4
test
0
Transfer-Encoding: chunked
chunked 表示是分段, test前面的4表示接下来的数据的长度, 这是一个16进制的数, test下一段的长度为0 , 即表示结束
request
由3部分组成:
request method, uri, protocol version
GET /index.php/index/index/test HTTP/1.1
request method | curd |
---|---|
get | r, read |
post | u, update |
put | c, create |
delete | d, delete |
request header
只说几个有趣的, 其他的自己看详细的http协议, 或者chrome调试台的request header
User-Agent
所有的浏览器都是Mozilla/5.0
开头的, 当时久我都惊呆了, 至于为什么看知乎Accept-Language
在chrome地址栏里面打开chrome://settings/languages
, 把英文拖到 最上面, 打开www.swoole.com
, 再把中文拖到最上面, 再打开www.swoole.com
困惑了我好久, 我之前打开很多网站, 打开的总是默认打开英文版的网站, 后来不小心review了下http协议, 恍然大悟?
X-Forward-For
可以用来伪造ip来源, 刷单, 限制ip的地方
在配置nginx的时候要注意, 和获取client ip的时候要注意, 不要相信用户的输入, 特别是http_xxx, 太容易伪造了
X-Request-With
区分是正常的请求还是ajax请求的, ajax请求一般都带有这个请求头, 当然可以直接定义
request body
post的数据就是放到里面
response
protocol version, response status, description
HTTP/1.1 200 OK
response header
Server: nginx
Date: Mon, 23 Jan 2017 02:29:09 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.22
Proxy-Connection: keep-alive
response body
就是我们看到的html实体, 或者ajax返回的字符串
PHP
大概说下php里面$_SERVER
php的文件内容为
ksort($_SERVER);
print_r($_SERVER);
request -> view-source:http://127.0.0.1:8000/index.php/index/index/test?a=1&d=x
返回的数据为(服务器用的是nginx, apache的类似)
Array
(
[CONTENT_LENGTH] =>
[CONTENT_TYPE] =>
[DOCUMENT_ROOT] => /home/wwwroot/tp5/public
[DOCUMENT_URI] => /index.php
[FCGI_ROLE] => RESPONDER
[GATEWAY_INTERFACE] => CGI/1.1
[HOME] => /home/www
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp
[HTTP_ACCEPT_ENCODING] => gzip, deflate, adch, br
[HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
[HTTP_CONNECTION] => keep-alive
[HTTP_COOKIE] => XDEBUG_SESSION=PHPSTORM
[HTTP_DNT] => 1
[HTTP_HOST] => 127.0.0.1:8000
[HTTP_UPGRADE_INSECURE_REQUESTS] => 1
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
[PATH_INFO] => /index/index/test
[PHP_SELF] => /index/index/test
[QUERY_STRING] => a=1&d=x
[REDIRECT_STATUS] => 200
[REMOTE_ADDR] => 10.0.2.2
[REMOTE_PORT] => 62835
[REQUEST_METHOD] => GET
[REQUEST_SCHEME] => http
[REQUEST_TIME] => 1485139559
[REQUEST_TIME_FLOAT] => 1485139559.6806
[REQUEST_URI] => /index.php/index/index/test?a=1&d=x
[SCRIPT_FILENAME] => /home/wwwroot/tp5/public/index.php
[SCRIPT_NAME] => /index.php
[SERVER_ADDR] => 10.0.2.15
[SERVER_NAME] => www.test.com
[SERVER_PORT] => 80
[SERVER_PROTOCOL] => HTTP/1.1
[SERVER_SOFTWARE] => nginx/1.10.0
[USER] => www
)
大概可以分为以下(#1表)
分类 | 描述 |
---|---|
HTTP开头 | request header |
REQUEST开头 | request method, protocol |
SERVER开头 | 服务器的相关信息 |
REMOTE开头 | 客户端的相关信息 |
SCRIPT,DOCUMENT开头 | 脚本相关的名称, 路径 |
路由, 参数相关 | path_info, query_string |
其他 |
nginx
cgi, fastcgi, php-fpm
cgi -> 公共网关接口, 与语言无关, 规定要传哪些数据(看#1表), 通过重定向语言的stdin, stdout来实现, 但是cgi很慢, 看下使用cgi的php执行流程
webserver 收到 parse php请求 -> 启动PHPCGI -> PHPCGI解析php.ini, 初始化运行环境 -> 处理请求, 以cgi规定格式返回 -> 退出PHPCGI -> webserver 返回数据
问题 : 每次都要启动phpcgi, 和初始化环境
fastcgi -> cgi的改进方案, 启动一个master进程, 解析配置文件, 初始化运行环境, 再fork多个worker来处理php请求, 返回数据, 他是要管理一个进程池来处理请求
php-fpm -> 是实现了fastcgi协议的 php fastcgi 进程管理器, 并且可以平滑重启(新的worker使用新的配置, 老的worker执行完就可以自动退出了),
nginx通常都是使用php-fpm, 通信有两种方式, socket和9000端口
params
看下fastcgi的重写
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
以$开头的是nginx ngx_http_core_module
提供的变量, 具体可参看http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
fastcgi_param这条指令就是对php中的$_SERVER赋值
fiddler
这个软件抓包使用很简单, 可能不满足需求, 当然需要更加专业wireshark
, 可以使用自定义脚本, 这个功能就自己想象了, 并且这个软件我也只会简单的抓包, 复杂的不会, 不敢写
为什么能抓包?
打开Internet属性
-> 连接
-> 局域网设置
-> 高级
你的http和https都使用了代理的, 你的所有的请求都会转发到代理, 由代理处理, 所以能抓包
你把手机的代理地址, 设置为fiddler自动配置的ip地址和端口, 也可以抓手机的包
http断点
打断点, 加参数, 就像调试本地程序一样
这里可能需要用到filter
过滤一下, 可以按 host
, 进程
, 请求头
过滤, 高兴就好
postman
有空再写, 回家过年了,
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。