利用cgi编程实现web版man手册
董老师前几天给我们布置了3道作业,第三道作业是cgi程序设计。
题目:
web服务器cgi接口功能的实现
要求:
能调用cgi程序并得到返回结果;
cgi程序能接受参数并得到返回结果;
使用两种或以上语言实现。
我的想法是:
1、既然要求能够接受参数,那么必然需要使用到表单来提交用户数据,方法可以为get或者post。
2、使用linux系统下最通用的语言——c语言,最通用的脚本语言——shell脚本。
3、该cgi程序为一个linux命令,post的数据即为该命令的参数。我选择了man命令,因为使用该命令,基本上不会产生安全隐患。不仅输入的参数具有丰富的可选项,而且不同的参数返回的结果具有很强的差异性。
一、前台html的设计
代码示例
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>man for web</title>
<link rel="stylesheet" type="text/css" href="man.css"/> <body>
<div id="box">
<h1>man for web</h1>
<form method="get" action="/cgi-bin/man.sh" name="myform">
<input type="text" placeholder="使用shell脚本" name="cmd"></input>
<button class="but" type="submit">确定</button>
</form>
<br>
<form method="post" action="/cgi-bin/man.exe" name="myform">
<input type="text" placeholder="使用c语言" name="cmd"></input>
<button class="but" type="submit">确定</button>
</form>
</div>
</body>
</html>
man.css代码
html{
width: 100%;
height: 100%;
overflow: hidden;
}
body{
width: 100%;
height: 100%;
margin: 0;
background-color: #4A374A;
}
#box{
position: absolute;
top: 50%;
left:50%;
margin: -150px 0 0 -150px;
width: 300px;
height: 300px;
}
#box h1{
color: #fff;
letter-spacing: 1px;
text-align: center;
}
h1{
font-size: 2em;
margin: 0.67em 0;
}
input{
width: 278px;
height: 18px;
margin-bottom: 10px;
outline: none;
padding: 10px;
font-size: 13px;
color: #fff;
border-top: 1px solid #312E3D;
border-left: 1px solid #312E3D;
border-right: 1px solid #312E3D;
border-bottom: 1px solid #56536A;
border-radius: 4px;
background-color: #2D2D3F;
}
.but{
width: 300px;
min-height: 20px;
display: block;
background-color: #4a77d4;
border: 1px solid #3762bc;
color: #fff;
padding: 9px 14px;
font-size: 15px;
line-height: normal;
border-radius: 5px;
margin: 0;
}
二、cgi程序设计
1、c语言
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 2000
main()
{
char poststr[14];
char cmd[10];
printf ("Content-type:text/plain \n\n");
int n=0;
int i;
if(getenv("CONTENT_LENGTH"))
{
n=atoi(getenv("CONTENT_LENGTH"));
fgets(poststr,n+1,stdin);
sscanf(poststr,"cmd=%s",cmd); char cmds[15];
sprintf(cmds,"man %s > data.txt",cmd);
system(cmds); FILE* fp;
int len;
if((fp=fopen("data.txt","r"))==NULL)
{
perror("fail to read");
}
while(fgets(buf,MAX_LINE,fp)!=NULL)
{
len=strlen(buf);
buf[len-1] = '\0';
printf("%s\n",buf);
}
} else{
printf("error");}
}
程序思路:
调用system函数,将处理过得post数据作为参数进行处理。
具体实现方法:
"Content-type:html/plain \n\n"这条语句用于输出头信息,浏览器读取到后,可获知该网页格式为plain(标准ascii字符),紧接着的两个\n\n缺一不可,否则该cgi程序不会被执行,并且访问的时候会显示500错误,查看apache2错误日志,记录为“malformed header from script. Bad header=xxx”或者“Premature end of script headers”。
数组poststr[15]用于存储环境变量CONTENT_LENGTH,cmd[10]用于存储用户真正输入的数据,长度15够用了。cmds[15]用于存储system函数调用的程序path及参数。比如欲查询find命令相关用法,按下确定后,浏览器将使用post方法发送一串字符串到服务器,该字符串经过url编码,编码后的字符串为“cmd=find”。在这个案例中,数组poststr的作用就是存储这个字符串,数组cmd的作用是存储"find",数组cmds的作用是存储“man find > in.txt”,至于怎么通过poststr来生成cmd、cmds,则需要用到相应的函数。
if(getenv("CONTENT_LENGTH")用于判断传递的字符串是否为空。
语句 fgets(poststr,n+1,stdin) 作用是从标准输入中读取n个字符串并存储到数组poststr[]。参考百度百科:“从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0')”,函数原型:char *fgets(char *buf, int bufsize, FILE *stream)。
语句 sscanf(poststr,"cmd=%s",cmd) 作用是生成cmd字符串。参考百度百科:“sscanf() - 从一个字符串中读进与指定格式相符的数据”。通俗的理解就是裁剪字符串,提取有效信息。
语句 sprintf(cmds,"man %s > data.txt",cmd) 作用是将字符串cmd和“man ”拼接,生成字符串cmds。
c语言中,system()函数用于调用系统命令。比如system("ls")调用ls命令,然而system调用成功返回值是0,因此需要将结果重定向到一个文本文件中再读取此文本文档以显示命令执行结果。system(cmds)相当于system("man xxx")。
之后的语句用于打开文本文档,不再详细解释。
2、使用shell脚本
#!/bin/bash
echo "content-type:text/html"
echo
echo "<html>"
echo "<head>"
echo "<meta charset="UTF-8">"
echo "<title>shell-cgi实现man命令</title>"
echo "<style>"
echo "pre {margin:0 auto; width:"50%"; height:"100%"; font-size:12pt;}"
echo "</style>"
echo "</head>"
echo "<body>"
echo "<pre>"
data=$QUERY_STRING
cmd=${data#*cmd=}
if man $cmd >/dev/null;then
man $cmd
else
echo "没有查询到相关信息"
echo "</pre>"
echo "</body>"
echo "</html>"
data=$QUERY_STRING用于从环境变量中获取数据并赋给data。
cmd=${data#*cmd=} 作用是从data字符串中截取“cmd=”之后的字符串。
之所以使用<pre>标签是因为位如果不使用的话生成的html页面不自动换行。
ps.不需要担心不怀好意的人输入一下诸如 "ls && rm -rf / "之类的数据到cgi,因为数据的传输都是经过了url编码的,空格会变成加号,特殊字符也会改变。shell.cgi没有进行相应的解码,输入多个命令传递给cgi程序的只是一堆无意义的乱码,如果设计成对url完全解码的cgi程序,应该格外注意安全问题。
利用cgi编程实现web版man手册的更多相关文章
- shell脚本作为cgi程序--以web版man为例
man.cgi源码 #! /bin/sh eval `sh proccgi.sh $*` echo "Content-type: text/html" echo echo echo ...
- Web 版 PowerDesigner (Canvas) 技术
什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形. ...
- Python的Web编程[1] -> Web服务器[0] -> Web 服务器与 CGI / WSGI
Web服务器 / Web Server 对于Web来说,需要建立一个Web服务器,必须建立一个基本的服务器和一个处理程序, 基本服务器的主要作用是,在客户端和服务器端完成必要的HTTP交互, 处理程序 ...
- Kali Linux Web渗透测试手册(第二版) - 1.3 - 靶机的安装
Kali Linux Web渗透测试手册(第二版) - 1.3 - 靶机的安装 一.配置KALI Linux和渗透测试环境 在这一章,我们将覆盖以下内容: 在Windows和Linux上安装Virt ...
- JAVA面向对象编程课程设计——web版斗地主
一.团队课程设计博客链接 JAVA面向对象编程课程设计--网络版单机斗地主 二.个人负责模块或任务说明 实体类的设计 斗地主规则的实现 人机自动出牌的算法 实现数据库的DAO模式 三.自己的代码提交记 ...
- CGI编程完全手册
一.基本原理 CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口.通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器 ...
- 物联网网络编程、Web编程综述
本文是基于嵌入式物联网研发工程师的视觉对网络编程和web编程进行阐述.对于专注J2EE后端服务开发的童鞋们来说,这篇文章可能稍显简单.但是网络编程和web编程对于绝大部分嵌入式物联网工程师来说是一块真 ...
- Python学习笔记-CGI编程(如何在IIS上挂Python开发的Webservice)
一.如何用Python开发一个简单的Webservice 利用python的cgi编程,可以传入参数将结果输出. 定义需要编码以及需要引用的模块 #conding=utf-8 #修正中文乱码 impo ...
- (笔记)Linux下的简单CGI编程
为什么要进行CGI编程? 在HTML中,当客户填写了表单,并按下了发送(submit)按钮后,表单的内容被发送到了服务器端,一般的,这时就需要有一个服务器端脚本来对表单的内容进行一些处理,或者是把它 ...
随机推荐
- [LeetCode] 154. Find Minimum in Rotated Sorted Array II_Hard
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...
- express框架之session 存储
1.express-session 是基于express框专门用于处理session的中间件.这里不谈express-session怎么安装,只给出相应的实例代码.另外,session的认证机制离不开 ...
- 实验一Java开发环境的熟悉-3
实现学生成绩管理功能(增删改,排序,查找),并进行测试(正常情况,异常情况,边界情况). 代码:
- linux 下查看c 函数帮助
帮助文档 man man MANUAL SECTIONS The standard sections of the manual include: User Commands System Calls ...
- python 读取excel数据并将测试结果填入Excel
python 读取excel数据并将测试结果填入Excel 读取一个Excel中的一条数据用例,请求接口,然后返回结果并反填到excel中.过程中会生成请求回来的文本,当然还会生成一个xml文件.具体 ...
- cocos2d JS-(JavaScript) 几种循环遍历对象的比较
通常我们会用循环的方式来遍历数组.但是循环是 导致js 性能问题的原因之一.一般我们会采用下几种方式来进行数组的遍历: 方式1: for in 循环: var arr = [1,2,3,4,5]; v ...
- 利用css伪类编写冒泡小三角
HTML代码 <div class="lf otherLogin"> <span>其他方式注册</span> <div class=&qu ...
- 通过Response下载。
之前一直在找js下载的插件,后来发现下载必须通过java后台处理,什么write(),open(),close()之类的方法.如果直接是通过<a>标签倒是简单的,直接将路径摆放在上面就可以 ...
- 000-js判断电脑或手机登录
<script type="text/javascript"> try{ if(/Android|webOS|iPhone|iPod|BlackBerry/i.test ...
- DataGridView控件用法一:数据绑定
使用DataGridView控件,可以显示和编辑来自多种不同类型的数据源的表格数据. 将数据绑定到DataGridView控件非常简单和直观,在大多数情况下,只需设置DataSource属性即可.在绑 ...