站内公告:

我们的虚拟社区正式开通了

Main Menu

最新帖子

#51
VirtualBox / Ubuntu下安装VirtualBox
上次发布者 jvip_chen - 2022-5月-25 10:29 上午
之前换了新硬盘,重装了ubuntu,由于学习需要还是要装个虚拟机。以前用过VMWare真的是神卡,这次换VirtualBox,希望开源社区能给我带来曙光:)
添加VirtualBox的源并安装5.1版本
虽然也可以直接安装deb包,但毕竟懒,添加源可以保持更新:
$ sed -i '$adeb http://download.virtualbox.org/virtualbox/debian xenial contrib' /etc/apt/sources.list
为apt-secure导入公钥:
$ wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
$ wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
通过apt安装VirtualBox和dkms,其中dkms包可以确保在下次通过apt upgrade更新内核时,VirtualBox的内核模块也正确地更新:
$ sudo apt-get update
$ sudo apt-get install virtualbox-5.1 dkms
安装Oracle VM VirtualBox扩展包
这个扩展包据说可以提供USB2.0/3.0、Webcam、远程桌面协议(RDP)、磁盘加密等的支持,对于我这种普通用户来说其实就是USB3.0和RDP的支持比较有用,主要还是本着一颗爱折腾的心。
这个包就不推荐通过apt源来安装了,首先直至目前apt源提供的ext-pack仍然是5.0版本,而最新的virtualBox是5.1版本,不匹配;其次还会遇到一些奇怪的问题导致安装不成功。
首先直接下载这个包:
$ axel -a -n 16 "http://download.virtualbox.org/virtualbox/5.1.6/Oracle_VM_VirtualBox_Extension_Pack-5.1.6-110634.vbox-extpack"然后打开VirtualBox,在管理-全局设定-扩展中选择添加新包。
#52
Linux 系统 / Linux下curl用法详解播
上次发布者 jvip_chen - 2022-5月-25 10:24 上午
Curl(CommandLine Uniform Resource Locator),即在命令行中利用URL进行数据或者文件传输,它是Linux下强大的http命令行工具,其功能十分强大,我们来看下帮助页面,参数非常丰富。

[root@mx ~]# curl -h
Usage: curl [options...] <url>
Options: (H) means HTTP/HTTPS only, (F) means FTP only
     --anyauth       Pick "any" authentication method (H)
 -a, --append        Append to target file when uploading (F/SFTP)
     --basic         Use HTTP Basic Authentication (H)
     --cacert FILE   CA certificate to verify peer against (SSL)
     --capath DIR    CA directory to verify peer against (SSL)
 -E, --cert CERT[:PASSWD] Client certificate file and password (SSL)
     --cert-type TYPE Certificate file type (DER/PEM/ENG) (SSL)
     --ciphers LIST  SSL ciphers to use (SSL)
     --compressed    Request compressed response (using deflate or gzip)
 -K, --config FILE   Specify which config file to read
     --connect-timeout SECONDS  Maximum time allowed for connection
 -C, --continue-at OFFSET  Resumed transfer offset
 -b, --cookie STRING/FILE  String or file to read cookies from (H)
 -c, --cookie-jar FILE  Write cookies to this file after operation (H)
     --create-dirs   Create necessary local directory hierarchy
     --crlf          Convert LF to CRLF in upload
     --crlfile FILE  Get a CRL list in PEM format from the given file
 -d, --data DATA     HTTP POST data (H)
     --data-ascii DATA  HTTP POST ASCII data (H)
     --data-binary DATA  HTTP POST binary data (H)
     --data-urlencode DATA  HTTP POST data url encoded (H)
     --delegation STRING GSS-API delegation permission
     --digest        Use HTTP Digest Authentication (H)
     --disable-eprt  Inhibit using EPRT or LPRT (F)
     --disable-epsv  Inhibit using EPSV (F)
 -D, --dump-header FILE  Write the headers to this file
     --egd-file FILE  EGD socket path for random data (SSL)
     --engine ENGINGE  Crypto engine (SSL). "--engine list" for list
 -f, --fail          Fail silently (no output at all) on HTTP errors (H)
 -F, --form CONTENT  Specify HTTP multipart POST data (H)
     --form-string STRING  Specify HTTP multipart POST data (H)
     --ftp-account DATA  Account data string (F)
     --ftp-alternative-to-user COMMAND  String to replace "USER [name]" (F)
     --ftp-create-dirs  Create the remote dirs if not present (F)
     --ftp-method [MULTICWD/NOCWD/SINGLECWD] Control CWD usage (F)
     --ftp-pasv      Use PASV/EPSV instead of PORT (F)
 -P, --ftp-port ADR  Use PORT with given address instead of PASV (F)
     --ftp-skip-pasv-ip Skip the IP address for PASV (F)
     --ftp-pret      Send PRET before PASV (for drftpd) (F)
     --ftp-ssl-ccc   Send CCC after authenticating (F)
     --ftp-ssl-ccc-mode ACTIVE/PASSIVE  Set CCC mode (F)
     --ftp-ssl-control Require SSL/TLS for ftp login, clear for transfer (F)
 -G, --get           Send the -d data with a HTTP GET (H)
 -g, --globoff       Disable URL sequences and ranges using {} and []
 -H, --header LINE   Custom header to pass to server (H)
 -I, --head          Show document info only
 -h, --help          This help text
     --hostpubmd5 MD5  Hex encoded MD5 string of the host public key. (SSH)
 -0, --http1.0       Use HTTP 1.0 (H)
     --ignore-content-length  Ignore the HTTP Content-Length header
 -i, --include       Include protocol headers in the output (H/F)
 -k, --insecure      Allow connections to SSL sites without certs (H)
     --interface INTERFACE  Specify network interface/address to use
 -4, --ipv4          Resolve name to IPv4 address
 -6, --ipv6          Resolve name to IPv6 address
 -j, --junk-session-cookies Ignore session cookies read from file (H)
     --keepalive-time SECONDS  Interval between keepalive probes
     --key KEY       Private key file name (SSL/SSH)
     --key-type TYPE Private key file type (DER/PEM/ENG) (SSL)
     --krb LEVEL     Enable Kerberos with specified security level (F)
     --libcurl FILE  Dump libcurl equivalent code of this command line
     --limit-rate RATE  Limit transfer speed to this rate
 -l, --list-only     List only names of an FTP directory (F)
     --local-port RANGE  Force use of these local port numbers
 -L, --location      Follow redirects (H)
     --location-trusted like --location and send auth to other hosts (H)
 -M, --manual        Display the full manual
     --mail-from FROM  Mail from this address
     --mail-rcpt TO  Mail to this receiver(s)
     --mail-auth AUTH  Originator address of the original email
     --max-filesize BYTES  Maximum file size to download (H/F)
     --max-redirs NUM  Maximum number of redirects allowed (H)
 -m, --max-time SECONDS  Maximum time allowed for the transfer
     --metalink      Process given URLs as metalink XML file
     --negotiate     Use HTTP Negotiate Authentication (H)
 -n, --netrc         Must read .netrc for user name and password
     --netrc-optional Use either .netrc or URL; overrides -n
     --netrc-file FILE  Set up the netrc filename to use
 -N, --no-buffer     Disable buffering of the output stream
     --no-keepalive  Disable keepalive use on the connection
     --no-sessionid  Disable SSL session-ID reusing (SSL)
     --noproxy       List of hosts which do not use proxy
     --ntlm          Use HTTP NTLM authentication (H)
 -o, --output FILE   Write output to <file> instead of stdout
     --pass PASS     Pass phrase for the private key (SSL/SSH)
     --post301       Do not switch to GET after following a 301 redirect (H)
     --post302       Do not switch to GET after following a 302 redirect (H)
     --post303       Do not switch to GET after following a 303 redirect (H)
 -#, --progress-bar  Display transfer progress as a progress bar
     --proto PROTOCOLS  Enable/disable specified protocols
     --proto-redir PROTOCOLS  Enable/disable specified protocols on redirect
 -x, --proxy [PROTOCOL://]HOST[:PORT] Use proxy on given port
     --proxy-anyauth Pick "any" proxy authentication method (H)
     --proxy-basic   Use Basic authentication on the proxy (H)
     --proxy-digest  Use Digest authentication on the proxy (H)
     --proxy-negotiate Use Negotiate authentication on the proxy (H)
     --proxy-ntlm    Use NTLM authentication on the proxy (H)
 -U, --proxy-user USER[:PASSWORD]  Proxy user and password
     --proxy1.0 HOST[:PORT]  Use HTTP/1.0 proxy on given port
 -p, --proxytunnel   Operate through a HTTP proxy tunnel (using CONNECT)
     --pubkey KEY    Public key file name (SSH)
 -Q, --quote CMD     Send command(s) to server before transfer (F/SFTP)
     --random-file FILE  File for reading random data from (SSL)
 -r, --range RANGE   Retrieve only the bytes within a range
     --raw           Do HTTP "raw", without any transfer decoding (H)
 -e, --referer       Referer URL (H)
 -J, --remote-header-name Use the header-provided filename (H)
 -O, --remote-name   Write output to a file named as the remote file
     --remote-name-all Use the remote file name for all URLs
 -R, --remote-time   Set the remote file's time on the local output
 -X, --request COMMAND  Specify request command to use
     --resolve HOST:PORT:ADDRESS  Force resolve of HOST:PORT to ADDRESS
     --retry NUM   Retry request NUM times if transient problems occur
     --retry-delay SECONDS When retrying, wait this many seconds between each
     --retry-max-time SECONDS  Retry only within this period
 -S, --show-error    Show error. With -s, make curl show errors when they occur
 -s, --silent        Silent mode. Don't output anything
     --socks4 HOST[:PORT]  SOCKS4 proxy on given host + port
     --socks4a HOST[:PORT]  SOCKS4a proxy on given host + port
     --socks5 HOST[:PORT]  SOCKS5 proxy on given host + port
     --socks5-basic  Enable username/password auth for SOCKS5 proxies
     --socks5-gssapi Enable GSS-API auth for SOCKS5 proxies
     --socks5-hostname HOST[:PORT] SOCKS5 proxy, pass host name to proxy
     --socks5-gssapi-service NAME  SOCKS5 proxy service name for gssapi
     --socks5-gssapi-nec  Compatibility with NEC SOCKS5 server
 -Y, --speed-limit RATE  Stop transfers below speed-limit for 'speed-time' secs
 -y, --speed-time SECONDS  Time for trig speed-limit abort. Defaults to 30
     --ssl           Try SSL/TLS (FTP, IMAP, POP3, SMTP)
     --ssl-reqd      Require SSL/TLS (FTP, IMAP, POP3, SMTP)
 -2, --sslv2         Use SSLv2 (SSL)
 -3, --sslv3         Use SSLv3 (SSL)
     --ssl-allow-beast Allow security flaw to improve interop (SSL)
     --stderr FILE   Where to redirect stderr. - means stdout
     --tcp-nodelay   Use the TCP_NODELAY option
 -t, --telnet-option OPT=VAL  Set telnet option
     --tftp-blksize VALUE  Set TFTP BLKSIZE option (must be >512)
 -z, --time-cond TIME  Transfer based on a time condition
 -1, --tlsv1         Use => TLSv1 (SSL)
     --tlsv1.0       Use TLSv1.0 (SSL)
     --tlsv1.1       Use TLSv1.1 (SSL)
     --tlsv1.2       Use TLSv1.2 (SSL)
     --tlsv1.3       Use TLSv1.3 (SSL)
     --tls-max VERSION  Use TLS up to VERSION (SSL)
     --trace FILE    Write a debug trace to the given file
     --trace-ascii FILE  Like --trace but without the hex output
     --trace-time    Add time stamps to trace/verbose output
     --tr-encoding   Request compressed transfer encoding (H)
 -T, --upload-file FILE  Transfer FILE to destination
     --url URL       URL to work with
 -B, --use-ascii     Use ASCII/text transfer
 -u, --user USER[:PASSWORD]  Server user and password
     --tlsuser USER  TLS username
     --tlspassword STRING TLS password
     --tlsauthtype STRING  TLS authentication type (default SRP)
     --unix-socket FILE    Connect through this UNIX domain socket
 -A, --user-agent STRING  User-Agent to send to server (H)
 -v, --verbose       Make the operation more talkative
 -V, --version       Show version number and quit
 -w, --write-out FORMAT  What to output after completion
     --xattr        Store metadata in extended file attributes
 -q                 If used as the first parameter disables .curlrc
[root@mx ~]#
curl在Mac和Linux下是自带的命令行工具,如果你也想在Windows上使用,这里推荐使用"git for windows"这个工具,你可以使用此关键字在网络上检索下载。


安装完成后,点击桌面的"Git Bash"后,就可以在Windows下使用curl命令行工具了。

基本用法
curl是http工具,最简单的使用方法就是直接搭配网址使用,比如请求百度的内容:

[root@mx ~]# curl www.baidu.com

-s 选项:
加上此选项,不显示请求内容的进度信息。

-o 选项:
将获取内容存储到本地文件,-o后接文件名,如把请求的内容存储到1.txt中
# 搭配-s选项一起使用
[root@mx ~]# curl -s https://www.baidu.com -o 1.txt
# 不使用-s时,显示进度信息
[root@mx ~]# curl  https://www.baidu.com -o 2.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2443  100  2443    0     0  14183      0 --:--:-- --:--:-- --:--:-- 14203
[root@mx ~]# cat 1.txt
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head
......
[root@mx ~]#

详细用法
-A 选项:
-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]。下面命令将User-Agent改成 Chrome 浏览器。

$ curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com下面命令会移除User-Agent标头。

$ curl -A '' https://google.com
也可以通过-H参数直接指定标头,更改User-Agent。

$ curl -H 'User-Agent: php/1.0' https://google.com
-b 选项:
-b参数用来向服务器发送 Cookie。

$ curl -b 'foo=bar' https://google.com
上面命令会生成一个标头Cookie: foo=bar,向服务器发送一个名为foo、值为bar的 Cookie。

$ curl -b 'foo1=bar;foo2=bar2' https://google.com
上面命令发送两个 Cookie。

$ curl -b cookies.txt https://www.google.com
上面命令读取本地文件cookies.txt,里面是服务器设置的 Cookie(参见-c参数),将其发送到服务器。

-c 选项:
-c参数将服务器设置的 Cookie 写入一个文件。

$ curl -c cookies.txt https://www.google.com
上面命令将服务器的 HTTP 回应所设置 Cookie 写入文本文件cookies.txt。

-d 选项:
-d参数用于发送 POST 请求的数据体。

$ curl -d'login=emma&password=123'-X POST https://google.com/login
#或者
$ curl -d 'login=emma' -d 'password=123' -X POST  https://google.com/login
使用-d参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略-X POST。

-d参数可以读取本地文本文件的数据,向服务器发送。

$ curl -d '@data.txt' https://google.com/login
上面命令读取data.txt文件的内容,作为数据体向服务器发送。

--data-urlencode--data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。

$ curl --data-urlencode 'comment=hello world' https://google.com/login
上面代码中,发送的数据hello world之间有一个空格,需要进行 URL 编码。

-e 选项:
-e参数用来设置 HTTP 的标头Referer,表示请求的来源。

curl -e 'https://google.com?q=example' https://www.example.com
上面命令将Referer标头设为https://google.com?q=example。

-H参数可以通过直接添加标头Referer,达到同样效果。

引用curl -H 'Referer: https://google.com?q=example' https://www.example.com
-F 参数:
-F参数用来向服务器上传二进制文件。

$ curl -F 'file=@photo.png' https://google.com/profile
上面命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。

-F参数可以指定 MIME 类型。

$ curl -F 'file=@photo.png;type=image/png' https://google.com/profile
上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream。

-F参数也可以指定文件名。

$ curl -F 'file=@photo.png;filename=me.png' https://google.com/profile
上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png。

-G 选项:
-G参数用来构造 URL 的查询字符串。

$ curl -G -d 'q=kitties' -d 'count=20' https://google.com/search
上面命令会发出一个 GET 请求,实际请求的 URL 为https://google.com/search?q=kitties&count=20。如果省略--G,会发出一个 POST 请求。

如果数据需要 URL 编码,可以结合--data--urlencode参数。

$ curl -G --data-urlencode 'comment=hello world' https://www.example.com
-H 选项:
-H参数添加 HTTP 请求的标头。

$ curl -H 'Accept-Language: en-US' https://google.com
上面命令添加 HTTP 标头Accept-Language: en-US。

$ curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com
上面命令添加两个 HTTP 标头。

$ curl -d '{"login": "emma", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login
上面命令添加 HTTP 请求的标头是Content-Type: application/json,然后用-d参数发送 JSON 数据。

-i 选项:
-i参数打印出服务器回应的 HTTP 标头。

$ curl -i https://www.example.com
上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。

-I 选项:
-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。

$ curl -I https://www.example.com
上面命令输出服务器对 HEAD 请求的回应。

--head参数等同于-I。

$ curl --head https://www.example.com
-k 参数:
-k参数指定跳过 SSL 检测。

$ curl -k https://www.example.com
上面命令不会检查服务器的 SSL 证书是否正确。

-L 参数:
-L参数会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向。

$ curl -L -d 'tweet=hi' https://api.twitter.com/tweet
--limit-rate 选项:
--limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。

$ curl --limit-rate 200k https://google.com
上面命令将带宽限制在每秒 200K 字节。

-o 选项:
-o参数将服务器的回应保存成文件,等同于wget命令。

$ curl -o example.html https://www.example.com
上面命令将www.example.com保存成example.html。

-O 选项:
-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。

$ curl -O https://www.example.com/foo/bar.html
上面命令将服务器回应保存成文件,文件名为bar.html。

-s 选项:
-s参数将不输出错误和进度信息。

$ curl -s https://www.example.com
上面命令一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。

如果想让 curl 不产生任何输出,可以使用下面的命令。

$ curl -s -o /dev/null https://google.com
-S 选项:
-S参数指定只输出错误信息,通常与-s一起使用。

$ curl -s -o /dev/null https://google.com
上面命令没有任何输出,除非发生错误。

-u 选项:
-u参数用来设置服务器认证的用户名和密码。

$ curl -u 'bob:12345' https://google.com/login
上面命令设置用户名为bob,密码为12345,然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。

curl 能够识别 URL 里面的用户名和密码。

$ curl https://bob:12345@google.com/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。

$ curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。

-v 选项:
-v参数输出通信的整个过程,用于调试。

$ curl -v https://www.example.com
--trace参数也可以用于调试,还会输出原始的二进制数据。

$ curl --trace - https://www.example.com
-x 选项:
-x参数指定 HTTP 请求的代理。

$ curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com
上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。

如果没有指定代理协议,默认为 HTTP。

$ curl -x james:cats@myproxy.com:8080 https://www.example.com
上面命令中,请求的代理使用 HTTP 协议。

-X 选项:
-X参数指定 HTTP 请求的方法。

$ curl -X POST https://www.example.com
上面命令对https://www.example.com发出 POST 请求。
#53
PHP 开发 / PHP CURL中CURLOPT_CONNECTTIMEOU...
上次发布者 cloud - 2022-5月-23 03:11 下午
写了一个简单的curl请求

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //限制响应时间200毫秒
$data = curl_exec($ch);
curl_close($ch);

再A服务器运行没有然后问题,到了B服务器发现$data返回false
这就令我百思不得其解了?
来我们开始排坑

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //限制响应时间200毫秒
$data = curl_exec($ch);
if($data === false){ //抓取错误信息
     print_r('---------------------start------------------------'.PHP_EOL);
     var_dump(curl_errno($ch));
     var_dump(curl_error($ch));
     print_r('---------------------end------------------------');
    exit();
}
curl_close($ch);
然后我们发现它告诉我们errno:28 超时了!!!
超时了那好解决啊,想当然的我把超时时间从200ms提升倒了600ms,要知道我们这个接口测试的时候是直接绑定host,响应也是直接返回一个json数据.600ms绝对足够了.

curl_setopt($ch, CURLOPT_TIMEOUT_MS, 600); //限制响应时间600毫秒
还是超时!
这就有点不对劲了!
继续修改时间

curl_setopt($ch, CURLOPT_TIMEOUT, 1); //限制响应时间1秒
成功了!那么问题就出在CURLOPT_TIMEOUT_MS上面了!

原来 CURLOPT_CONNECTTIMEOUT_MS 的等待的时间,以毫秒为单位。
真确的开启方式是

    curl_setopt($ch, CURLOPT_NOSIGNAL, true);//libcurl支持毫秒
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
#54
PHP框架-Yii / 数据格式
上次发布者 jvip_chen - 2022-5月-22 05:38 下午
数据格式取决于 HTTP 消息内容组合或解析的方式,例如: 它将确定 yii\httpclient\Message::$data 通过何种方式转换为 yii\httpclient\Message::$content,反之亦然。

默认情况下支持以下格式:

  • yii\httpclient\Client::FORMAT_JSON - JSON format
  • yii\httpclient\Client::FORMAT_URLENCODED - urlencoded by RFC1738 query string
  • yii\httpclient\Client::FORMAT_RAW_URLENCODED - urlencoded by PHP_QUERY_RFC3986 query string
  • yii\httpclient\Client::FORMAT_XML - XML format
每个格式由2个实体覆盖: "formatter" 和 "parser" 。 Formatter 决定请求中数据的组成方式。 Parser 决定如何将原始响应内容解析为数据。

yii\httpclient\Client 自动为上述所有格式选择相应的 formatter 和 parser 。 但是,可以使用 yii\httpclient\Client::$formatters 和 yii\httpclient\Client::$parsers 更改此行为。 可以使用这些字段添加自定义格式或更改标准的格式。 例如:

use yii\httpclient\Client;

$client = new Client([
    'formatters' => [
        'myformat' => 'app\components\http\MyFormatter', // add new formatter
        Client::FORMAT_XML => 'app\components\http\MyXMLFormatter', // override default XML formatter
    ],
]);
在创建自定义的解析器时,应该实现 yii\httpclient\ParserInterface ,同时创建formatter - yii\httpclient\FormatterInterface。 例如:

use yii\httpclient\FormatterInterface;
use yii\httpclient\ParserInterface;
use yii\httpclient\Response;

class ParserIni implements ParserInterface
{
    public function parse(Response $response)
    {
        return parse_ini_string($response->content);
    }
}

class FormatterIni implements FormatterInterface
{
    public function format(Request $request)
    {
        $request->getHeaders()->set('Content-Type', 'text/ini   ; charset=UTF-8');

        $pairs = []
        foreach ($request->data as $name => $value) {
            $pairs[] = "$name=$value";
        }

        $request->setContent(implode("\n", $pairs));
        return $request;
    }
}
#55
PHP框架-Yii / 批量 request 请求
上次发布者 jvip_chen - 2022-5月-22 05:37 下午
可以使用 yii\httpclient\Client::batchSend() 方法同时发送多个请求:

use yii\httpclient\Client;

$client = new Client();

$requests = [
    $client->get('http://domain.com/keep-alive'),
    $client->post('http://domain.com/notify', ['userId' => 12]),
];
$responses = $client->batchSend($requests);
可使用特定的 传输方式 提升其性能。 在内置传输中,只有 yii\httpclient\CurlTransport 允许并行发送请求,从而减少程序执行时间。

注意:只有某些特定的传输传输方式可以使用 batchSend() 并行发送请求。 默认情况下,请求只是一个接一个地发送,没有任何错误或警告抛出。如果需要提升性能 ,则需为客户端配置正确的传输方式。

batchSend() 方法返回响应数组,这些键对应于请求数组中的键。 可以使用如下方式简化响应的处理:

use yii\httpclient\Client;

$client = new Client();

$requests = [
    'news' => $client->get('http://domain.com/news'),
    'friends' => $client->get('http://domain.com/user/friends', ['userId' => 12]),
    'newComment' => $client->post('http://domain.com/user/comments', ['userId' => 12, 'content' => 'New comment']),
];
$responses = $client->batchSend($requests);

// result of `GET http://domain.com/news` :
if ($responses['news']->isOk) {
    echo $responses['news']->content;
}

// result of `GET http://domain.com/user/friends` :
if ($responses['friends']->isOk) {
    echo $responses['friends']->content;
}

// result of `POST http://domain.com/user/comments` :
if ($responses['newComment']->isOk) {
    echo "Comment has been added successfully";
}
#56
PHP框架-Yii / Request 参数
上次发布者 jvip_chen - 2022-5月-22 05:36 下午
使用 yii\httpclient\Request::$options 来调整特定的请求。 支持以下参数:

  • timeout: integer, 允许执行请求的最大超时时间(秒)。
  • proxy: string, 指定代理服务器的地址的 URI。(例如 tcp://proxy.example.com:5100)
  • userAgent: string, 在 HTTP 请求中使用的 "User-Agent:" 标头的内容。
  • followLocation: boolean, 是否重定向至 HTTP 头信息中的任意 "Location:"。
  • maxRedirects: integer, 要跟踪的重定向的最大数量。
  • sslVerifyPeer: boolean, 是否启用 ssl 验证。
  • sslCafile: string, CA 证书在本地文件系统上的位置,应与 'sslVerifyPeer' 参数一起使用以验证服务端的身份。
  • sslCapath: string, 一个保存多个CA证书的目录。
例如:

use yii\httpclient\Client;

$client = new Client();

$response = $client->createRequest()
    ->setMethod('POST')
    ->setUrl('http://domain.com/api/1.0/users')
    ->setData(['name' => 'John Doe', 'email' => 'johndoe@domain.com'])
    ->setOptions([
        'proxy' => 'tcp://proxy.example.com:5100', // use a Proxy
        'timeout' => 5, // set timeout to 5 seconds for the case server is not responding
    ])
    ->send();
提示:可以通过 yii\httpclient\Client::$requestConfig 对默认请求进行设置。 可以使用 yii\httpclient\Request::addOptions() 在添加其他设置的同时保留原始的其他参数。

在使用 yii\httpclient\CurlTransport 时,可配置特殊的请求参数。 例如:指定 cUrl 请求的连接和接收数据的超时时间:

use yii\httpclient\Client;

$client = new Client([
    'transport' => 'yii\httpclient\CurlTransport' // only cURL supports the options we need
]);

$response = $client->createRequest()
    ->setMethod('POST')
    ->setUrl('http://domain.com/api/1.0/users')
    ->setData(['name' => 'John Doe', 'email' => 'johndoe@domain.com'])
    ->setOptions([
        CURLOPT_CONNECTTIMEOUT => 5, // connection timeout
        CURLOPT_TIMEOUT => 10, // data receiving timeout
    ])
    ->send();
有关特定参数支持的详细信息,请参阅特定的传输类文档。
#57
PHP 开发 / PHP——curl使用代理
上次发布者 jvip_chen - 2022-5月-22 04:08 下午
代码样例
使用代理

<?php
//要访问的目标页面
$page_url "http://dev.kdlapi.com/testproxy";

//代理ip,由快代理提供
$proxy "47.115.5.19";
$prod 16816;

$ch curl_init();
curl_setopt($chCURLOPT_URL$page_url);

curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);  
curl_setopt($chCURLOPT_SSL_VERIFYHOSTFALSE);

//设置代理
curl_setopt($chCURLOPT_PROXYTYPECURLPROXY_HTTP);
curl_setopt($chCURLOPT_PROXY$proxy);
curl_setopt($chCURLOPT_PROXYPORT$prod); 

//自定义header
$headers = array();
$headers[] = 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0);';
curl_setopt($chCURLOPT_HTTPHEADER$headers);

//自定义cookie
curl_setopt($chCURLOPT_COOKIE,''); 

curl_setopt($chCURLOPT_ENCODING'gzip'); //使用gzip压缩传输数据让访问更快

curl_setopt($chCURLOPT_CONNECTTIMEOUT5);
curl_setopt($chCURLOPT_TIMEOUT10);

curl_setopt($chCURLOPT_HEADERtrue);
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

$result curl_exec($ch);
$info curl_getinfo($ch);
curl_close($ch);

echo 
$result;
echo 
"\n\nfetch ".$info['url']."\ntimeuse: ".$info['total_time']."s\n\n";
?>
运行下
php curl.php
#58
Linux 系统 / Supervisor使用详解
上次发布者 cloud - 2022-5月-15 10:33 下午
一、supervisor简介
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。

注:本文以centos7为例,supervisor版本3.4.0。

二、supervisor安装
配置好yum源后,可以直接安装
yum install supervisor
Debian/Ubuntu可通过apt安装
apt-get install supervisor
pip安装
pip install supervisor
easy_install安装
easy_install supervisor
三、supervisor使用
supervisor配置文件:/etc/supervisord.conf
注:supervisor的配置文件默认是不全的,不过在大部分默认的情况下,上面说的基本功能已经满足。

子进程配置文件路径:/etc/supervisord.d/
注:默认子进程配置文件为ini格式,可在supervisor主配置文件中修改。

四、配置文件说明
supervisor.conf配置文件说明:
[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ;socket文件的mode,默认是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid
 
;[inet_http_server]         ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              ;登录管理后台的用户名
;password=123               ;登录管理后台的密码
 
[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ;可以打开的进程数的最小值,默认 200
 
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord
 
; [program:xx]是被管理的进程配置参数,xx是进程的名称
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序启动命令
autostart=true       ; 在supervisord启动的时候也自动启动
startsecs=10         ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true     ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3       ; 启动失败自动重试次数,默认是3
user=tomcat          ; 用哪个用户启动进程,默认是root
priority=999         ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20   ; stdout 日志文件备份数,默认是10
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false     ;默认为false,向进程组发送kill信号,包括子进程
 
;包含其它配置文件
[include]
files = relative/directory/*.ini    ;可以指定一个或多个以.ini结束的配置文件
子进程配置文件说明:
给需要管理的子进程(程序)编写一个配置文件,放在/etc/supervisor.d/目录下,以.ini作为扩展名(每个进程的配置文件都可以单独分拆也可以把相关的脚本放一起)。如任意定义一个和脚本相关的项目名称的选项组(/etc/supervisord.d/test.conf):
#项目名
[program:blog]
#脚本目录
directory=/opt/bin
#脚本执行命令
command=/usr/bin/python /opt/bin/test.py

#supervisor启动的时候是否随着同时启动,默认True
autostart=true
#当程序exit的时候,这个program不会自动重启,默认unexpected,设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1

#脚本运行的用户身份
user = test

#日志输出
stderr_logfile=/tmp/blog_stderr.log
stdout_logfile=/tmp/blog_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true
#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
子进程配置示例:
#说明同上
[program:test]
directory=/opt/bin
command=/opt/bin/test
autostart=true
autorestart=false
stderr_logfile=/tmp/test_stderr.log
stdout_logfile=/tmp/test_stdout.log
#user = test 
五、supervisor命令说明
常用命令
supervisorctl status        //查看所有进程的状态
supervisorctl stop es       //停止es
supervisorctl start es      //启动es
supervisorctl restart       //重启es
supervisorctl update        //配置文件修改后使用该命令加载新的配置
supervisorctl reload        //重新启动配置中的所有程序
注:把es换成all可以管理配置中的所有进程。直接输入supervisorctl进入supervisorctl的shell交互界面,此时上面的命令不带supervisorctl可直接使用。

注意事项
使用supervisor进程管理命令之前先启动supervisord,否则程序报错。
使用命令supervisord -c /etc/supervisord.conf启动。
若是centos7:
systemctl start supervisord.service     //启动supervisor并加载默认配置文件
systemctl enable supervisord.service    //将supervisor加入开机启动项
常见问题
unix:///var/run/supervisor.sock no such file
问题描述:安装好supervisor没有开启服务直接使用supervisorctl报的错
解决办法:supervisord -c /etc/supervisord.conf

command中指定的进程已经起来,但supervisor还不断重启
问题描述:command中启动方式为后台启动,导致识别不到pid,然后不断重启,这里使用的是elasticsearch,command指定的是$path/bin/elasticsearch -d
解决办法:supervisor无法检测后台启动进程的pid,而supervisor本身就是后台启动守护进程,因此不用担心这个

启动了多个supervisord服务,导致无法正常关闭服务
问题描述:在运行supervisord -c /etc/supervisord.conf之前,直接运行过supervisord -c /etc/supervisord.d/xx.conf导致有些进程被多个superviord管理,无法正常关闭进程。
解决办法:使用ps -fe | grep supervisord查看所有启动过的supervisord服务,kill相关的进程。

#59
Ubuntu / Ubuntu操作-04 SUDO设置
上次发布者 jvip_chen - 2022-5月-09 03:02 下午
在sudo于1980年前后被写出之前,一般用户管理系统的方式是利用su切换为超级用户。但是使用su的缺点之一在于必须要先告知超级用户的密码,而sudo使一般用户不需要知道超级用户的密码即可获得权限。

1 授权普通用户执行root指令
授权普通用户执行root指令,就需要在/etc/sudoers文件中进行配置(或者直接使用visudo命令,不过只能在root用户下执行):

[root@test-huanqiu ~]# visudo
.....
# User privilege specification
pang ALL=(ALL) ALL

1.1 参数解释
第一个字段zhangj指定的是用户:可以是用户名,也可以是别名。每个用户设置一行,多个用户设置多行,也可以将多个用户设置成一个别名后再进行设置。
第二个字段ALL指定的是用户所在的主机:可以是ip,也可以是主机名,表示这个sudo设置后的文件即/etc/sudoers只在这个主机上生效,ALL表示在所有主机上都生效!限制的一般都是本机,也就是限制使用这个文件的主机;如果指定为"192.168.1.88"表示这个文件只有在这台主机上生效,如果拷贝到别的机子上是不起作用的!一般都指定为"ALL"表示所有的主机,不管文件拷到那里都可以用。
第三个字段(ALL)括号里指定的也是用户:指定以什么用户身份执行sudo,即使用sudo后可以享有所有账号下的权限。如果要排除个别用户,可以在括号内设置,比如ALL=(ALL,!root,!ops)。也可以设置别名
第四个字段ALL指定的是执行的命令:即使用sudo后可以执行所有的命令。也可以设置别名。NOPASSWD: ALL表示使用sudo的不需要输入密码。这里指令要用绝对路径
1.2 示例
如果我们想让用户pang只能在本主机(主机名为localhost)以root账户执行/bin/chown、/bin/chmod 两条命令,那么就应该这样配置:

[root@test-huanqiu ~]# visudo
.......
# User privilege specification
pang localhost=(root) /bin/chown,/bin/chmod

如果用户pang登录之后运行sudo命令,不满足上面三个条件之一的操作都将失败。

2 免密操作
安全是安全了,但很麻烦,每次执行指令都要输入密码,若要消除密码输入操作,修改配置文件:

2.1 使用root用户 visudo
#这里的NOPASSWD就是配置支持免密执行的字段
pang       ALL=(root)      NOPASSWD:/usr/bin/vim     
       

这里设置的是vim指令能够无密码执行!

2.2 手工修改/etc/sudoers文件
# 切换至root用户
sudo su - root
# 修改/etc/sudoers文件权限
chmod 744 /etc/sudoers
# 修改/etc/sudoers文件,添加如下内容,ubuntu为当前用户
ubuntu    ALL=(ALL:ALL) NOPASSWD:ALL
# 保存,并恢复权限
chmod 440 /etc/sudoers
# 重启系统
reboot
新启动一个terminal, 测试没有生效。
原因: 设了nopasswd,但是不起作用,原因是被后面的group的设置覆盖了。改为添加在文件最后一行即可。
# User privilege specification
root ALL=(ALL:ALL) ALL
pang ALL=(ALL:ALL) NOPASSWD:ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
pang    ALL=(ALL:ALL) NOPASSWD:ALL

3 授权给用户组
[root@test-huanqiu ~]# visudo
.....
# Allow members of group sudo to execute any command
# (Note that later entries override this, so you might need to move it further down)
%sudo ALL=(ALL) ALL
和授权给单个用户类似,只不过将用户名在这里换成%组名,所有在该组中的用户都按照此规则进行授权。

对于该例,所有在sudo组内的用户都有在任何终端(第一个ALL)、以任何用户(第二个ALL)、执行任何命令(第三个ALL)的权限,查看/etc/group文件可以知道哪些用户属于 sudo组。

4 操作技巧
4.1 执行root命令忘记加sudo:
输入一个长长的命令,按Enter之后出现无权限操作,因为在命令前面忘记加sudo了。
大多人的做法是按 ↑ 回到上一条命令,在该命令之前加上sudo,再执行该命令。
其实,也大可不必这样,巧妙的做法是:
只要输入 sudo !! 即可,这里的 !! 代表上一条命令。如:

[pang@localhost ~]$ cat test
cat: test: Permission denied
[pang@localhost ~]$ sudo !!
sudo cat test
lala
xiixixi'
nihao

即拿到了test文件的内容!

4.2 shell内置命令无法使用sudo
shell是一个交互式的应用程序,在执行外部命令时通过fork来创建一个子进程,再通过exec来加载外部命令的程序来执行。
但是如果一个命令是shell内置命令,那么只能直接由shell 来运行。
sudo 的意思是,以别的用户(如root)的权限来fork一个进程,加载程序并运行,因此sudo后面不能跟shell 的内置命令。\

[pang@localhost ~]$ sudo cd /sys/kernel/debug/
sudo: cd: command not found

此时应使用:

[pang@localhost ~]$ sudo bash   //或者sudo su - 或者 sudo -s,其实就使用sudo命令从当前用户切换到root用户
[root@localhost debug]# cd /sys/kernel/debug/
[root@localhost debug]#
4.3 sudo操作记入日志
作为一个Linux系统的管理员,不仅可以让指定的用户或用户组作为root用户或其它用户来运行某些命令,还能将指定的用户所输入的命令和参数作详细的记录。
而sudo的日志功能就可以用户跟踪用户输入的命令,这不仅能增进系统的安全性,还能用来进行故障检修。

创建sudo日志文件
[pang@localhost ~]$ sudo touch /var/log/sudo.log
修改/etc/rsyslog.conf配置文件(有些版本系统的这个文件名为/etc/syslog.conf),在该文件加入下面一行
[pang@localhost ~]$ sudo vim /etc/rsyslog.conf
.........
local2.debug /var/log/sudo.log //空白不能用空格,必须用tab

修改/etc/sudoers 配置文件
[pang@localhost ~]$ sudo vim /etc/sudoers
........
Defaults logfile=/var/log/sudo.log
重启 syslog 服务
[pang@localhost ~]$ sudo service rsyslog restart
验证
经过上面的配置,sudo的所有成功和不成功的sudo命令都记录到文件/var/log/sudo.log 中。
4.4 为多个用户分配不同的组:
在root用户的情况下,编辑/etc/group文件,这个文件就是控制系统的组和用户所属组情况的。

groupadd sudo                 #因为没有指定gid,所以就按着文件中的gid往后推的
sudo:x:504:                    #添加完之后在该文件中就出现了这条字段。

修改为:

sudo:x:504:batman,test            #此时,用户batman和test的附属组就是sudo了
此时再visudo

%sudo   ALL=(root)      NOPASSWD:/usr/bin/vim
%sudo   ALL=(root)      NOPASSWD:/bin/cat

保存退出,可以用:visudo -c来检查语法,返回OK,没问题。
检测:

-rw-------. 1 root root 1595 Jul 24 05:00 rsyncd.conf
-rw-------. 1 root root    8 Jul 24 05:00 rsyncd.pass
-rw-------. 1 root root   14 Jul 24 05:00 rsyncd.pwd

这三个文件,只有root有操作权限,现在

[pang@localhost]$ sudo vim rsyncd.conf
发现也是ok的。

5 sudo问题记录
手工修改/etc/sudoers时,如果不注意操作会导致一些问题产生,特此记录。

5.1 错误修改/etc/sudoers所属用户后恢复
在修改设置sudo免密码时,无意将chmod 440 /etc/sudoers改为了chown 440 /etc/sudoers后,导致系统重启后无法使用sudo命令。

解决方法:

(1) 重启电脑,进入ubuntu 恢复模式Grub(一直按esc或shift)
(2) 在Grub的菜单中选择root
(3) 重新输入命令 chown root /etc/sudoers
(4) reboot
#60
Ubuntu / 通过PHP执行系统命令
上次发布者 jvip_chen - 2022-5月-09 02:56 下午
PS.这几天用PHP写了一个小工具,因为要部署在Linux,又要暂时使用sudo执行一些Shell命令,网上也有很多资料,但是有的要么就直接把Web服务器用户直接提升权限,要么就使用密码存文件方式,安全性都不是特别好,好在搜索到在Wordpress上一位外国友人的文章,很实用,安全性也不错,就把它翻译过来和大家分享一下,下面是正文部分。

  许多时候我们需要在Linux系统上执行系统命令--比如来删除一个目录或者重启服务。但是,因为Apache并不是以root权限运行的,这样使用PHP的exec()、system()或者passthru()函数来实现以上功能就变得不太可能。

  解决这个问题的方案是非常简单的,特别是在Ubuntu上。Apache的用户www-data需要获得权限来使用sudo执行一些应用。

  1、执行命令

command sudo visudo
  2、在文件末尾,增加如下内容

www-data ALL=NOPASSWD: /sbin/iptables, /usr/bin/du
  假设你希望使用超级用户(root)权限运行iptables和du命令。但是,如果你想使用超级用户权限运行每一个应用,添加以下命令来代替上面的命令。 

www-data ALL=NOPASSWD: ALL
  3、就是这样,现在像下面这种方式在你的php脚本中使用exec()函数

exec("sudo iptables -P FORWARD ACCEPT");
  这使我能够在服务器上执行脚本,这个脚本我早先不得不使用setuid和联合是否为cron的方式。但是现在,PHP使这变得方便。
PS.

1、修改sudoers还有另外一种方式,使用 vi /etc/sudoers,在此之前要 sudo chmod u+w /etc/sudoers,获取权限。

2、如果要让PHP运行我们自己写的脚本,我在Google上看到用这个方法也是可以的。例如:www-data ALL=NOPASSWD: /tmp/script.sh

     要写明sh文件的具体位置