用c++寫一個 「hello,world」 的 FastCGI程序

原文:http://chriswu.me/blog/writing-hello-world-in-fcgi-with-c-plus-plus/javascript

上面的鏈接地址給出的是做者的原文地址。php

另一個做者稍微整理了一下,github 地址:https://github.com/homer6/fastcgihtml

下面給出我測試的截圖:java

這個用 C++ 寫的cgi 程序哦, c++ 也能夠寫網站了,是否是很興奮!!!ios

stackoverflow 的問題:http://stackoverflow.com/questions/2149709/c-language-fastcgi-with-nginxnginx

 

俗話說:「好記性不如爛筆頭」, 因此這裏記錄下原文地址,和稍微寫一寫本身的心得和一路的過程。c++

google 到這篇用 c++ (c)語言寫的 fastCGi 程序,並能成功運行,中間實屬不易。。git

作 web (網站) 開發也有兩三年了, 用 php 語言寫的。 web server 用過 apache , nginx .  對於apache ,它會啓動一個 php 的模塊,來處理php腳本。 對於nginx,github

則 fast-pass: 127.0.0.1:9000 , webserver (nginx)將 請求  ----cgi 協議--- 轉發到 facscgi (php-fpm) 處理(固然 會傳遞 標準輸入和一個 環境變量過去),php 解釋器執行完web

php 腳本後, 將標準輸出  給webserver , webserver 而後將輸出 經過 http response 傳給 browser (client), 一個 http 的請求和響應就結束了。

cgi 程序能夠用php, java, C#寫,固然能夠用 C, C++ 來寫。 

 

我一直也在研究一個 fastCGI 這個處理過程究竟是怎麼樣的。 webserver 和 fastCGI 之間的交互過程是怎麼樣的。因此本身想寫一個 C++ 的fastCGI 腳原本完成一個http 請求,因而我也找了不少資料,因此就有了這篇文章的產生。

關於 CGI 應用程序和 web server 之間的交互的過程,這裏有幾張圖片,圖片來源:(原做者:吳秦Tyler)  https://images0.cnblogs.com/blog/92071/201412/191104473136735.png

 

prerequistites:

  need some familiarity with C++;

Why fastCGI?

  FCGI (FastCGI) is a protocol in which web applications can talk to a web server to serve web requests.

Installation:

  We will need to install the libfcgi++ library, a web server (nignx in our case) and spawn-fcgi to run the fcgi app. We’ll also install curl to help test later on.

  

sudo apt-get install libfcgi-dev
sudo apt-get install spawn-fcgi
sudo apt-get install nginx
sudo apt-get install curl

  

The code:

  a c++ source file(echo.cpp)

  

#include <iostream>
#include "fcgio.h"

using namespace std;

int main(void) {
    // Backup the stdio streambufs
    streambuf * cin_streambuf  = cin.rdbuf();
    streambuf * cout_streambuf = cout.rdbuf();
    streambuf * cerr_streambuf = cerr.rdbuf();

    FCGX_Request request;

    FCGX_Init();
    FCGX_InitRequest(&request, 0, 0);

    while (FCGX_Accept_r(&request) == 0) {
        fcgi_streambuf cin_fcgi_streambuf(request.in);
        fcgi_streambuf cout_fcgi_streambuf(request.out);
        fcgi_streambuf cerr_fcgi_streambuf(request.err);

        cin.rdbuf(&cin_fcgi_streambuf);
        cout.rdbuf(&cout_fcgi_streambuf);
        cerr.rdbuf(&cerr_fcgi_streambuf);

        cout << "Content-type: text/html\r\n"
             << "\r\n"
             << "<html>\n"
             << "  <head>\n"
             << "    <title>Hello, World!</title>\n"
             << "  </head>\n"
             << "  <body>\n"
             << "    <h1>Hello, World!</h1>\n"
             << "  </body>\n"
             << "</html>\n";

        // Note: the fcgi_streambuf destructor will auto flush
    }

    // restore stdio streambufs
    cin.rdbuf(cin_streambuf);
    cout.rdbuf(cout_streambuf);
    cerr.rdbuf(cerr_streambuf);

    return 0;
}

  

Nginx config:

  

Next up we’ll setup nginx to listen on port 80 for http requests and forward those along the the fcgi process which will listen on port 8000.

The key directive is fastcgi_pass 127.0.0.1:8000 indicates that nginx should forward the fcgi request to port 8000 at localhost. You can replace the address with an upstream directive if you want to want to load balance across many processes. The rest of the fastcgi_param directives are optional and just set appropriate environment variables which get forwarded to the fcgi application.

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;
    server_name localhost;

    location / {
      fastcgi_pass   127.0.0.1:8000;

      fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
      fastcgi_param  SERVER_SOFTWARE    nginx;
      fastcgi_param  QUERY_STRING       $query_string;
      fastcgi_param  REQUEST_METHOD     $request_method;
      fastcgi_param  CONTENT_TYPE       $content_type;
      fastcgi_param  CONTENT_LENGTH     $content_length;
      fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
      fastcgi_param  REQUEST_URI        $request_uri;
      fastcgi_param  DOCUMENT_URI       $document_uri;
      fastcgi_param  DOCUMENT_ROOT      $document_root;
      fastcgi_param  SERVER_PROTOCOL    $server_protocol;
      fastcgi_param  REMOTE_ADDR        $remote_addr;
      fastcgi_param  REMOTE_PORT        $remote_port;
      fastcgi_param  SERVER_ADDR        $server_addr;
      fastcgi_param  SERVER_PORT        $server_port;
      fastcgi_param  SERVER_NAME        $server_name;
    }
  }
}

  

Running the code:

  The system now comprises of three parts. One will be the executable fcgi c++ app. In order to run this we need spawn-fcgi and to listen to a port. Nginx will then forward web requests to this port, translating the http proctocol into the fast cgi protocol.

# run nginx using the provided configuration
# 下面這一行其實我沒用到。
sudo nginx -c <path to nginx.conf> 

# compile hello_world
g++ main_v1.cpp -lfcgi++ -lfcgi -o hello_world

# spawn the fcgi app on port 8000 with no fork
spawn-fcgi -p 8000 -n hello_world

  Then just head to the browser and enter http://localhost/ into the location bar and voilà! Hello, World! See the next part in this tutorial to see how to incorporate the request uri and the request content into this simple app

相關文章
相關標籤/搜索