发现一个第三方 nginx 模块:echo,可以方便的输出信息,利用这一模块可以实现变量值读取到 html,调试方便了很多。
echo GitHub 主页:https://github.com/openresty/echo-nginx-module
echo 模块需要从源码编译 nginx 时使用指令:--add-module= 加入,源码编译 nginx 及加入第三方模块参考我的教程:Nginx 安装/编译教程
echo 使用命令很简单:
server{
listen 80;
server_name 127.0.0.1;
location /echo {
default_type text/plain;
echo 'remote address: $remote_addr';
echo 'remote_port: $remote_port';
}
}default_type text/plain 指令设置响应内容的格式,不设置的话浏览器访问会返回下载文件而不是网页。
执行 curl 127.0.0.1/echo 或浏览器访问 127.0.0.1/echo 路径就会看到 echo 定义的内容。
**注意如果在 echo 指令下面定义了其他 html 页面或者 proxy_pass 反向代理,则 echo 的内容会被覆盖,如果 echo 指令在
location 段的最后,则会显示 echo 指令的内容。**
nginx 可以将一个客户端的请求反向代理到其他地址/端口,从客户端上看不到代理过程。方向代理的常用来处理服务器上部署的多个网络服务,根据请求呈现不同网页内容,转发请求到其他应用程序等。支持转发的协议有: HTTP,FastCGI, uwsgi, SCGI, and memcached。
不同于 nginx 的重定向 return/rewrite/try_fiels 功能,反向代理对于客户端是不可见的,关于重定向的语法参考:https://blog.niekun.net/archives/195.html
下面介绍 ngx_http_proxy_module 模块的使用方式。
proxy_pass 指令将请求转发到其他代理服务器。
转发一个 http 请求到另一个地址:
location /some/path/ {
proxy_pass http://www.example.com/link/;
}以上示例将访问 location 段的请求转发到特定地址,这里有几个规则需要注意:
1.代理地址如果不写明 location 段,则转发请求 location 到新的地址:
location /some/path/ {
proxy_pass http://www.example.com;
}以上规则下,访问 /some/path/.test.html 时,会转发到 http://www.example.com/some/path/.test.html
location ~ \.php {
proxy_pass http://127.0.0.1:8000;
}以上规则下,访问 /some/path/test.php 时,会转发到 127.0.0.1:8000/some/path/test.php
2.代理地址包含新的 location 时会替换掉请求 location 部分:
location /some/path/ {
proxy_pass http://www.example.com/new/;
}以上规则下,访问 /some/path/test.html 时,会转发到 http://www.example.com/new/test.html,注意 http://www.example.com/ 和 http://www.example.com 不同,也属于包含根路径 location 段的。
proxy_pass 语法用来转发给 http 服务,还支持转发给其他协议的服务:
转发的服务地址可以用一个 upstream 组来实现负载均衡:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server 192.0.0.1 backup;
}
server {
...
location / {
proxy_pass http://backend;
}
}
}以上是一个简单的负载均衡代理转发示例。关于 upstream 详细使用参考官方教程
当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时,proxy_redirect可以重设HTTP头部的location/Refresh 字段。
语法结构:
proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
默认设置是:proxy_redirect default。
http 响应头的 location 段 HTTP Location 是在两种情况使用在响应头中:
通过修改 location 可以让客户端接收到响应后,访问重定向到新的 location。
更详细的关于重定向/刷新请求头概念,需要理解 http 协议的结构,查看我的教程:HTTP 协议结构
如果设置:
server {
listen 8080;
servername frontend;
proxy_redirect http://localhost:8000/two/ http://frontend:8080/one/;
...}
代理服务器返回的 http 头信息:
HTTP/1.1 302 Found
Location: http://localhost:8000/two/some/uri/
则返回给客户端的 Location 段被重写为: http://frontend:8080/one/some/uri/,客户端接收到后就会去重新访问这个新的地址。
server 名也可以被省略:
proxy_redirect http://localhost:8000/two/ /
以上指令返回给客户端的 Location 段被重写为: http://frontend:8080/some/uri/
proxy_redirect 默认设置值为:default,它会自动根据 server location 段和 proxy_pass 地址来修改头信息,以下两种写法效果一样:
location /one/ {
proxy_pass http://localhost:8000/two/;
proxy_redirect default;
location /one/ {
proxy_pass http://localhost:8000/two/;
proxy_redirect http://localhost:8000/two/ /one/;以上两种写法都是将返回 location 头信息中 http://localhost:8000/two/ 修改为 http://frontend:8080/one/
redirect 和 replacement 都可以包含参数:
proxy_redirect http://$proxy_host:8000/ $scheme$host:$server_port/;
rederect 可以使用正则匹配:
proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;
proxy_redirect ~*/user/([^/]+)/(.+)$ http://$1.example.com/$2;
可以同时写多个 proxy_redirect 指令来处理不同的重定向地址。
使用 proxy_redirect off 具有最高优先级,会取消当前同一级的所有 proxy_redirect 指令。
一个完整例子:
server {
listen 8080;
server_name 127.0.0.1;
location /return {
return 301 https://niekun.net;
}
location /proxy {
proxy_pass $scheme://$http_host/return;
proxy_redirect https://niekun.net /echo;
}
location /echo {
default_type text/plain;
echo 'remote address: $remote_addr';
}
}代理过程:
默认情况下,nginx 反向代理时会舍弃原始请求头中的空字符串项,并重新设定两个请求头内容:Host 和 Connection:
关于 http 请求头 header 的可定义的项目参考我的教程:HTTP 协议结构
想要设置或修改传递给代理服务的请求头,使用 proxy_set_header 指令:
location /some/path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_pass http://localhost:8000;
}以上示例的处理结果是:
proxy_set_header 支持使用内部变量来定义,也可以使用 map 指令配合自定义参数来根据请求清空动态设置相关 header 内容,注意 map 指令要写在 http 段:
map $http_cloudfront_forwarded_proto $cloudfront_proto {
default "http";
https "https";
}
server {
...
location / {
proxy_set_header X-Forwarded-Proto $cloudfront_proto;
proxy_pass http://app;
proxy_redirect off;
...
}
}以上示例中 $http_cloudfront_forwarded_proto 是已知变量,$cloudfront_proto 是我自定义的变量,使用 map 指令来根据前者的值设置后者的值,然后在 proxy_set_header 设置。
map 指令支持以两个因变量来给终变量赋值,语法示例如下:
map "$http_cloudfront_forwarded_proto:$http_x_forwarded_proto" $cloudfront_proto {
default "http";
":https" "https";
"https:" "https";
"https:http" "https";
"http:https" "https";
"https:https" "https";
}如果用户访问时加了代理或者网站有 CDN,$remote_addr 的值就不是用户真实 IP 了。客户端也可以伪造 X-Forwarded-For 信息,使用 map 指令提取用户真实 IP,注意 map 指令要写在配置文件的 http 段:
map $http_x_forwarded_for $client_real_ip {
default $remote_addr;
~^(([0-9\.]+),\s?)*([0-9\.]+)$ $3;
}
server {
echo 'remote address: $client_real_ip';
}如果 $http_x_forwarded_for 没有匹配到则赋值为 $remote_addr,如果匹配到了则提取最后一个 IP。$client_real_ip 变量就是真是客户端的 IP 地址。
关于 $http_x_forwarded_for 和 $proxy_add_x_forwarded_for 参考我的文章:获取用户真实 IP in Nginx
默认情况下 nginx 缓存来自 proxy server 的响应内容。nginx 会一直在内部缓存来自代理服务器的响应内容直到内容接收完成,然后才发送给客户端。缓存能够帮助减轻客户端的压力,但会浪费服务器的资源和响应。但是打开缓存功能的另一个好处是当客户端再次进行一个缓存过的请求时,nginx 可以快速的返回已经在缓存区的内容。
使用 proxy_buffering 指令控制缓存打开/关闭。默认是 on 状态。proxy_buffers 指令控制缓存区数量和缓存大小。第一个来自代理服务器的响应会缓存到单独的区域,proxy_buffer_size 指令控制这一区域的大小:
location /some/path/ {
proxy_buffers 16 4k;
proxy_buffer_size 2k;
proxy_pass http://localhost:8000;
}以上示例会给 来自代理服务器:http://localhost:8000 的响应建立 16 个缓存区,每个区域 4kb 空间,第一个响应缓存区 2kb 空间。
如果关闭缓存,来自代理服务器的响应会即时发送给客户端,对于想要快速响应的使用场景可以关闭缓存:
location /some/path/ {
proxy_buffering off;
proxy_pass http://localhost:8000;
}默认情况下 nginx 向 proxy 上游发起请求连接,代理服务器看到的请求 IP 地址来自 nignx 服务器地址。有时候 web 服务器会设置只允许特定 IP 地址的访问,可以通过 proxy_bind 指令来修改,nginx 用户必须是 root 才行:
user root;
...
http{
...
server {
location /app1/ {
proxy_bind proxy_bind $remote_addr transparent;
proxy_pass http://example.com/app1/;
}
}
}以上示例中,代理服务器看到的请求来源就会是真正的访问客户端 IP 地址,也就是实现了透明代理。
nginx 配置后还需要配置 iptables 路由表来处理代理服务器响应内容:
#### 新建一个 DIVERT 给包打标签
sudo iptables -t mangle -N DIVERT;
sudo iptables -t mangle -A DIVERT -j MARK --set-mark 1;
sudo iptables -t mangle -A DIVERT -j ACCEPT;
#### 把tcp的包给DIVERT处理
sudo iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT;
#### 有标签的包去查名为 100 的路由表
sudo ip rule add fwmark 1 lookup 100
#### 100的路由表里就一条默认路由,把所有包都扔到lo网卡上去
sudo ip route add local 0.0.0.0/0 dev lo table 100;具体实现我还不太懂,后期再研究下。
以上就是 http 代理服务器基本使用,下面简单介绍其他集中代理服务器的语法。
Nginx must rely on a separate PHP processor to handle PHP requests. Most often, this processing is handled with php-fpm, a PHP processor that has been extensively tested to work with Nginx.
简单说就是 FastCGI 实现了使用 Nginx 代理 php 请求的过程,将请求转发给 php-fpm:php 进程管理器。
location / {
fastcgi_pass localhost:9000;
# fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+?\.php)(.*)$;
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param HTTP_X-REAL-IP $remote_addr;
fastcgi_param HTTP_X-FORWARED-FOR $proxy_add_x_forwarded_for;
fastcgi_param HOST $http_host;
}总结下和 http 语法区别:
HTTP_ 前缀,如:HTTP_X-FORWARED-FOR关于 FastCGI 的详细分析参考:Understanding and Implementing FastCGI Proxying in Nginx
uWSGI 是一个独立的 web 服务器,和 nginx 是一个类型的应用。一般 uWSGI 作为后端服务器使用,用 nginx 代理来访问。
uWSGI 可以用来部署 python 应用。之前我学习 django 的时候就使用过这个。
未完待续。。。
ngx_http_proxy_module 模块所有指令
NGINX Reverse Proxy
HTTP Load Balancing
Securing HTTP Traffic to Upstream Servers
使用nginx的proxy_bind选项配置透明的反向代理
Mapping Headers in Nginx
ngx_http_fastcgi_module 模块所有指令
[]()

锐化的原理就是将像素颜色反差的地方加强反差,而不破坏颜色相似地方的自然过渡。
下面介绍三种不同的方式进行图像锐化。使用的工具主要有以下:
首先介绍使用智能锐化工具配合混合模式来进行锐化。
智能锐化相比较其他几个锐化工具多个几个调节项目,可以通过滑块进行精细调节。配合混合模式主要是为了消除部分锐化过后的边沿亮条。
我们的主体是石狮子:
首先复制图层,转换为智能图层,然后选择 filter - sharpen - smart sharpen:
调节 radius 等参数进行适当锐化:
确认后,图像整体已经相比之前突出很多了,但是仔细观察会发现在和背景衔接处有明显的亮条,这就是锐化的副作用:
下面通过混合模式来处理,将锐化后的图层复制一个,将两个图层混合模式分别设置为 darken 和 lighten,这样就可以分别控制亮部和暗部了:
通过分离亮暗部分,通过蒙版来去除我们不想要的锐化过度区域。在 lighten 图层建立蒙版,使用黑色笔刷刷掉亮条部分:
在需要的时候也可以涂抹暗部锐化过度区域,此图经过上面的调节已经可以了:
第二种方法叫做:频率分离。以人物图像来举例,皮肤部分色彩过度较均匀,叫做低频部分;睫毛,头发,皮肤纹理等地方颜色反差大,叫做高频部分。在处理人像时,我们常规操作是将低频部分进一步使色彩平滑过渡,也就是磨皮,高频部分进一步加大反差增加清晰感,也就是锐化。
以下面人物为例,介绍操作方法:
复制两个图层,分别命名为 color 和 texture,将 color 图层转换为智能图层方便后期调节参数:
color 图层复制柔化皮肤,texture 图层负责锐化细节。
暂时关闭 texture 图层,选中 color 图层,执行 filter - blur - gaussian blur,调节 radius 使皮肤柔化到合适感觉,暂时不必理会细节丢失:
打开并选中 texture 图层,执行 image - apply image:
layer 选择 color 图层,blending 选择 subtract,scale 设置为 2,offset 设置 128。以上设置的意思是:将 texture 图层剪掉和 color 图层相同像素部分,并将剪掉部分填充为 50% 灰,scale 影响反差敏感度:
将 texture 图层混合模式设置为 linear light:
这样处理后,color 和 texture 就实现了分离,两个图层和原图层几乎是一样的。然后我们就可以单独对texture进行控制了。
复制 texture 图层,图像会明显的锐化过度,调节 fill 填充值来降低锐化效果到合适:
我只想锐化眼睛等区域,配合蒙版来处理:
最终效果:
最后一种方法是高反差保留,配合对比度调节工具,能够实现更加方便的锐化程度调节体验。
还是以上面人物为例进行处理,首先还是复制图层,然后转换为智能图层,将混合模式设置为 overlay:
执行 filter - other - high pass,调节 radius 观察锐化效果,注意不要设置过大而在反差地方出现光晕:
为了能够更加方便的调节锐化强度而不用复制图层,我们执行 image - adjustment - brightness/contrast,选中 use legacy,通过调节 contrast 可以实现锐化强度的调节:
由于我们的图层是智能图层,后期可以根据实际情况再次调节 high pass 和 contrast 的值到合适。
可以配合蒙版来调节锐化影响范围,这里还是只锐化面部重点区域即可用画笔涂抹出想要锐化的部分,最终效果如下:

BaiduPCS-Go 是我之前一直使用的工具,他是 GO 语言编写的命令行工具,需要登录你的账号使用,集成下载/上传等功能。就是一个第三方命令行客户端。
他可以设置缓存/并发数/user agent等,理论上可以加速下载。
GitHub 主页(作者已删除):https://github.com/iikira/BaiduPCS-Go
fork:https://github.com/Erope/BaiduPCS-Go
可以下载 release 页面发布的版本,也可以使用源码自己编译,go 语言编译教程参考我的文章:https://blog.niekun.net/archives/468.html
打开 BaiduPCS-Go 客户端,进入命令行界面,登录完成后可以输入 help 指令查看支持的命令。
----
BaiduPCS-Go - 百度网盘客户端 for windows/amd64
USAGE:
BaiduPCS-Go.exe [global options] command [command options] [arguments...]
VERSION:
v3.6.1-devel
DESCRIPTION:
BaiduPCS-Go 使用Go语言编写的百度网盘命令行客户端, 为操作百度网盘, 提供实用功能.
具体功能, 参见 COMMANDS 列表
特色:
网盘内列出文件和目录, 支持通配符匹配路径;
下载网盘内文件, 支持网盘内目录 (文件夹) 下载, 支持多个文件或目录下载, 支持断点续传和高并发高速下载.
---------------------------------------------------
前往 https://github.com/iikira/BaiduPCS-Go 以获取更多帮助信息!
前往 https://github.com/iikira/BaiduPCS-Go/releases 以获取程序更新信息!
---------------------------------------------------
交流反馈:
提交Issue: https://github.com/iikira/BaiduPCS-Go/issues
邮箱: i@mail.iikira.com
AUTHOR:
iikira/BaiduPCS-Go: https://github.com/iikira/BaiduPCS-Go
COMMANDS:
tool 工具箱
help, h, ?, ? Shows a list of commands or help for one command
其他:
bg 管理后台任务
clear, cls 清空控制台
env 显示程序环境变量
run 执行系统命令
sumfile, sf 获取本地文件的秒传信息
update 检测程序更新
百度帐号:
login 登录百度账号
loglist 列出帐号列表
logout 退出百度帐号
su 切换百度帐号
who 获取当前帐号
百度网盘:
cd 切换工作目录
cp 拷贝文件/目录
createsuperfile, csf 手动分片上传—合并分片文件
download, d 下载文件/目录
export, ep 导出文件/目录
fixmd5 修复文件MD5
locate, lt 获取下载直链
ls, l, ll 列出目录
match 测试通配符
meta 获取文件/目录的元信息
mkdir 创建目录
mv 移动/重命名文件/目录
offlinedl, clouddl, od 离线下载
pwd 输出工作目录
quota 获取网盘配额
rapidupload, ru 手动秒传文件
recycle 回收站
rm 删除文件/目录
search, s 搜索文件
share 分享文件/目录
tree, t 列出目录的树形图
upload, u 上传文件/目录
配置:
config 显示和修改程序配置项
GLOBAL OPTIONS:
--verbose 启用调试 [%BAIDUPCS_GO_VERBOSE%]
--help, -h show help
--version, -v print the version
COPYRIGHT:
(c) 2016-2019 iikira.执行 login 指令,登录百度账户,根据提示输入密码及验证码。
登录完成后可以使用 ls cd 等命令来访问目录及文件。
执行 config 命令查看当前配置信息:
运行 BaiduPCS-Go config set 可进行设置配置
当前配置:
名称 值 描述 建议值
appid 421937 百度 PCS 应用ID
cache_size 256.00KB 下载缓存, 如果硬盘占用高或下载速度慢, 请尝试 调大此值 1KB ~ 256KB
max_parallel 64 下载最大并发量 50 ~ 500
max_upload_parallel 64 上传最大并发量 1 ~ 100
max_download_load 3 同时进行下载文件的最大数 1 ~ 5
max_download_rate 不限制 限制最大下载速度, 0代表不限制
max_upload_rate 不限制 限制最大上传速度, 0代表不限制
savedir C:\Users\Marco Nie\Downloads 下载文件的储存目录
enable_https true 启用 https true
user_agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 浏览器标识
pcs_ua PCS 浏览器标识
pan_ua netdisk;2.2.51.6;netdisk;10.0.63;PC;android-android Pan 浏览器标识 netdisk;2.2.51.6;netdisk;10.0.63;PC;android-android
proxy 设置代理, 支持 http/socks5 代理
local_addrs 设置本地网卡地址, 多个地址用逗号隔开执行 config set --名称=value 可以修改设置值。
下载指令是 d file_name。
我当前使用 BaiduPCS-Go 速度非常慢,在下载时使用参数 --verbose 和 --status 查看详细信息,发现链接都是错误的,经过查询发现可能是 appid 的问题,我的账号可能上了黑名单了,需要修改 appid 来修复。
找了半天网上提供的 appid 都没法用,这个 python 小程序可以扫描可用的 appid:https://gist.github.com/pcmid/5818b1165bc3f5f2088e19299278a613
from __future__ import print_function
import requests
import threading
import sys
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
class GetterTread(threading.Thread):
def __init__(self, thread_id, app_id, times=1000):
threading.Thread.__init__(self)
self.__thread_id = thread_id
self.__URL = "http://pcs.baidu.com/rest/2.0/pcs/file?app_id={}&method=list&path=%2F"
with open("./BDUSS.txt") as f:
BDUSS = f.readline()
self.__COOKIES = {"BDUSS": BDUSS}
self.app_id = app_id
self.times = times
def run(self):
current_id = self.app_id
while current_id - self.app_id < self.times: # 250000:
url = self.__URL.format(current_id)
try:
r = requests.get(url, cookies=self.__COOKIES)
if r.status_code == 200:
print(current_id)
except Exception:
eprint("Exception: " + str(current_id))
current_id += 1
# print("id " + str(self.__thread_id) + " over")
if __name__ == '__main__':
start_app_id = 300000
times = 1000
threads_list = []
while start_app_id < 500000:
thread = GetterTread(start_app_id, start_app_id, times)
thread.start()
threads_list.append(thread)
start_app_id += times
# print("size: " + str(len(threads_list)))
for thread in threads_list:
thread.join()需要在目录下放一个 BDUSS.txt,里面填上你的账号的 BDUSS 获取 BDUSS 的方法参考
BaiduPCS-Go 慢慢失效后,我开始找寻其他的有效方法,发现有一个网盘直链下载助手挺好用的。
官网:https://www.baiduyun.wiki/
GitHub 主页:https://github.com/syhyz1990/baiduyun
这是一个油猴脚本,需要在 chrome 安装 Tampermonkey 脚本管理器,在 chrome 安装 tampermonkey
安装好管理器后,访问 GitHub脚本,会自动跳转到 tampermonkey 安装界面,然后点击安装即可。
进入百度云盘,会出现一个下载助手按钮:
勾选想要下载的资源,点击下载助手,里面有几个选项:
第一个是直接获取 api 下载链接,可以在浏览器或其他下载软件粘贴链接即可下载:
第二个是 aria2 下载链接,可以导入 aria2 进行下载,关于 aria2 的安装参考我的教程:https://blog.niekun.net/archives/1199.html
安装好 aria2 后还需要安装网盘万能助手 chrome 插件才能使用这个功能。插件地址:https://www.baiduyun.wiki/download.html
插件安装步骤:
第三个是远程 aria2 rpc 下载,也是需要安装 aria2 并启用 rpc,然后点击 rpc 配置,设置参数:
点击显示链接可以直接发送到 aria2:
下载客户端推荐:
aria2:https://blog.niekun.net/archives/1199.html
IDM:https://www.internetdownloadmanager.com/ 可以设置最大链接数到 32 来提高下载速度 download - option - connection
xdown:https://xdown.org/ 可以识别 aria2 的链接
以上说明摘录自 Wikipedia,HTTP 全称为超文本传输协议,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。
HTTP是一个客户端(用户)和服务端(网站)之间请求和应答的标准,通常使用TCP协议。有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS:
HTTP协议永远都是客户端发起请求,服务器回送响应。
HTTP是一个无状态的协议。协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。可以使用 connection: Keep-Alive 来保留 tcp 握手连接。
一次HTTP操作称为一个事务,其工作过程可分为四步:
HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要三次握手:
可以使用 Wireshark 网络协议分析工具来查看一个握手过程:https://www.wireshark.org/
打开 Wireshark,点击 capture - options,上方选择当前连接外网的硬件,我选择 WiFi,在 capture filter 里设置监听地址:tcp port http:
在浏览器访问:http://baidu.com,记得如果使用了代理的话先关掉。
在 wireshark 里就会显示报文信息:
可以通过颜色区分报文种类,绿色是 tcp 报文,黑色是有问题的报文。如果报文过多可以使用上面的 filter 过滤有用信息。
上面的报文显示了握手的过程:
下面主要分析 request 和 response 的 http 数据。
tcp 握手成功后,客户端就通过发送 request 开始请求 http 页面。
发出的请求信息(message request)结构如下:
请求行和标题必须以<CR><LF>作为结尾。空行内必须只有<CR><LF>而无其他空格。在HTTP/1.1协议中,所有的请求头,除Host外,都是可选的。
一个最简单的 request:
GET / HTTP/1.1
Host: www.bing.com末尾有一个空行。第一行指定方法、资源路径、协议版本;第二行是在1.1版里必带的一个header作用于指定主机。
上面访问 http://baidu.com 的request 全部内容如下:(在 wireshark 点击 request http 报文可查看)
GET / HTTP/1.1\r\n
Host: news.baidu.com\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
DNT: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n
Referer: https://www.baidu.com/\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en,en-US;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6\r\n
Cookie: BIDUPSID=DFBCEB19126518FE5B14DE02435939DF; PSTM=1585012306; BAIDUID=DFBCEB19126518FEC81AB23A0B7A652F:FG=1; H_PS_PSSID=30971_1426_31118_21108_30824_26350\r\n
\r\n
[Full request URI: http://news.baidu.com/]
[HTTP request 1/3]
[Response in frame: 23]
[Next request in frame: 599]HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源:
当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。
最常用的就是 GET 和 POST 方法。
GET和POST的区别:
HTTP 头字段根据实际用途被分为以下 4 种类型:
常见的请求头字段:
常见的非标准请求头字段:
更多请求头字段参考:wikepedia
服务端发出 tcp 确认后,发出 response 响应 http 页面。
发出的响应信息(message request)结构如下:
下面是一个 http 页面的响应实例:
HTTP/1.1 200 OK\r\n
Content-Type: text/html; charset=utf-8\r\n
Server: GitHub.com\r\n
Last-Modified: Fri, 22 Jan 2016 02:52:30 GMT\r\n
ETag: W/"56a1996e-2d27"\r\n
Access-Control-Allow-Origin: *\r\n
Expires: Tue, 24 Mar 2020 06:32:29 GMT\r\n
Cache-Control: max-age=600\r\n
Content-Encoding: gzip\r\n
X-Proxy-Cache: MISS\r\n
X-GitHub-Request-Id: EAD6:198D:D9A2C:E5FDD:5E79A724\r\n
Content-Length: 4509\r\n
Accept-Ranges: bytes\r\n
Date: Tue, 24 Mar 2020 06:22:29 GMT\r\n
Via: 1.1 varnish\r\n
Age: 0\r\n
Connection: keep-alive\r\n
X-Served-By: cache-hnd18730-HND\r\n
X-Cache: MISS\r\n
X-Cache-Hits: 0\r\n
X-Timer: S1585030950.603621,VS0,VE171\r\n
Vary: Accept-Encoding\r\n
X-Fastly-Request-ID: 806211821134676c48d8c7c6ed9cee2a6bad952d\r\n
\r\n
[HTTP response 1/5]
[Time since request: 0.405424000 seconds]
[Request in frame: 2595]
[Next request in frame: 2604]
[Next response in frame: 2623]
[Request URI: http://zq210wl.github.io/imgs/noise.png]
Content-encoded entity body (gzip): 4509 bytes -> 11559 bytes
File Data: 11559 bytes
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
...
</head>
<body>
...
</body>响应行结构为:当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。
状态代码的第一个数字代表当前响应的类型:
详细的状态码介绍参考:https://blog.niekun.net/archives/192.html
HTTP 头字段根据实际用途被分为以下 4 种类型:
常见的响应头字段:
常见的非标准回应字段:
详细的响应头字段参考:Wikipedia
HTTP Location 是在两种情况使用在响应头中:
示例:
HTTP/1.1 302 Found
Location: http://www.example.org/index.php客户端请求的 URL 被服务端重定向到 http://www.example.org/index.php.
客户端请求:
GET /blog HTTP/1.1
Host: www.example.com服务端响应:
HTTP/1.1 302 Found
Location: /articles/该位置 /blog 被客户端定向到 http://www.example.com/articles/.
使用Cookie来实现:

使用URL回写来实现:
URL回写是指服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带会服务器。如果直接在浏览器输入服务端资源的url来请求该资源,那么Session是匹配不到的。
统一资源标识符(英语:Uniform Resource Identifier,缩写:URI)在电脑术语中是一个用于标识某一互联网资源名称的字符串。
该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI的最常见的形式是统一资源定位符(URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(URN),其目的是通过提供一种途径。用于在特定的名字空间资源的标识,以补充网址。
通用URI的格式如下:
[协议名]://[用户名]:[密码]@[主机名]:[端口]/[路径]?[查询参数]#[片段ID]下面是两个常见的 URI 构成:
hierarchical part
┌───────────────────┴─────────────────────┐
authority path
┌───────────────┴───────────────┐┌───┴────┐
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
└┬┘ └───────┬───────┘ └────┬────┘ └┬┘ └─────────┬─────────┘ └──┬──┘
scheme user information host port query fragment
urn:example:mammal:monotreme:echidna
└┬┘ └──────────────┬───────────────┘
scheme path以 https://zh.wikipedia.org:80/w/index.php?title=Special:随机页面#ABC 为例, 其中:

这里用到的技术细节其实就是提取出想要修改部分,然后修改颜色。有两个方法可以进行提取:color range 和 hue。
首先使用 color range 来进行选区,选择 select - color range:
首先将 fuzziness 设为 0,关闭 localized color clutter,preview 设为 none:
选择右侧 eyedrop,点击花朵,然后选择带加号的 eyedrop 进行区域添加:
将 preview 设置为 black matte 更清晰的观察选取:
适当调整 fuzziness 使过渡平滑:
确认后就建立了选区,新建 hue 图层,会自动添加蒙版,这样修改只影响花朵部分:
调节 hue 或 saturation 来修改颜色:
如果要修改背景色彩,可以新建 hue 图层,按住 alt 拖动蒙版到新的图层,然后 ctrl I 反转蒙版,这样就可以单独调整背景色彩了:
最终效果如下:
也可以直接使用 hue/saturation 图层来提取颜色。新建 hue/saturation 图层,先选择任意一种颜色:
下方 eyedrop 就可以使用了,选择左侧 eyedrop 上方选择 3×3,点击花朵部分:
先将 hue 和 saturation 设置到最大,这样方便观察当前影响的颜色范围:
调节左右滑块使影响的颜色只包含花朵:
恢复 hue/saturation 值,然后调节到合适位置:
最终效果如下:

如果你有遇到以上场景,这篇教程就能够帮助到你。
屏幕录制我使用的是 OBS Studio,一款开源的视频录制及流媒体传输的软件,支持 Windows macOS Linux。
官网:https://obsproject.com/
GitHub 主页:https://github.com/obsproject/obs-studio/wiki/Sources-Guide
在官网下载最新版并安装,然后运行 OBS。
第一次启动会有几个设置项,首先根据提示选择自动配置或手动配置,选择自动识别硬件并配置。
然后选择要进行流媒体传输还是只进行视频录制,我选择只视频录制:
设置录制分辨率及刷新率,默认即可:
主界面如下,默认没有设置视频源输入,所以背景为黑色:
界面中间为当前监听的视频源预览,界面下方有 5 个区域 senses,sources,audio mixer,senses transitions,control。
可以创建多个 sense,每个 sense 都有单独的 sources 设置,可以通过切换 sense 快速切换不同的 sources。
source 就是添加监听源,点击下方加号可以添加 source:
可以添加多种不同的 source,如:音频,窗口,应用,监视器等,如果录制某个打开的应用窗口,点击 Windows capture:
可以起个名字点击 ok:
Windows 菜单下会列出当前打开的窗口,选择需要的即可:
有时候我们需要录制的内容要在多个窗口下切换,这时候可以录制整个监视器,选择 display capture:
这时就会录制当前屏幕显示的内容了:
如果选择 display capture 后显示的是黑屏,需要设置 app 的 graphic setting,搜索并打开 graphic setting:
点击 browse 找到 OBS 主程序:
点击 option 选择 power saving:
重新启动 OBS 应该就可以捕获到监视器了。
官方对此的解释:https://obsproject.com/forum/threads/laptop-black-screen-when-capturing-read-here-first.5965/
默认会捕获输入输出的 audio,可以调节滑块了控制音量大小或者屏蔽某个音频。
当建立了多个 sense 时,可以设定在 sense 间切换时的过渡延时时间,时间越长过渡越慢。

我常用的就是 start recoding。可以设置快捷键来录制,点击 settings- hotkeys,在 start recoding 右侧设置快捷键,我设置的是 ctrl shift 9,stop recoding 默认也会使用这个快捷键:
设置好 sense,source,audio 就可以开始录制了,点击 start recoding 或者快捷键开始录制,然后点击 stop recoding 结束录制,默认保存路径是用户目录下的 videos 文件夹,默认格式是 MKV。
如果需要 mp4 格式,可以使用内置的 remux reroders 来转码,点击 file - remux recoders:
在左侧输入录制的 MKV 文件,右侧就是要转码的 mp4 文件路径,点击 remux 即可。
使用 OBS 录制的视频默认会有鼠标,想要更多的功能,如:局部放大,聚光灯效果,轨迹绘制,按键提示等就需要其他 app 了。
我这里使用的是 SwordSoft Mousetrack,可以实现这些功能,但是只支持 Windows。
除了屏幕录制时使用,在给别人进行演示或者做报告的时候,使用 SwordSoft Mousetrack 也是很好的选择。
官网:http://www.swordsoft.idv.tw/mousetrack/
SwordSoft Mousetrack is a useful tool for presentations or demos. It can puts a spotlight on the area around the mouse pointer, show animation effect when you click your mouse and displays your keystrokes on the screen.
SwordSoft Mousetrack 可以免费使用,但是如果想要保存设置项,就需要付费买授权了。下面介绍他的几个功能。
general 选项卡,在 show spotlight 前打勾,就开启了聚光灯模式,鼠标周围区域高亮,其他区域变暗:
可以设置圆圈半径轮廓颜色,不透明度等。在 spotlight 选项卡进行设置:
live draw 就是在当前屏幕用鼠标进行画线,在 show livedraw 前打勾即可激活:
默认会有一行提示信息,可以使用鼠标进行绘制了:
按 esc 退出 livedraw。在 livedraw 选项卡进行线条粗细/透明度/颜色的设置:
zoom 可以放大鼠标局部区域,在 show livezoom 前打勾即可激活:
激活后,在鼠标附近或有当前区域放大图:
在 zoom 选项卡可以进行放大倍率/放大区域宽高等设置项。
点击鼠标位置效果,在 show mouse click 前打勾激活,当点击鼠标时,当前位置会显示一个动态效果:
默认显示一个红色圆环,需要设定其他效果,可以到 mouse click 选项卡设置。
在 show keystroke 前打勾激活。再按下键盘上的任意键后,会在屏幕下方提示栏显示按下的键:
在 keystroke 选项卡可以设置提示栏位置/大小/透明度/颜色等信息。
每次需要使用什么功能可以在 general 进行选择,也可以为每个功能设置快捷键,这样就可以快速的激活/关闭相关功能了。
在 general 选项卡,每个功能右侧都可以定义快捷键,我设置的快捷键如下:
设置好后只需要按下 ctrl shift 1 即可激活 聚光灯效果。
有时我们需要截取当前屏幕,并做一些标注。Windows 10 和 macOS 都有原生工具可供使用。
macOS:
shift command 3 截取全屏
shift command 4 截取部分区域
截屏后会在右下角显示预览,点击后可进行编辑。或者截屏会自动存储在桌面。
Windows 10:
shift win S 截屏
使用 OBS 和 SwordSoft Mousetrack 可以很好的实现屏幕录制效果。先打开 SwordSoft Mousetrack 然后打开 OBS 开始录制即可。免费版的 SwordSoft Mousetrack,不能保存设置,重新启动后所有设置会恢复默认。默认激活的功能是 mouse click 和 keystroke。
]]>程序是利用增加存活时间(TTL)值来实现其功能的。每当数据包经过一个路由器,其存活时间就会减 1。当其存活时间是 0 时,主机便取消数据包,并发送一个ICMP TTL数据包给原数据包的发出者。
traceroute 使用互联网控制信息协议(ICMP)实现,ICMP 依靠IP来完成它的任务,它是IP的主要部分。它与传输协议(如TCP和UDP)显著不同:它一般不用于在两点间传输数据。由于协议不同所以本地 http 代理对 traceroute 无效。
现代 Linux 系统称为 tracepath,Windows 系统称为 tracert,Windows NT 系统有结合 ping 和 traceroute 的 pathping 工具。
可以使用 tracepath/traceroute 工具来测试,traceroute 可使用 apt 来安装,默认最多检测30个路由节点,超过的话就直接结束:
root@niekun-bandwagon:~# tracepath github.com
1?: [LOCALHOST] pmtu 1500
1: no reply
2: 173.254.196.25.static.quadranet.com 0.980ms
3: lax1-fatpipe-1.it7.net 0.395ms
4: 69.12.69.1 0.539ms asymm 3
5: ae12.er4.lax112.us.zip.zayo.com 0.515ms asymm 4
6: ae14.cr2.lax112.us.zip.zayo.com 26.123ms asymm 11
7: ae2.cs1.sjc2.us.eth.zayo.com 26.180ms asymm 11
8: ae3.cs1.sea1.us.eth.zayo.com 30.307ms asymm 10
9: ae1.mcs1.sea1.us.eth.zayo.com 26.299ms asymm 8traceroute to github.com (192.30.255.112), 30 hops max, 60 byte packets
1 * * *
2 173.254.196.25.static.quadranet.com (173.254.196.25) 1.172 ms 1.172 ms 1.161 ms
3 lax1-fatpipe-1.it7.net (69.12.70.234) 0.220 ms lax1-fatpipe-1.it7.net (69.12.70.232) 0.341 ms lax1-fatpipe-1.it7.net (69.12.70.234) 0.193 ms
4 ae12.er4.lax112.us.zip.zayo.com (64.124.85.221) 0.397 ms 0.422 ms 69.12.69.1 (69.12.69.1) 0.268 ms
5 ae14.cr2.lax112.us.zip.zayo.com (64.125.30.74) 25.828 ms ae12.er4.lax112.us.zip.zayo.com (64.124.85.221) 0.364 ms 0.345 ms
6 ae2.cs1.sjc2.us.eth.zayo.com (64.125.28.144) 35.091 ms ae14.cr2.lax112.us.zip.zayo.com (64.125.30.74) 26.043 ms 26.009 ms
7 ae2.cs1.sjc2.us.eth.zayo.com (64.125.28.144) 34.909 ms 34.889 ms 34.832 ms
8 ae1.mcs1.sea1.us.eth.zayo.com (64.125.28.133) 28.864 ms 26.124 ms 26.112 ms
9 ae1.mcs1.sea1.us.eth.zayo.com (64.125.28.133) 28.448 ms 28.416 ms 64.125.188.97.IPYX-243981-001-ZYO.zip.zayo.com (64.125.188.97) 30.797 ms
10 * 64.125.188.97.IPYX-243981-001-ZYO.zip.zayo.com (64.125.188.97) 30.949 ms *
可以使用 tracert/pathping 工具来测试,pathping 多显示了个本地 IP,默认最多检测30个路由节点,超过的话就直接结束:
PS C:\Users\Marco Nie> tracert niekun.net
Tracing route to niekun.net [104.24.97.72]
over a maximum of 30 hops:
1 5 ms 1 ms 1 ms OrayBox.lan [27.168.1.1]
2 67 ms 111 ms 81 ms 192.168.1.1
3 3 ms 3 ms 4 ms 100.64.16.1
4 4 ms 3 ms 4 ms 10.226.25.13
5 9 ms * * 219.145.223.105
6 33 ms 32 ms 33 ms 202.97.65.41
7 * * * Request timed out.
8 * 42 ms 131 ms 202.97.12.50
9 341 ms 197 ms 201 ms 202.97.41.50
10 237 ms 232 ms 224 ms 202.97.92.45
11 242 ms 252 ms 238 ms 218.30.54.214
12 197 ms 195 ms 196 ms 104.24.97.72
Trace complete.PS C:\Users\Marco Nie> pathping niekun.net
Tracing route to niekun.net [104.24.97.72]
over a maximum of 30 hops:
0 Marco-vostro-14.lan [27.168.1.209]
1 OrayBox.lan [27.168.1.1]
2 192.168.1.1
3 100.64.16.1
4 10.226.25.13
5 219.145.223.105
6 202.97.65.41
7 202.97.34.74
8 * 202.97.12.50
9 202.97.41.50
10 202.97.92.45
11 218.30.54.214
12 104.24.97.72
Computing statistics for 300 seconds...
]]>wkhtmltopdf and wkhtmltoimage are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine. These run entirely "headless" and do not require a display or display service.
wkhtmltopdf 官网:https://wkhtmltopdf.org/
GitHub 主页:https://github.com/wkhtmltopdf/wkhtmltopdf
在 release 页面下载对应系统最新版:https://github.com/wkhtmltopdf/wkhtmltopdf/releases
我要安装到 Ubuntu 18.04,所以下载:wkhtmltox_0.12.5-1.bionic_amd64.deb
查看 Ubuntu 系统代号可以使用命令:
lsb_release -c
下载的 deb 包,用以下命令进行安装:
dpkg -i wkhtmltox_0.12.5-1.bionic_amd64.deb
支持 url 或 本地 html 转换:
wkhtmltopdf http://bing.com bing.pdf
wkhtmltopdf path/to/test.html index.pdf
配合 find 命令可以实现批量转换:
find path/to/html -name '*.html' -exec wkhtmltopdf {} {}.pdf \;
mkdir pdf/
find path/to/html -name '*.pdf' -exec mv {} pdf/ \;find 命令详细用法参考:https://blog.niekun.net/archives/543.html
可以使用 wget 命令下载某个网站到本地,然后使用上面命令批量转换:
wget -m -p -k URL
-m, –mirror 等价于 -r -N -l inf -nr
-p:下载所有html文件适合显示的元素
-k, –convert-links 转换非相对链接为相对链接,将文档链接都转换成本地的

在使用相机拍摄一些长方形物体时,由于不能很好的控制视角和高低,拍摄出来的物体会出现变形而不是正确的四方形。后期我们可以使用 ps 的 perspective warp 工具来进行修复。
关于 perspective warp 的详细用法,参考:https://blog.niekun.net/archives/615.html
上图模拟本来是正方形的物体,由于拍摄问题产生的变形。
选择 edit - perspective warp:
选择第一个 layout 工具,拖动选择出物体的区域:
通过调整四角控制点来精确选中物体四周:
切换到 warp 工具开始进行调整:
这里需要使用的矫直命令,按住 shift 键点击四条边,可以自动将四边垂直/水平:
以上就完成了变形修复。perspective warp 的更多功能参数我上面的文章。
]]>