Nginx + fastCGI realizes dynamic web page deployment

Introduction

  • This article mainly introduces how to deploy dynamic web pages through Nginx + fastCGI.

Introduction to CGI

  • Before introducing fastCGI, let me introduce what CGI is.
  • CGI: Common Gateway Interface, public gateway interface. On the physical level, it is a program that runs on the server and provides an interface with the client HTML page.
  • Nginx+CGI processing steps
  • User sends HTTP request to web server
  • The web server forks a CGI child process and hands the user request to the CGI program
  • The CGI program transmits the processing result to the Web server, and the CGI child process is destroyed
  • The web server returns the result to the user
    Please add a picture description
  • Disadvantages of CGI
    • Every time CGI processes a request, it must fork a child process, and after processing the request, the child process is destroyed. Frequent creation and destruction of processes will greatly reduce the efficiency of the Web server.
  • fastCGI
    • fastCGI is an optimization of CGI. fastCGI does not create a process every time a request is processed, thus avoiding the frequent creation and destruction of CGI processes, which can greatly improve the efficiency of the server.
    • The following will focus on fastCGI

fastCGI

  • FastCGI is a scalable, high-speed communication interface between HTTP server and dynamic scripting language. The main advantage is to separate dynamic language and HTTP server.
  • It is mainly to keep the CGI process in memory for management and scheduling to obtain higher performance.
  • How fastCGI works
    • Load the fastCGI process manager when the web server starts
    • The fastCGI process manager initializes itself, starts multiple CGI child processes and waits for connections from the Web server
    • When a client request arrives at the web server, the fastCGI process manager selects and connects to a CGI process to handle the request
    • After the fastCGI child process finishes processing, it returns the result to the Web server
  • question
    • Under Nginx, fastCGI is separated from the server, that is, Nginx cannot directly call fastCGI, and needs to be managed by spawn-fcgi

spawn-fcgi

  • spawn-fcgi is a bridge between Nginx and fastCGI, responsible for data communication between Nginx and fastCGI
    Please add a picture description

Install

  • fastCGI
    • ./configure
    • make
    • make install
  • If make reports an error, add the header file #include <stdio.h> to libfcgi/fcgio.cpp
  • spawn-fcgi
    • ./configure
    • make
    • make install
  • The installation of Nginx is introduced in another article: Nginx deploys static web pages

Environment configuration

  • Nginx configuration
    • It is mainly to hand over the instructions that Nginx cannot handle to fastCGI operation
    • Open the Nginx configuration file /usr/local/nginx/conf/nginx.conf, add a location field in the server field
      •   # 处理指令
          location /fastCgiTest{
          	# 配置fastcgi模块,这里的端口是fastCGI进程的端口
          	fastcgi_pass 192.168.206.128:10010;
          	# 包含配置文件
          	include fastcgi.conf;
          }
        
  • Nginx displays the login page by default (replace Nginx default index.html with this program)
    •   <!DOCTYPE html>
        <html lang="en">
        <head>
        	<meta charset="UTF-8">
        	<title>FastCGI测试网站</title>
        </head>
        <body>
        	<h1 align="center">FastCGI测试网站</h1>
        	<div class="container">
        		<form method="post" action="http://192.168.206.128/fastCgiTest">
        		<p align="center"><label>姓名:<input type="text" name="username" placeholder="admin" autofocus="autofocus"></label></p>
        		<p align="center"><label>密码:<input type="password" name="password" placeholder="000" required="required"></label></p>
        		<p align="center">
        	 		<button class="mybtn">登录</button>
        	 	</p>
        		</form>
        	</div>
        </body>
        </html>
      

Use of spawn-fcgi

  • Command: spawn-fcgi -a IP -p PORT -f fastcgi program
    • IP: Nginx server ip address, which is 192.168.206.128 configured above
    • PORT : The port to which the server sends data, which is the port 10010 we configured above
    • fastcgi program: spawn-fcgi fork fastcgi process, fastcgi program needs to be implemented and compiled by ourselves.

Write fastcgi program

  • This is written with reference to a demo in fastcgi. It mainly implements the login function. If you enter the correct user name and password, the login success interface will be displayed. If you enter the wrong user name and password, the login interface will continue to be displayed and you will be prompted to log in again.
  •  #include "fcgi_config.h"
     #include <stdlib.h>
    
     #ifdef HAVE_UNISTD_H
     #include <unistd.h>
     #endif
    
     #ifdef _WIN32
     #include <process.h>
     #else
     extern char **environ;
     #endif
    
     #include <string.h>
     #include "fcgi_stdio.h"
    
     //检查登录账号和密码
     int checkLogin(char* recvBuf, const char* userName, const char* password);
    
     int main ()
     {
          
          
     	char **initialEnv = environ;
    	 	int count = 0;
    
     	while (FCGI_Accept() >= 0) {
          
          
     		//请求数据长度
         	char *contentLength = getenv("CONTENT_LENGTH");
     		//请求方法(GET/POST)
     		char *requestmechod = getenv("REQUEST_METHOD");
    
     		//响应头(printf相当于发送数据)
     		printf("MyFlag: IsFastCGI\r\n");  //可以加自定义响应头
     		printf("Content-type: text/html\r\n");
     		printf("\r\n");
    
     		int length = 0;
     		//POST请求
     		if(strcmp(requestmechod, "POST") == 0){
          
          
     			length = strtol(contentLength, NULL, 10);
     			//post请求没有数据,不处理
     			if(length == 0){
          
          
     				continue;
     			}
     		
     			//读取post请求数据
     			char ch;
     			char recvBuf[1024 * 10] = {
          
          0};
     			for (int i = 0; i < length; i++) {
          
          
                	 	if ((ch = getchar()) < 0) {
          
          
                     	printf("read post data failed\n");
                     	continue;
     				}
     				recvBuf[i] = ch;
             	}
     		
     			if(checkLogin(recvBuf, "admin", "000")){
          
          
     				printf("<h1>Login success!</h1>\r\n");
     			}else{
          
          
     				printf("<!DOCTYPE html>\r\n");
     				printf("<html lang=\"en\">\r\n");
     				printf("<head>\r\n");
     				printf("<meta charset=\"UTF-8\">\r\n");
     				printf("<title>FastCGI测试网站</title>\r\n");
     				printf("</head>\r\n");
     				printf("<body>\r\n");
     				printf("<h1 align=\"center\">FastCGI测试网站</h1>\r\n");
     				printf("<div class=\"container\">\r\n");
     				printf("<form method=\"post\" action=\"http://192.168.206.128/fastCgiTest\">\r\n");
     				printf("<p align=\"center\"><label>姓名:<input type=\"text\" name=\"username\" placeholder=\"admin\" autofocus=\"autofocus\"></label></p>\r\n");
     				printf("<p align=\"center\"><label>密码:<input type=\"password\" name=\"password\" placeholder=\"000\" required=\"required\"></label></p>\r\n");
     				printf("<p align=\"center\">\r\n");
     				printf("<button class=\"mybtn\">登录</button>\r\n");
     				printf("</p>\r\n");
     				printf("</form>\r\n");
     				printf("</div>\r\n");
     				printf("<dialog open>\r\n");
     				printf("<p>用户名或密码错误,请重新登录</p>\r\n");
     				printf("<form method=\"dialog\">\r\n");
     				printf("<button align=\"center\">确定</button>\r\n");
     				printf("</form>\r\n");
     				printf("</dialog>\r\n");
     				printf("</html>\r\n");
     			}
     		}
    
     	} /* while */
    
     	return 0;
     }
    
     int checkLogin(char* recvBuf, const char* userName, const char* password){
          
          	
     	char* p = recvBuf;
     	char* pUserName = strtok(p, "&");
     	char* pPassWord = strtok(NULL, "&");
    
     	char* pUserNameKey = strtok(pUserName, "=");
     	char* pUserNameValue = strtok(NULL, "=");
    
    
     	char* pPassWordKey = strtok(pPassWord, "=");
     	char* pPassWordValue = strtok(NULL, "=");
    
    
     	if(strcmp(pUserNameValue, userName) == 0 && strcmp(pPassWordValue, password) == 0){
          
          
     		return 1;
     	}
     	return 0;
     }
    
  • compile
    • gcc echo.c -lfcgi
  • start fastcgi
    • spawn-fcgi -a 192.168.206.128 -p 10010 -f ./a.out
    • If the following error is reported, it means that the startup failed. First start a.out directly to see what error is reported
    • spawn-fcgi: child exited with: 127
    • Start a.out directly, you can see the following error
    • ./a.out: error while loading shared libraries: libfcgi.so.0: cannot open shared object file: No such file or directory
    • It means that the library file libfcgi.so cannot be found, this file is in this directory /usr/local/lib
    • You can add this directory to the /etc/ld.so.conf file and execute sudo ldconfig
    • Then restart the fastcgi program. Note that the path must be added in front of a.out.
    • The following prints indicate that the startup is successful
    • spawn-fcgi: child spawned successfully: PID: 26378

environment variable

  • There are some environment variables in the FastCGI program, we can get the corresponding value through the getenv function
  • REQUEST_METHOD: request method (GET/POST)
  • CONTENT_TYPE: data type
  • REQUEST_URI:URI
  • SERVER_PROTOCOL: HTTP protocol
  • REMOTE_ADDR: Client IP
  • REMOTE_PORT: client port
  • SERVER_NAME: Server IP
  • SERVER_PORT: server port

test

  • First, we access Nginx in the browser, the default port is 80. Then the login webpage we wrote will be displayed. After entering the user name and password in the login webpage, click submit, and a POST request will be sent to the /fastCgiTest command configured in the Nginx configuration file. Nginx will forward the command to the fastCGI program according to the ip and port, and the fastCGI program will process the POST request data. If the user name and password are correct, it will show that the login is successful. If the user name and password are wrong, it will continue to display the login interface and prompt the user to log in again.
  • Visit Nginx first to display the default web page
    insert image description here
  • Enter the correct user name and password, and the fastCGI program will display a successful login interface after processing
    insert image description here
  • Enter the wrong user name and password, after the fastCGI program processes, the login interface will be displayed again, and prompt to log in again
    insert image description here

Guess you like

Origin blog.csdn.net/new9232/article/details/130777776
Recommended