使用Bash脚本实现Web服务CGI
来源:互联网 发布:h5界面设计软件 编辑:程序博客网 时间:2024/05/01 17:38
2014-01-09 wcdj
之前总结过一篇使用Perl实现Web服务的文章《Web服务器的实现(最小的Perl Web服务器) 》。在工作中经常需要和CGI接口进行交互,当依赖的接口还未实现时,自己可以写一个简单的CGI接口来模拟依赖的接口以完成调试。Bash也是日常使用的脚本之一,本文总结如何使用Bash实现简单的CGI交互。
0 实现一个返回json格式应答的CGI
#!/bin/bashecho "Content-type: text/html"echo ""# ok, we've sent the header, now send some contentecho "{\"ret\":0,\"msg\":\"ok\"}"测试方法:
将上述的Bash脚本放在Websvr下,可以通过curl命令发送http请求,例如:curl "http://172.25.81.16/cgi-bin/ret_json_ok.sh",然后会返回:{"ret":0,"msg":"ok"}。
1 实现一个form来发送http请求
效果如下图所示:
(1) 写一个简单的html页面,例如,form.html
<FORM ACTION="/cgi-bin/form_test.sh">Enter Host: <INPUT name="host"><INPUT TYPE=SUBMIT VALUE="Submit"></FORM>(2) 写一个接收请求的CGI,上面的ACTION已指定,即,form_test.sh
#!/bin/bashecho 'Content-type: test/html'echo ''echo $QUERY_STRING
2 实现一个返回html页面,标题和内容都为Hello World
返回的页面效果如下图:实现方法,同样实现一个CGI,只是返回的内容是一个html:
#!/bin/bashecho 'Content-type: test/html'echo ''echo '<html>'echo '<head>'echo '<meta http-equiv="Content-Type" content="text/html; charst=UTF-8">'echo '<title>Hello World</title>'echo '</head>'echo '<body>'echo 'Hello World'echo '</body>'echo '</html>'exit 0
3 温故知新
通过上面几个非常简单的例子,下面总结一些基本概念:(1) Introduction to CGI
Web CGI programs can be written in any language which can process standard input (stdin),environment variables and write to standard output (stdout).The web server will interact with all CGI programs using the "Common Gateway Interface" (CGI) standard as set by RFC 3875. This capability is possessed by most modern computer programming and scripting languages, including the bash shell.
(2) Basic Bash CGI Example
CGI programs typically perform the following:
- All CGI scripts must write out a header used by the browser to identify the content.
- They typically process some input. (URL, form data or ISINDEX)
- CGI can access environment variables set by the web server.
- CGI scripts will write out HTML content to be viewed. This typically has the structure of the "head" which contains non-viewable content and "body" which provides the viewable content.
Script Location:
Various distributions of Linux locate the CGI directory in different directory paths. The path is set by the web server configuration file. For the Apache web server, the "ScriptAlias" directive defines the CGI path:Script Permissions:
The script will require system executable permissions: chmod +x /var/www/cgi-bin/hello.shIf using SELinux, the security context must also permit execution: chcon -t httpd_sys_content_t /var/www/cgi-bin/hello.sh
Executing Shell Commands:
Typically one will want to process shell or system commands:
Add the paths required to find the commands:(3) Processing Bash CGI Input
Accessing Environment Variables:
The web server will pass environment variables to the CGI which it can access and use. This is very simple for bash.#!/bin/bash echo "Content-type: text/html"echo "" echo '<html>'echo '<head>'echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'echo '<title>Environment Variables</title>'echo '</head>'echo '<body>'echo 'Environment Variables:'echo '<pre>'/usr/bin/envecho '</pre>' echo '</body>'echo '</html>' exit 0
Typically one will want to process input from the URL "QUERY_STRING" such as "namex=valuex&namey=valuey&namez=valuez" extracted from the following URL:http://localhost/cgi-bin/env.sh?namex=valuex&namey=valuey&namez=valuez
Script Description:- Script will loop through all of the arguments in environment variable "QUERY_STRING" as separated by the delimiter "&". Thus the script loops three times with the following "Args":
- namex=valuex
- namey=valuey
- namez=valuez
- For each "Args" line, look for each token separated by the delimeter "=". Component 1 ($1) and component 2 ($2).
- Use "sed" to parse and substitute characters. A blank space is substituted for all %20's.
#!/bin/bash echo "Content-type: text/html"echo "" echo '<html>'echo '<head>'echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'echo '<title>Environment Variables</title>'echo '</head>'echo '<body>'echo 'Parse Variables:' # Save the old internal field separator. OIFS="$IFS" # Set the field separator to & and parse the QUERY_STRING at the ampersand. IFS="${IFS}&" set $QUERY_STRING Args="$*" IFS="$OIFS" # Next parse the individual "name=value" tokens. ARGX="" ARGY="" ARGZ="" for i in $Args ;do # Set the field separator to = IFS="${OIFS}=" set $i IFS="${OIFS}" case $1 in # Don't allow "/" changed to " ". Prevent hacker problems. namex) ARGX="`echo $2 | sed 's|[\]||g' | sed 's|%20| |g'`" ;; # Filter for "/" not applied here namey) ARGY="`echo $2 | sed 's|%20| |g'`" ;; namez) ARGZ="${2/\// /}" ;; *) echo "<hr>Warning:"\ "<br>Unrecognized variable \'$1\' passed by FORM in QUERY_STRING.<hr>" ;; esac done echo 'Parsed Values:' echo '<br>' echo $ARGX echo '<br>' echo $ARGY echo '<br>' echo $ARGZ echo '</body>'echo '</html>' exit 0Output:
Parsed Values:valuexvalueyvaluezYou will get the same results for: http://node1.megawww.com/cgi-bin/env.sh?namex=valuex&namez=valuez&namey=valuey
Typically one will also want to produce and process input from an HTML form:
URL: http://localhost/cgi-bin/exampleForm.sh
#!/bin/bash echo "Content-type: text/html"echo "" echo '<html>'echo '<head>'echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'echo '<title>Form Example</title>'echo '</head>'echo '<body>' echo "<form method=GET action=\"${SCRIPT}\">"\ '<table nowrap>'\ '<tr><td>Input</TD><TD><input type="text" name="val_x" size=12></td></tr>'\ '<tr><td>Section</td><td><input type="text" name="val_y" size=12 value=""></td>'\ '</tr></table>' echo '<input type="radio" name="val_z" value="1" checked> Option 1<br>'\ '<input type="radio" name="val_z" value="2"> Option 2<br>'\ '<input type="radio" name="val_z" value="3"> Option 3' echo '<br><input type="submit" value="Process Form">'\ '<input type="reset" value="Reset"></form>' # Make sure we have been invoked properly. if [ "$REQUEST_METHOD" != "GET" ]; then echo "<hr>Script Error:"\ "<br>Usage error, cannot complete request, REQUEST_METHOD!=GET."\ "<br>Check your FORM declaration and be sure to use METHOD=\"GET\".<hr>" exit 1 fi # If no search arguments, exit gracefully now. if [ -z "$QUERY_STRING" ]; then exit 0 else # No looping this time, just extract the data you are looking for with sed: XX=`echo "$QUERY_STRING" | sed -n 's/^.*val_x=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` YY=`echo "$QUERY_STRING" | sed -n 's/^.*val_y=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` ZZ=`echo "$QUERY_STRING" | sed -n 's/^.*val_z=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` echo "val_x: " $XX echo '<br>' echo "val_y: " $YY echo '<br>' echo "val_z: " $ZZ fiecho '</body>'echo '</html>' exit 0
Note that the environment variables $REQUEST_METHOD and $QUERY_STRING can be processed by the shell directly.
You can string together more "sed" translators as needed (depending on your content):| sed "s/%20/ /g" | sed "s/%3A/:/g" | sed "s/%2F/\//g"
(4) CGI Security
One must filter the input to avoid cross site scripting. Filter out "<>&*?./" to avoid trouble from hackers.
4 参考
[1] Bash shell CGI
[2] Simple CGI and Apache examples on Ubuntu Linux
- 使用Bash脚本实现Web服务CGI
- 使用vbscript脚本调用web服务
- 使用vbscript脚本调用web服务
- 使用vbscript脚本调用web服务
- 使用curl脚本监控web服务状态
- 使用shell脚本编写cgi
- 使用Spring实现Web服务
- 使用XFire实现Web服务
- WEB服务CGI接口漏洞分析(转)
- bash脚本实现fabnacci函数
- html与cgi脚本的配合使用
- 如何创建和使用Python CGI脚本
- gawk脚本中使用bash脚本变量
- AJAX及使用E4X编写Web服务脚本
- AJAX及使用E4X编写Web服务脚本
- AJAX及使用E4X编写Web服务脚本
- CGI脚本
- CGI脚本
- 静态库,共享库
- java一定要谨慎的操作!
- emmc boot partition 使用思考
- java笔记8
- boost程序编写步骤
- 使用Bash脚本实现Web服务CGI
- hibernate的单向一对多
- date中的类!
- 函数对象
- HBase数据迁移(3)-自己编写MapReduce Job导入数据
- 结合Wireshark捕获分组深入理解DNS协议
- 女孩子要检点点
- BS架构与CS架构的区别
- Objective-C中的instancetype和id区别