我正在寻找一种类似于终端的东西,但可以让我通过 http 与服务器进行“对话”。像这样的东西:
$ connect http://myserver.com
Welcome to myserver.com
Options
A - Fribble the obsticator
B - List Frogits
C - Show the log
Q - Quit
$ A
Obsticator fribbled
blah blah
blah
$ C
Log file
...
$ Q
Bye
我并不是在寻找任何通过 http 隧道传输实际 Unix 命令行的聪明方法。也不是文本模式浏览器。这将与一个简单的自定义服务器通信,该服务器知道它正在以这种方式访问,并且将返回纯文本,而不是 html。
但它必须通过 http,而不是不同的协议。我不想做类似卷曲的命令
$ curl http://myserver.com?opt=A
它应该能够捕获一次 URL。将命令转换为 CGI 参数对于用户来说应该是透明的。
更新:另外,我不介意在单个连接中保持此对话打开,发送和接收的每个命令都可以是单独的 http 请求。 (事实上,这样更好,因为它允许服务器更简单)
更新 2:我想要这个的原因是我想使用 Python Hug 构建一个简单的小型 Web 服务 API(http://www.hug.rest/)但是直接从命令行而不是浏览器访问它的一些操作会很方便。
与其增加额外的复杂性(在服务器上使用不同的协议并管理单独的交互侦听器),不如使用一个简单的命令行客户端通过标准 http 请求与 API 进行交互。
那么,有这样的事情吗? (在我坐下来写一篇之前。)
答案1
您可以使用 telnet 连接到服务器,并且知道(我在这里假设您想要使用 Web 服务器进行通信)您需要在 HTTP 规范的约束下进行操作。
例如规格 https://www.w3.org/Protocols/rfc2616/rfc2616.txt
状态:
源服务器必须在所有响应中包含日期标头字段,但以下情况除外:...
这是我通过 telnet 与网络服务器进行的“对话”的终端输出。
请记住,网络服务器配置将确定 TCP 连接保持活动状态的时间 - 即,在服务器因“不活动”而切断 TCP 连接之前,您必须键入正确格式的 HTTP 请求的时间。但这是可配置的。
如果您在超时之前输入每个请求,则实际上将通过单个连续 TCP 连接发送许多 HTTP 请求和响应。
% telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1 <---- this in where you type characters "interactively"
Host: localhost <---- this in where you type characters "interactively"
<-- per the HTTP specification this has to be an emtpy line
to tell the server you are done with your "message"
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 17 Sep 2016 07:38:08 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
45d
<html>
[truncated ... ]
</html>
0
GET / HTTP/1.1 <-- now you are back at prompt
Host: localhost Note: you need to enter the `Host` header if you are talking
to a webserver
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 17 Sep 2016 07:41:07 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
45d
<html>
[truncated]
显然,为了获得更清晰的“对话”,您需要清理网络服务器或处理请求的应用程序的输出。
nginxttp_core_module
负责管理默认类型,使用
http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type
要添加标题,您可以使用http_headers_module
http://nginx.org/en/docs/http/ngx_http_headers_module.html
答案2
只要您不介意用作curl
后端,并且您只是不想每次都输入整个 URL,您就可以curl
循环运行,如下所示:
read -p "Server name: " s && curl -fs "$s" && while true; do read -p "$ " x && curl -fs "$s?opt=${x^^}" || break; done
alias
如果您不想每次都输入或粘贴整个内容,那么它也非常适合。
那里没有太多的错误检查,如果您只是想要一种简单的方法来与您自己的受信任服务器通信并且不想尝试破解您自己的脚本,那么这可能没问题。更高级的脚本可以验证服务器名称或在显示返回的网页之前尝试解析它们,当然双方都应该防御不受信任的输入。
我添加了两个选项到curl
:
-f
21
如果网页返回错误400
或以上错误,将退出并显示错误代码(对于quit
命令有用)-s
静默模式不会显示每个命令的连接数据。
除此之外,您将准确地看到服务器为每个查询输出的内容。
答案3
好的。
受到 @drewbenn 的回答的启发,我自己用 Python 编写了它,使用请求 (http://requests.readthedocs.io/en/master/) 图书馆 :
import requests
import sys
url = sys.argv[1]
print "Connecting ", url
r = requests.get(url)
print r.text
flag = True
while flag :
s = raw_input()
data = {"opt": s}
r = requests.get(url, params=data)
print r.text
答案4
如果它是 RESTful HTTP API,特别是 HATEOAS 品种,那么您可以使用 Spring 的 Rest-shell
https://github.com/spring-projects/rest-shell
用法示例:
http://localhost:8080:> discover
rel href
========================================================
address http://localhost:8080/address
family http://localhost:8080/family
people http://localhost:8080/person
profile http://localhost:8080/profile
http://localhost:8080:> follow people
http://localhost:8080/person:> list
rel href
===================================================
people.Person http://localhost:8080/person/1
people.Person http://localhost:8080/person/2
people.search http://localhost:8080/person/search
http://localhost:8080/person:> get 1
...