C++ 웹 프로그래밍: 초보자 가이드

안녕하세요, 관심을 가진 웹 개발자 여러분! 여러분과 함께 C++ 웹 프로그래밍의 흥미로운 여정을 시작하게 되어 기쁩니다. 컴퓨터 과학을 10년 이상 가르쳐온 저는 여러분에게 확신할 수 있습니다. 처음에는 두려울 수 있지만, 인내와 연습으로 여러분은 곧 동적 웹 애플리케이션을 만들 수 있을 것입니다. 그럼, 던저 들어가보겠습니다!

C++ Web Programming

CGI란 무엇인가요?

코드를 작성하기 전에 CGI가 무엇인지 이해해야 합니다. CGI는 Common Gateway Interface의 약자입니다. 여러분의 웹 서버와 동적 콘텐츠를 생성하는 프로그램들 사이의 번역자 같은 역할을 합니다. CGI를 친절한 중간자로 상상해보세요. 이는 웹 사용자들의 요청을 받아서 여러분의 C++ 프로그램으로 전달하고, 그 결과를 다시 사용자들의 브라우저로 돌려줍니다.

웹 브라우징

CGI의 중요성을 이해하려면 웹 브라우징이 어떻게 작동하는지 알아야 합니다. URL을 브라우저에 입력하면 다음과 같은 일이 발생합니다:

  1. 여러분의 브라우저는 웹 서버에 요청을 보냅니다.
  2. 웹 서버는 이 요청을 처리합니다.
  3. 정적 페이지라면 서버가 직접 전송합니다.
  4. 동적 콘텐츠라면 CGI가 역할을 합니다.
  5. CGI는 적절한 프로그램(우리의 경우는 C++ 프로그램)을 실행합니다.
  6. 프로그램은 콘텐츠를 생성합니다.
  7. CGI는 이 콘텐츠를 서버로 다시 보냅니다.
  8. 서버는 이 콘텐츠를 여러분의 브라우저에 전송합니다.

CGI 아키텍처 다이어그램

이 과정을 간단한 다이어그램으로 시각화해보겠습니다:

[사용자의 브라우저] <--> [웹 서버] <--> [CGI] <--> [C++ 프로그램]

이 다이어그램은 여러분의 C++ 프로그램이 CGI를 통해 웹과 어떻게 상호작용하는지 보여줍니다.

웹 서버 구성

첫 번째 CGI 프로그램을 작성하기 전에 우리는 웹 서버를 구성해야 합니다. 대부분의 웹 서버는 Apache나 Nginx같이 CGI 모듈을 가지고 있습니다. 이를 활성화하고 CGI 스크립트의 디렉토리를 설정해야 합니다. 예를 들어, Apache에서는 설정에 이렇게 추가할 수 있습니다:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI
Require all granted
</Directory>

이는 Apache에 /var/www/cgi-bin/에 있는 파일들을 CGI 스크립트로 취급하도록 합니다.

첫 번째 CGI 프로그램

이제 첫 번째 CGI 프로그램을 C++로 작성해보겠습니다. 간단한 "Hello, World!" 예제로 시작해보겠습니다:

#include <iostream>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - First CGI Program</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<h2>Hello World! This is my first CGI program</h2>\n";
cout << "</body>\n";
cout << "</html>\n";
return 0;
}

이를 분석해보겠습니다:

  1. iostream 라이브러리를 포함하여 입력/출력 연산을 수행합니다.
  2. Content-type 줄은 브라우저에 어떤 종류의 콘텐츠를 기대할지 알려줍니다.
  3. 그런 다음에 정적 HTML 파일처럼 HTML 코드를 출력합니다.
  4. \n 문자들은 출력에서 적절한 줄 바꿈을 확보합니다.

HTTP 헤더

이전 예제에서 이 줄을 봤었습니다:

cout << "Content-type:text/html\r\n\r\n";

이것은 HTTP 헤더입니다. 브라우저가 다음 콘텐츠를 어떻게 해석할지를 알려줍니다. 많은 종류의 헤더가 있지만, 지금은 Content-type 헤더에 집중하겠습니다.

CGI 환경 변수

CGI는 요청에 대한 정보를 제공하기 위해 환경 변수를 제공합니다. 다음은 몇 가지 환경 변수를 표시하는 프로그램입니다:

#include <iostream>
#include <cstdlib>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html><body>";
cout << "SERVER_NAME: " << getenv("SERVER_NAME") << "<br>";
cout << "REQUEST_METHOD: " << getenv("REQUEST_METHOD") << "<br>";
cout << "QUERY_STRING: " << getenv("QUERY_STRING") << "<br>";
cout << "</body></html>";
return 0;
}

이 프로그램은 웹 서버가 설정한 환경 변수를 getenv()를 사용하여 검색합니다.

C++ CGI 라이브러리

CGI 프로그래밍을 쉽게 하기 위해 cgicc 같은 라이브러리를 사용할 수 있습니다. 이렇게 사용할 수 있습니다:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << HTMLDoctype(HTMLDoctype::eStrict) << endl;
cout << html() << head(title("My First CGI Program")) << endl;
cout << body() << h1("Hello, World!") << endl;
cout << body() << html();
return 0;
}

이 라이브러리는 HTML을 생성하고 폼 데이터를 처리하는 데 도움을 주는 클래스를 제공합니다.

GET과 POST 방법

웹 서버에 데이터를 보내는 데는 두 가지 주요 방법이 있습니다: GET과 POST.

GET 방법

GET 방법은 데이터를 URL의 일부로 보냅니다. 예를 들어:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "No name was submitted." << endl;
}

cout << body() << html();
return 0;
}

이 프로그램은 URL에 "name" 매개변수를 검색합니다 (예: http://yourserver.com/cgi-bin/program?name=John) 그리고 사용자에게 인사합니다.

POST 방법

POST 방법은 HTTP 요청 본문에 데이터를 보냅니다. 더 안전하고 더 많은 데이터를 처리할 수 있습니다. 예를 들어:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "No name was submitted." << endl;
}

cout << body() << html();
return 0;
}

이 코드는 GET 예제와 유사하지만, POST 요청에 맞게 설계되었습니다.

폼 데이터 처리

이제 다양한 종류의 폼 데이터를 처리하는 방법을 살펴보겠습니다:

체크박스 데이터

form_iterator checkbox = cgi.getElement("mycheckbox");
if(checkbox != cgi.getElements().end() && checkbox->getValue() == "on") {
cout << "Checkbox is checked!" << endl;
} else {
cout << "Checkbox is not checked." << endl;
}

라디오 버튼 데이터

form_iterator radio = cgi.getElement("myradio");
if(radio != cgi.getElements().end()) {
cout << "Selected option: " << **radio << endl;
} else {
cout << "No option selected." << endl;
}

텍스트 영역 데이터

form_iterator textarea = cgi.getElement("mytextarea");
if(textarea != cgi.getElements().end()) {
cout << "Text area content: " << **textarea << endl;
} else {
cout << "Text area is empty." << endl;
}

드롭다운 상자 데이터

form_iterator dropdown = cgi.getElement("mydropdown");
if(dropdown != cgi.getElements().end()) {
cout << "Selected option: " << **dropdown << endl;
} else {
cout << "No option selected." << endl;
}

CGI에서 쿠키 사용

쿠키는 클라이언트의 기기에 작은 데이터 조각을 저장할 수 있게 해줍니다. 이렇게 쿠키를 설정하고 검색할 수 있습니다:

쿠키 설정

#include <cgicc/HTTPCookie.h>

// ... (다른 포함 및 이름 공간 선언)

int main() {
Cgicc cgi;
HTTPCookie cookie("user", "John Doe");
cookie.setMaxAge(3600);  // 쿠키는 1시간 후 만료됩니다.

cout << HTTPHTMLHeader().setCookie(cookie) << endl;
// ... 나머지 HTML 출력
}

쿠키 검색

const CgiEnvironment& env = cgi.getEnvironment();
const vector<HTTPCookie>& cookies = env.getCookieList();

for(vector<HTTPCookie>::const_iterator i = cookies.begin(); i != cookies.end(); ++i) {
if(i->getName() == "user") {
cout << "Welcome back, " << i->getValue() << "!" << endl;
break;
}
}

파일 업로드 예제

마지막으로, 파일 업로드를 처리하는 방법을 살펴보겠습니다:

#include <iostream>
#include <fstream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

const_file_iterator file = cgi.getFile("userfile");
if(file != cgi.getFiles().end()) {
ofstream out("/path/to/upload/directory/" + file->getFilename());
out << file->getData();
cout << "File " << file->getFilename() << " uploaded successfully." << endl;
} else {
cout << "No file was uploaded." << endl;
}

cout << body() << html();
return 0;
}

이 프로그램은 업로드된 파일을 서버의 지정된 디렉토리에 저장합니다.

그리고 여기 있습니다! 우리는 C++ 웹 프로그래밍을 CGI를 사용하여 기본적으로 다루었습니다. 기억하십시오, 연습이 제일 중요합니다. 이 예제들을 시도하고, 실험해보고, 곧 복잡한 웹 애플리케이션을 C++로 만들 수 있을 것입니다. 코딩을 즐겨세요!

메소드 설명
GET URL의 일부로 데이터를 보냅니다
POST HTTP 요청 본문에 데이터를 보냅니다
getElement() GET이나 POST 요청으로부터 폼 데이터를 검색합니다
setCookie() 클라이언트의 기기에 쿠키를 설정합니다
getCookieList() 클라이언트의 기기에서 쿠키를 검색합니다
getFile() CGI에서 파일 업로드를 처리합니다

Credits: Image by storyset