首页 > 其他分享 >CGI通用网关接口

CGI通用网关接口

时间:2022-10-29 23:01:36浏览次数:73  
标签:CGI 网关 程序 接口 method char 服务器 环境变量



Common Gatway Interface

原理

简介

CGI 是 Web服务器和程序动态生成数据之间的通用接口

CGI通用网关接口_服务器

服务器和CGI程序之间是通过标准输入输出来进行数据传递的,需要环境变量的协作才可以实现

基本流程:

  1. 通过浏览器将用户请求送到服务器
  2. 服务器接收用户请求并交给CGI程序处理
  3. CGI程序把处理结果传送给服务器
  4. 服务器把结果送回到浏览器

对于Windows系统而言,还可以通过profile文件进行数据传输(如ini文件)

每个CGI程序只能处理一个用户请求,在激活一个CGI程序进程时也创建了属于该进程的环境变量。

环境变量

对于CGI程序来说,它继承了系统的环境变量, CGI环境变量在CGI程序启动时初始化,在结束时销毁。

当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了关于HTTP服务器、客户端、CGI传输过程等相关内容。

与请求相关的环境变量

名称

说明

REQUEST_METHOD

服务器与CGI程序之间的信息传输方式

QUERY_STRING

采用GET时所传输的信息

CONTENT_LENGTH

STDIO中有效信息长度

CONTENT_TYPE

指示所传来的信息的MIME类型

CONTENT_FILE

使用Windows HTTPd/WinCGI标准时,用来传送数据的文件名

PATH_INFO

路径信息

PATH_TRANSLATED

CGI程序的完整路径名

SCRIPT_NAME

所调用的CGI程序的名字

与服务器相关的环境变量

名称

说明

GATEWAY_INTERFACE

服务器所实现的CGI版本

SERVER_NAME

服务器的IP或名字

SERVER_PORT

主机的端口号

SERVER_SOFTWARE

调用的CGI程序名称和版本号

与客户端相关的环境变量

名称

说明

REMOTE_ADDR

客户机的IP地址

REMOTE_HOST

客户机的主机名

ACCEPT

能接收的应答方式

ACCEPT_ENCODING

支持的编码方式

ACCEPT_LANGUAGE

可接受的语言

AUTORIZATION

认证方式

FORM

客户机地址

IF_MODIFIED_SINGCE

当用get方式请求并且只有当文档比指定的日期更早时才返回数据

PRAGMA

设定将来要用到的服务器代理

REFFERER

链接到当前文档的文档的URL

USER_AGENT

客户端浏览器的信息

  • CGI传送给Web服务器的信息可以用各种格式,通常是以HTML文本或者XML文本的形式
1. 传输HTML,文本第一行输出的内容必须是"content-type:text/html\n\n"
2. 传输XML,文本第一行输出的内容必须是"content-type:text/xml\n\n"
3. 其他的一些格式:JIF(image/gif)、JPEG(image/jpeg)、AVI(video/avi)

两个重要环境变量

  • ​QUERY_STRING​​:在浏览器端以GET的方法输入的数据,数据的内容就是url问号后的内容
char *data = getenv("QUERY_STRING");
  • ​CONTENT_LENGTH​​:在浏览器端以POST方法输入的数据的字节数,数据的内容通过标准输入获取
//1. 数据的长度
char *len = getenv("CONTENT_LENGTH");
//2、根据长度 从标准输入设备 获取内容
char data[128]="";
fgets(data, atoi(len)+1, stdin);
POST方法

客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH

GET方法

客户端来的用户数据存放到到环境变量QUERY_STRING

CGI程序的执行流程:

  • 查询与该CGI程序进程相应的环境变量:
    REQUEST_METHOD,如果是POST,就从环境变量中获取数据的长度len,然后到该进程相应的标准输入取出len长的数据。
    如果是GET,则用户数据就在环境变量的QUERY_STRING中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int get_inputs(){
int length;
char *method;
char *inputstring;
method = getenv("REQUEST_METHOD"); //将返回结果赋予指针
if(method == NULL) return 1; //找不到环境变量REQUEST_METHOD
if(!strcmp(method, "POST")) { // POST方法
length = atoi(getenv("CONTENT_LENGTH")); //结果是字符,需要转换
if(length != 0) {
inputstring = malloc(sizeof(char)*length + 1) //必须申请缓存,因为stdin是不带缓存的。
fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据
}
}else if(!strcmp(method, "GET")){
Inputstring = getenv("QUERY_STRING");
length = strlen(inputstring);
}
}

先判断“REQUEST_METHOD”是否存在,程序会更健壮,否则在某些情况下可能会造成程序崩溃。

假若CGI程序不是由服务器调用的,环境变量集里就没有与CGI相关的环境变量(如REQUEST_METHOD,REMOTE_ADDR等)添加进来

CGI数据输出

在CGI程序中的标准输出stdout是经过重定义了的,没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器

可以用打印来实现客户端新的HTML页面的生成。

CGI标题

CGI的格式输出内容必须组织成标题/内容的形式,CGI标准规定了CGI程序可以使用的三个HTTP标题。

标题必须占据第一行输出,而且必须随后带有一个空行

标题

描述

Content-Type

设定随后输出数据的MIME类型

Location

设定输出为另外一个文档

Status

指定HTTP状态码

Content-Type

向标准输出发送网页内容要遵循MIME格式

任意输出前面必须要有一个用于定义MIME类型的输出内容,随后必须跟一个空行。

printf("Content-Type:text/html\n\n");
printf("Welcome\n");

MIME类型以类型/子类型(type/subtype)的形式表示。

  • 其中type表示一下几种典型文件格式的一种:

text、audio、video、image、application、mutipart、message

  • Subtype则用来描述具体所用的数据格式。

类型

说明

Application/msword

word文档

Application/octet-stream

一种通用二进制文件格式

Application/zip

zip压缩文件

Application/pdf

pdf文件

Location

使用location ,一个CGI可以使用当前用户转而访问同一服务器上的另外一个程序,甚至可以访问一个url

使用Location的格式为:Location:Filename/URL

printf("Location:/test.html\n\n");
//这与直接链接到test.html的效果是一样的。
printf("Location:http:*//www.baidu.com/\n\n");
//由于该URL并不指向当前服务器,用户浏览器并不会直接链接到指定的URL,而是给用户输出提示信息。

Demo

GET方式:计算a + b的值

url: ​​http://ip:port/add?a=nn&b=nn​​

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
char * method = NULL;
char *query_string = NULL;
printf("Content-Type:text/html\r\n\r\n");

method = getenv("REQUEST_METHOD");
if(method == NULL){
printf("<html> <p> UNKNOWN METHOD</p></html>");
return;
}
if(strcasecmp(method,"POST") == 0){
printf("<html> <p> UNSUPPORTED METHOD</p></html>");
return 0;
}
query_string = getenv("QUERY_STRING");
if(query_string == NULL){
printf("<html> <p> PARAMETER ERROR </p></html>");
return 0;
}
int a = 0;
int b = 0;
int i = 0;
char * start = query_string+2;
char * end = NULL;
// format: a=xxx&b=xxx
for(i = 0;i<strlen(query_string);i++){
if(*(query_string+i) == '&'){
end = query_string+i;
break;
}
}
*end = '\0';
a = atoi(start);
start = end +3;
b = atoi(start);
printf("<html> <p> %d + %d = %d </p></html>",a,b,a+b);
return 0;
}

显示效果如下:

CGI通用网关接口_数据_02

参考

  1. ​​t.csdn.cn/44wV4​​
  2. ​​t.csdn.cn/tkgPJ​​
  3. ​​t.csdn.cn/JqlKj​​
  4. ​​t.csdn.cn/afcOz​​

标签:CGI,网关,程序,接口,method,char,服务器,环境变量
From: https://blog.51cto.com/u_14926062/5806592

相关文章

  • Go接口嵌套的使用
    原文链接:https://www.zhoubotong.site/post/86.html这里介绍下接口interface嵌套的用法,大家知道Go语言中不仅仅结构体与结构体之间可以嵌套,接口与接口之间也可以嵌套,通过......
  • Qt应用程序接口和插件的创建详细过程
    Qt应用程序接口:包含类定义的头文件(*.h),该类定义中一般只包含纯虚函数的声明。Qt应用程序插件:继承自指定类和接口的C++类,该类实现了接口中定义的纯虚函数。 ------------......
  • .NET API 接口数据传输加密最佳实践
    .NETAPI接口数据传输加密最佳实践我们在做Api接口时,相信一定会有接触到要给传输的请求body的内容进行加密传输。其目的就是为了防止一些敏感的内容直接被UI层查看......
  • 服务器双网卡网关配置注意
    前提:服务器两块网卡,一块内网网卡,一块外网网卡,因为只能有一个默认网关,所以外网网卡配置网关,而内网网卡不能配置网关,否则会造成过段时间外网上不了,内网网关通过配置默认路由解......
  • PLC智能网关采集三菱FX-3U对接thingsboard平台示例
    BL102是一款采集西门子、三菱、欧姆龙、台达、AB、施耐德等各种PLC数据转换为ModbusTCP、OPCUA、MQTT、ThingsBoard等协议的网关。BL102下行支持:西门子、三菱、欧姆龙、台......
  • Istio(四):创建部署Gateway并使用网关暴露服务
    目录一.模块概览二.系统环境三.Gateway网关3.1使用Gateway四.实战:使用Gateway发布服务4.1创建部署并使用网关暴露4.2清理一.模块概览在Kubernetes集群中,服务的发布方......
  • MES数据采集网关通过OPC UA网关实现工业现场设备对接OPC UA服务器
    通过OPCUA网关快速实现工业现场设备对接OPCUA服务器目前市场上大部分PLC接入到OPCUAServer中,都是通过OPCUA软件运行在工控机上来实现,既需要工控机作为硬件,还需要购买......
  • node.js:《接口实现文件的上传和下载》
    使用node.js写上传文件和下载文件的接口上传接口:开始写接口前,我们先安装一个上传文件的插件:npminstallmulter安装成功在package.json或package-lock.json包中能看到......
  • MES智能网关通过OPC UA网关实现工业现场设备对接OPC UA服务器
    通过OPCUA网关快速实现工业现场设备对接OPCUA服务器目前市场上大部分PLC接入到OPCUAServer中,都是通过OPCUA软件运行在工控机上来实现,既需要工控机作为硬件,还需要购......
  • node.js:《路由—接口分类》
     一个项目有很多不同的接口,如果把它们都写在同个js文件中,报错或需要改会很麻烦!我们可以将接口按我们想要的规则分类出来写在路由文件中,再借助中间件用拼接的方式,将在路......