CGI不推荐了,请参考mongoose,nginx
备注:我最开始使用cgic;https://github.com/search?q=cgic中的https://github.com/boutell/cgic。但是在嵌入式cpu(400M)中,上传文件(上传文件用multipart/form-data才能正常获取)时非常慢,10M需要2分钟。后来换成cgicc-3.2.16就快很多,只要10秒。
pc端cgic和cgicc都差不多,嵌入式端cgic中cgiParsePostMultipartInput运行太慢。
在web端用F12也可以查看network:GET post的情况。cgi代码并不长,区分以下普通和文件的上传:x-www-form-urlencoded与multipart/form-data区别。
cgiGetenv(&cgiServerSoftware, (char*)"SERVER_SOFTWARE");//lighttpd/1.4.35 ---明显取得web服务器以及版本
cgiGetenv(&cgiServerName, (char*)"SERVER_NAME");//192.168.59.254 ---域名
cgiGetenv(&cgiGatewayInterface, (char*)"GATEWAY_INTERFACE");//CGI/1.1 ---CGI通用网关结构
cgiGetenv(&cgiServerProtocol, (char*)"SERVER_PROTOCOL");//HTTP/1.1 ---服务器协议版本
cgiGetenv(&cgiServerPort, (char*)"SERVER_PORT");//80 ---端口
cgiGetenv(&cgiRequestMethod, (char*)"REQUEST_METHOD");//GET ---web请求方法。GET,SET我也不是很熟
cgiGetenv(&cgiPathInfo, (char*)"PATH_INFO");//NULL
cgiGetenv(&cgiPathTranslated, (char*)"PATH_TRANSLATED");//NULL
cgiGetenv(&cgiScriptName, (char*)"SCRIPT_NAME");///cgi-bin/login.cgi ----调用的脚本名字
cgiGetenv(&cgiQueryString, (char*)"QUERY_STRING");//NULL ----请求的数据,如action=login&username=Administrator&password=WiDi
cgiGetenv(&cgiRemoteHost, (char*)"REMOTE_HOST");//192.168.59.40 ----远端主机名
cgiGetenv(&cgiRemoteAddr, (char*)"REMOTE_ADDR");//NULL
cgiGetenv(&cgiAuthType, (char*)"AUTH_TYPE");//NULL
cgiGetenv(&cgiRemoteUser, (char*)"REMOTE_USER");//NULL
cgiGetenv(&cgiRemoteIdent, (char*)"REMOTE_IDENT");//NULL
............................................................
cgiGetenv(&cgiContentLengthString, (char*)"CONTENT_LENGTH");//0 ---访问时内容长度
cgiContentLength = atoi(cgiContentLengthString);
cgiGetenv(&cgiAccept, (char*)"HTTP_ACCEPT");//text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 ---应该是可以接收的格式。html,xhtml,xml(猜的)。
cgiGetenv(&cgiUserAgent, (char*)"HTTP_USER_AGENT");//Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0 ---访问代理Firefox
cgiGetenv(&cgiReferrer, (char*)"HTTP_REFERER");//http://192.168.59.254/index.html ---web访问的地址
cgiGetenv(&cgiCookie, (char*)"HTTP_COOKIE");//lang=English; SESSIONID=E85F333900B0B4586A0E25A1CC9B0A21 ---与web端会话ID
对应输出结果:
SERVER_SOFTWARE==lighttpd/1.4.35
SERVER_NAME==192.168.59.254
GATEWAY_INTERFACE==CGI/1.1
SERVER_PROTOCOL==HTTP/1.1
SERVER_PORT==80
REQUEST_METHOD==GET
SCRIPT_NAME==/cgi-bin/login.cgi
REMOTE_ADDR==192.168.59.40
CONTENT_LENGTH==0
HTTP_ACCEPT==text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_USER_AGENT==Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
HTTP_REFERER==http://192.168.59.254/index.html
HTTP_COOKIE==lang=English; SESSIONID=E85F333900B0B4586A0E25A1CC9B0A21
Web session invalid
如果REQUEST_METHOD==POST说明是设置命令如:SET http://localhost/Jack/cgi-bin/out.cgi?theText=it%27s+me
其中theText是html/javascript中定义的输入接口名称。it%27s+me为输入的内容。
对应函数:cgiParseFormInput
typedef struct cgiFormEntryStruct {
char *attr;//属性名,html中定义的,保存在这里POST上传
/* value is populated for regular form fields only.
For file uploads, it points to an empty string, and file
upload data should be read from the file tfileName. */
char *value;//对应的数据
/* When fileName is not an empty string, tfileName is not null,
and 'value' points to an empty string. */
/* Valid for both files and regular fields; does not include
terminating null of regular fields. */
int valueLength;//数据长度
char *fileName;
char *contentType;
/* Temporary file name for working storage of file uploads. */
char *tfileName;
struct cgiFormEntryStruct *next;//下一个组上传属性。表头cgiFormEntryFirst
} cgiFormEntry;
cgiStrEqNc判断字符串相等。
cgiParsePostFormInput从cgin读取数据并解析POST到表头cgiFormEntryFirst
cgiParseGetFormInput从cgiQueryString解析数据到cgiFormEntryFirst
cgiCookies用来提取cgiCookie中如:lang和SESSIONID的名字--不是value
get_cgi_session_id这是用户层代码了,用来查看cgiCookie中是否有SESSIONID信息。
cgiHeaderCookieSetString设置cookie,作用举例:如果有效期过了,可以退到登陆界面
CGI页面跳转: CGI实现HTML页面跳转的几种方式
CGI实现HTML页面跳转的几种方式_cgi页面跳转-CSDN博客
CGI操作Session:
在CGI中实现session的想法和实现(ltesting.net)_cgi实现session-CSDN博客
用c编写CGI,如何实现用户登录的session问题_c语言的session操作-CSDN博客
CSS: