어떻게 C 로 웹 서버 의 CGI 프로 토 콜 을 작성 합 니까

6720 단어 cwebcgi서버
머리말
이번 업 데 이 트 는 주로 CGI 프로 토 콜 을 실현 합 니 다.
GitHub 링크 먼저 올 리 고.https://github.com/zhenbianshu/tinyServer
서버 로 서 기본 적 인 요 구 는 요청 을 수리 하고 정 보 를 추출 하여 CGI 해석 기 에 메 시 지 를 나 눠 주 고 해석 기 가 응답 하 는 메 시 지 를 포장 한 후 클 라 이언 트 로 돌아 가 는 것 이다.이 과정 에서 클 라 이언 트 socket 과 의 상호작용 을 제외 하고 세 번 째 실체-해석 요청 기 에 도 관련 되 어 있 습 니 다.

위의 그림 에서 보 듯 이 클 라 이언 트 는 패 키 징 요청 과 해석 응답 을 책임 집 니 다.서버 의 주요 직책 은 연결,데이터 변환,전송 과 배포 클 라 이언 트 요청 을 관리 하 는 것 입 니 다.진정 으로 데이터 문서 처리 와 데이터 베 이 스 를 조작 하 는 것 은 요청 해석 기 입 니 다.이 해석 기 는 PHP 에서 보통 PHP-FPM 이 고 JAVA 에서 Servlet 입 니 다.
우리 가 이전에 진행 한 처 리 는 주로 클 라 이언 트 와 서버 간 의 통신,그리고 서버 의 내부 조정 이 었 다.이번 업 데 이 트 된 내용 은 주로 뒤의 두 실체 간 의 프로 세 스 간 통신 이다.
프로 세 스 간 통신 은 세 가지 측면,즉 방식 과 형식 과 내용 에 관련된다.
방식 은 프로 세 스 간 통신 의 전송 매 체 를 말한다.예 를 들 어 Nginx 에서 실 현 된 TCP 방식 과 Unix Domain Socket 은 각각 기계 와 효율 적 인 장점 을 가지 고 내 가 실현 한 서버 는 매우 낮은 popen 방식 을 사용 했다.
형식 은 데이터 형식 입 니 다.서버 가 데 이 터 를 쉽게 구성 하고 해석 기 가 편리 하 게 받 아들 이 고 해석 할 수 있다 면 전송 자원 을 절약 하고 전송 효율 을 높 일 수 있 는 것 이 좋 습 니 다.현재 솔 루 션 은 전형 적 인 xml,쉽게 이해 할 수 있 는 제 이 슨 과 구 글 의 효율 적 인 protobuf 가 있다.그들 은 각각 장점 이 있 습 니 다.저 는 json 을 선 택 했 습 니 다.주로 CJSon 라 이브 러 리 가 존재 하기 때문에 데 이 터 는 C 에서 조직 하기 편 하고 PHP 에서 json 입 니 다.decode()방법 으로 데이터 분석 이 완료 되 었 습 니 다.
어떤 내용 을 전송 해 야 합 니까?CGI 는 프로 토 콜 을 설명 합 니 다:
CGI
유 니 버 설 게 이 트 웨 이 인터페이스(Common Gateway Interface/CGI)는 웹 브 라 우 저 에서 웹 서버 에 실 행 된 프로그램 에 데 이 터 를 요청 할 수 있 는 중요 한 인터넷 기술 이다.CGI 는 서버 와 요청 처리 프로그램 간 에 데 이 터 를 전송 하 는 표준 을 설명 한다.
CGI 는 서버 와 해석 기 가 상호작용 하 는 인터페이스 로 서버 가 요청 을 수리 하고 요청 정 보 를 하나의 기본 적 인 요청 정보(문서 에서'메타 데이터'라 고 함)로 해석 하여 해석 기 에 전송 하여 실행 을 설명 하고 해석 기 는 문서 와 데이터 베이스 작업 정 보 를 응답 한다.
전에 CGI 의 RFC 문 서 를 보고 몇 가지 중요 한 점 을 정 리 했 는데 관심 이 있 는 것 은 아래 의 참고 문헌 을 볼 수 있다.일반적인 규범(정보 가 너무 많 고 MUST 만 고려 하 는 경우)은 다음 과 같다.
CGI 요청
  • 서버 는/분 리 된 경로 에 따라 해석 기 를 선택 합 니 다
  • AUTH 필드 가 있 으 면 AUTH 를 먼저 실행 하고 해석 기 를 실행 해 야 합 니 다
  • 서버 는 CONTENT-LENGTH 가 데이터 분석 을 나타 내 는 길 이 를 확인 하고 정보 체 를 추가 하면 길이 필드 를 해석 기 에 전송 해 야 합 니 다
  • CONTENT-TYPE 필드 가 있 으 면 서버 에서 이 를 해석 기 에 전달 해 야 합 니 다.이 필드 가 없 지만 정보 체 가 있 으 면 서버 가 이 유형 을 판단 하거나 정보 체 를 포기 합 니 다
  • 서버 는 QUERY 를 설정 해 야 합 니 다.STRING 필드,클 라 이언 트 가 설정 되 어 있 지 않 으 면 서버 에서 빈 문자열"
  • 서버 는 REMOTE 를 설정 해 야 합 니 다.ADDR,즉 클 라 이언 트 가 IP 를 요청 합 니 다
  • REQUEST_METHOD 필드 는 반드시 설정 해 야 합 니 다.GET POST 등 대소 문자 가 민감 합 니 다
  • SCRIPT_NAME 는 실행 중인 해석 기 스 크 립 트 이름 을 표시 합 니 다.설정 해 야 합 니 다
  • SERVER_NAME 와 SERVERPORT 는 대소 문자 가 민감 한 서버 이름과 서버 가 수리 할 때의 TCP/IP 포트 를 대표 합 니 다
  • SERVER_PROTOCOL 필드 는 서버 와 해석 기 가 협상 하 는 프로 토 콜 형식 을 가리 키 며 클 라 이언 트 가 요청 한 SCHEMA 와 같 지 않 습 니 다.예 를 들 어'https://'는 HTTP 일 수 있 습 니 다
  • CONTENT-LENGTH 가 NULL 이 아 닐 때 서버 는 정보 체 를 제공 해 야 합 니 다.이 정보 체 는 길이 와 엄 격 히 일치 해 야 합 니 다.더 많은 읽 을 수 있 는 정보 가 있어 도 많이 전달 할 수 없습니다
  • 서버 는 데이터 압축 등 인 코딩 을 분석 해 야 합 니 다
  • CGI 응답
  • CGI 해석 기 는 최소한 줄+줄 바 꿈+응답 내용 에 응답 해 야 합 니 다
  • 해석 기 는 문서 에 응답 할 때 CONTENT-TYPE 헤드 가 있어 야 합 니 다
  • 클 라 이언 트 가 방향 을 바 꿀 때 해석 기 는 client-redir-response=절대 url 주 소 를 제외 하고 다른 반환 이 없 으 며 서버 는 302 상태 코드 를 되 돌려 줍 니 다
  • 해석 기 는 세 개의 디지털 상태 코드 에 응답 하고 구체 적 인 설정 은 스스로 검색 할 수 있 습 니 다
  • 서버 는 압축 등 인 코딩 이 필요 하지 않 으 면 서버 에서 응답 데 이 터 를 수정 할 수 없습니다
  • Nginx 와 PHP 의 CGI 구현
    CGI 를 소 개 했 습 니 다.현재 서버 CGI 프로 토 콜 이 실현 하 는 성숙 한 방안 을 참고 하 겠 습 니 다.여기 서 제 가 잘 아 는 Nginx 와 PHP 를 선택 하 십시오.
    Nginx 와 PHP 의 조합 에서 Nginx 는 당연히 서버 이 고 해석 기 는 PHP 의 SAPI 이다.
    SAPI
    SAPI:Server abstraction API 는 PHP 의 구체 적 인 응용 프로 그래 밍 인 터 페 이 스 를 가리 키 며 PHP 가 다른 응용 프로그램 과 상호작용 을 할 수 있 도록 한다.
    PHP 스 크 립 트 를 실행 하려 면 여러 가지 방식 으로 웹 서버 를 통 해 실행 하거나 명령 행 에 직접 삽입 할 수도 있 습 니 다.흔히 볼 수 있 는 sapi 는 apache2handler,fpm-fcgi,cli,cgi-fcgi 가 있 으 며,PHP 함수 pp 를 통 해sapi_name()은 현재 PHP 실행 에 사용 되 는 sapi 를 볼 수 있 습 니 다.
    PHP 5.3 이전에 사용 한 서버 와 의 상호작용 sapi 는 cgi 로 기본 적 인 CGI 프로 토 콜 을 실현 합 니 다.요청 을 처리 할 때마다 프로 세 스 를 만 들 고 프로 세 스 를 초기 화 하 며 요청 을 처리 하고 프로 세 스 를 소각 해 야 하기 때문에 시스템 성능 이 크게 떨 어 집 니 다.
    이때 CGI 프로 토 콜 의 업그레이드 버 전인 Fast-CGI 가 나 왔 다.
    PHP-FPM
    빠 른 유 니 버 설 게 이 트 웨 이 인터페이스(Fast Common Gateway Interface/FastCGI)는 인 터 랙 션 프로그램 이 웹 서버 와 통신 하도록 하 는 프로 토 콜 이다.FastCGI 는 초기 유 니 버 설 게 이 트 웨 이 인터페이스(CGI)의 증강 버 전이 다.
    Fast-CGI 의 효율 성 향상 은 주로 CGI 해석 기 를 메모리 에 저장 하여 재현 함으로써 프로 세 스 가 반복 적 으로 불 러 오 는 손실 을 피 할 수 있 습 니 다.PHP 의 sapi cgi-fcgi 는 Fast-CGI 프로 토 콜 을 실현 하여 PHP 처리 웹 요청 의 효율 을 향상 시 켰 습 니 다.
    그럼 우리 가 흔히 볼 수 있 는 pp-fpm 는 무엇 일 까요?이것 은 프로 세 스 관리자(PHP-FastCGI Process Manager)로 Fast-CGI 를 실현 하 는 프로 세 스(worker 프로 세 스)를 관리 합 니 다.php.ini 정 보 를 불 러 오고 worker 프로 세 스 를 초기 화하 고 부 드 러 운 재 부팅 과 다른 고급 기능 을 수행 합 니 다.
    Nginx 는 요청 을 모두 phop-fpm 에 맡 기 고 fpm 는 남 은 작업 프로 세 스 를 선택 하여 요청 을 처리 합 니 다.
    편향 을 바로잡다
    여기 서 몇 개의 이름 을 정리 하여 헷 갈 리 지 않도록 한다.
  • sapi 는 PHP 와 외부 프로 세 스 가 상호작용 하 는 인터페이스 입 니 다
  • CGI/Fast-CGI(대문자)는 협의 이다
  • 이 절 에 나타 난 cgi(소문 자)는 PHP 의 sapi,즉 CGI 프로 토 콜 을 실현 하 는 인 터 페 이 스 를 말한다
  • phop-fpm 는 Fast-CGI 프로 토 콜 을 실현 하 는 프로 세 스 를 관리 하 는 프로 세 스 입 니 다
  • 코드 구현
    고급 Nginx 서버 를 소개 하고 제 실현 에 대해 말씀 드 리 겠 습 니 다.
    서버 는 http 메 시 지 를 분석 하여 CGI 프로 토 콜 을 실현 하고 데 이 터 를 json 형식 으로 포장 하여 PHP 의 cli sapi 를 통 해 PHP 프로 세 스 로 보 냅 니 다.PHP 프로 세 스 는 json 형식 데이터 에 응답 하고 서버 는 응답 데 이 터 를 분석 한 후 http 응답 메시지 로 포장 하여 클 라 이언 트 에 보 냅 니 다.
    http_parser
    첫 번 째 임 무 는 http 메 시 지 를 해석 하 는 것 입 니 다.C 에 풍부 한 문자열 함수 가 없습니다.저도 자주 사용 하 는 함수 라 이브 러 리 를 봉인 한 적 이 없어 서 임시로 util 을 실현 할 수 밖 에 없습니다.http.c,http 메 시 지 를 처리 할 때 사용 하기 좋 은 문자열 함수 몇 개 를 소개 합 니 다.
    strtok(char str[],const*delimeter)는 delimeter 를'''로 설정 하고 http 메시지 헤드 를 분점 처리 하 는 것 이 적합 합 니 다.
    sscanf(const*str,format,dest 1[,dest...])문자열 에서 특정한 형식 으로 문자열 을 읽 습 니 다.읽 을 때 구분자 가 빈 칸 이 므 로 http 요청 행 을 처리 하 는 것 이 편리 합 니 다.
    http 메시지 헤더 의 키 값 대응 을 분석 하 는 데 있어 서 좋 은 방법 을 생각 하지 못 했 습 니 다.문자 로 여러 번 판단 할 수 밖 에 없습니다.
    cJSON
    cJSON 은 json 형식의 데 이 터 를 생 성하 고 해석 하 는 함수 라 이브 러 리 로 GitHub 에서 쉽게 찾 을 수 있 으 며 두 개의 파일 cJSON.c 와 cJSON.h 만 사용 하면 된다.
    주의:C 는 강 한 유형 언어 로 서 json 에 서로 다른 유형의 데 이 터 를 추가 하려 면 서로 다른 방법 을 사용 해 야 합 니 다.cJSON 은 string,bool,number,cJSON object 등 유형 을 지원 합 니 다.
    여기 서 생 성과 해석 의 일반적인 방법 을 간단하게 소개 합 니 다.
    생 성:
    
    cJSON *root; //   cJSON    
    root = cJSON_CreateObject(); //     cJSON  
    cJSON_AddStringToObject(root, "key", "value") //  cJSON        
    char *output = cJSON_PrintUnformatted(root); //   json   
    cJSON_Delete(root); //        
    해석:
    
    cJSON *json = cJSON_Parse(response_json);
    value = cJSON_GetObjectItem(cJSON, "key");
    물론 cJSON 형식의 데 이 터 를 끼 워 넣 을 수도 있 습 니 다.
    이상 은 C 로 웹 서버 의 CGI 프로 토 콜 을 어떻게 쓰 는 지 에 대한 상세 한 내용 입 니 다.C 로 웹 서버 의 CGI 프로 토 콜 을 쓰 는 것 에 대한 자 료 는 다른 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기