2015-10-10 1 views
1

Я хочу преобразовать скрипт оболочки в C++. Пожалуйста, помогите мне.вызов php-cgi из C++ с REQUEST_METHOD = "POST"

это мой файл сценария оболочки. он работал хорошо, но когда я перейти на C++, не работает правильно

test.sh

#!/bin/sh 
REQUEST_DATA="var_1=val_1&var_2=val_2" 
export GATEWAY_INTERFACE="CGI/1.1" 
export SERVER_PROTOCOL="HTTP/1.1" 
export QUERY_STRING="test=querystring" 
export REDIRECT_STATUS="200" 
export SCRIPT_FILENAME="/test.php" 
export REQUEST_METHOD="POST" 
export CONTENT_LENGTH=${#REQUEST_DATA} 
export CONTENT_TYPE="application/x-www-form-urlencoded;charset=utf-8" 
echo $REQUEST_DATA | /usr/bin/php-cgi 

и test.php является

<?php 
    print_r($_POST); 
?> 

когда я бегу sh test.sh, я получил ответ:

X-Powered-By: PHP/5.6.13 
Set-Cookie: PHPSESSID=f4ntbasno365p08tf94drl7026; path=/ 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Content-type: text/html; charset=UTF-8 

Array 
(
    [var_1] => val_1 
    [var_2] => val_2 
) 

Когда я пытаюсь преобразовать это в C++

char **sysCline = NULL; 
char **sysEnv = NULL; 
std::string sData = "var_1=val_1&var_2=val_2"; 

std::vector<std::string> aArgs; 
aArgs.push_back("/usr/bin/php-cgi"); 
aArgs.push_back("/test.php"); 
sysCline = new char*[aArgs.size() + 1]; 
for (i=0; i<aArgs.size(); i++) { 
    sysCline[i] = new char[aArgs[i].size()+1]; 
    ::strncpy(sysCline[i], aArgs[i].c_str(), aArgs[i].size()+1); 
} 
sysCline[aArgs.size()] = NULL; 

// Construct environment 
std::vector<std::string> aEnv; 
aEnv.push_back("GATEWAY_INTERFACE=CGI/1.1"); 
aEnv.push_back("SERVER_PROTOCOL=HTTP/1.1"); 
aEnv.push_back("QUERY_STRING=test=querystring"); 
aEnv.push_back("REDIRECT_STATUS=200"); 
aEnv.push_back("REQUEST_METHOD=POST"); 
aEnv.push_back("CONTENT_TYPE=application/x-www-form-urlencoded;charset=utf-8"); 
aEnv.push_back("SCRIPT_FILENAME=/test.php"); 
aEnv.push_back("CONTENT_LENGTH="+ to_string(sData.length())); 
sysEnv = new char*[aEnv.size() + 1]; 
for (i=0; i<aEnv.size(); i++) { 
    sysEnv[i] = new char[aEnv[i].size()+1]; 
    ::strncpy(sysEnv[i], aEnv[i].c_str(), aEnv[i].size() + 1); 
} 
sysEnv[aEnv.size()] = NULL; 

execve(sysCline[0], sysCline, sysEnv); 

При запуске, я получил ответ:

X-Powered-By: PHP/5.6.13 
Set-Cookie: PHPSESSID=2vdp947ghlg0h8st66c9ll3vt6; path=/ 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Content-type: text/html; charset=UTF-8 

Array 
(
) 

Она должна быть такой же ответ с sh test.sh

ответ

1

Вам нужно создать канал для того, чтобы передать данные POST сценарию:

char *echocmd[] = {"echo", "var_1=val_1&var_2=val_2", NULL}; 
int pp[2]; 
int pid, res; 

pipe(pp); 

if ((pid = fork()) != 0) 
{ 
    dup2(pp[1], 1); 
    close(pp[0]); 

    res = execvp(echocmd[0], echocmd); 
} 
else 
{ 
    dup2(pp[0], 0); 
    close(pp[1]); 

    res = execve(sysCline[0], sysCline, sysEnv); 
} 

close(pp[1]); 
return res; 
+0

Большое спасибо. –

+0

Спасибо за участие, пожалуйста. – yacc

1

Спасибо @ yacc, я нашел способ, это демо, как я использовал http://cpp.sh/4wgu

Идея: мы будем развивать текущий процесс, используйте 2 трубы: 1 для stdin и 1 для stdout. в родительском процессе мы будем использовать канал для записи строки в stdin дочернего процесса, а в дочернем процессе мы будем писать трубу для вывода из дочернего stdout. таким образом, мы можем написать stdin и прочитать stdout дочернего процесса из родительского процесса.

Смежные вопросы