利用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)按钮后,表单的内容被发送到了服务器端,一般的,这时就需要有一个服务器端脚本来对表单的内容进行一些处理,或者是把它 ...
随机推荐
- JS快速入门
字符串 模板字符串 需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果: var s = 'Test'; s[0] = 'X'; alert(s); ...
- ROC曲线,AUC面积
AUC(Area under Curve):Roc曲线下的面积,介于0.1和1之间.Auc作为数值可以直观的评价分类器的好坏,值越大越好. 首先AUC值是一个概率值,当你随机挑选一个正样本以及负样本, ...
- 【cocos2d-js官方文档】事件分发监听机制(摘录)
简介 游戏开发中一个很重要的功能就是交互,如果没有与用户的交互,那么游戏将变成动画,而处理用户交互就需要使用事件监听器了. 总概: 事件监听器(cc.EventListener) 封装用户的事件处理逻 ...
- 字符串转化为int数组
String a = "1,2,3,4,5,6" String str[] = a.split(","); int array[] = new int[str. ...
- 笔记 : CSS3实现背景渐变过渡
使用CSS3的人都知道背景background-image是可以线性渐变(linear-gradient)和径向渐变(radial-gradient),但是想要做到过渡动画,单纯的background ...
- Mongodb $in $or 性能比较
MongoDB docs have the answer: "When using $or with <expressions> that are equality chec ...
- Comparator与Comparable用法与区别
一.概述. Comparator和Comparable两者都属于集合框架的一部分,都是用来在对象之间进行比较的,但两者又有些许的不同,我们先通过一个例子来看一下他们的区别,然后再分别学习下它们的源 ...
- C++中overload(重载),override(覆盖),overwrite(重写/覆写)的区别
#include <cstdio> #include <cstdlib> class Base { public: #pragma region MyRegion1 //函数重 ...
- MySQL练习题之参考答案
1.创建表结构和数据 /* Navicat Premium Data Transfer Source Server : localhost Source Server Type : MySQL Sou ...
- Lua用table模拟二维数组
local array = {}; , , , , } , , , , } local row3 = {"I", "love", "lua" ...