s2d1ent
@s2d1ent
Специалист технической поддержки

Как обработать запрос с формы на сервере?

Пишу учебный проект, веб-сервер на C#, и столкнулся с такой проблемой, что не могу обработать на сервере запрос с формы:
POST /php/auth.php HTTP/1.1
Host: uppdd
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: uppdd/signin.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
Origin: uppdd
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

login=admin&pass=secretpass&but=%D0%92%D0%BE%D0%B9%D1%82%D0%B8
Этот кусок кода отвечает за обработку php файла:
string html = AnyFile(link); // функция AnyFile(string addrs) - запускает интерпретатор php, передает путь на файл в виде строки и возвращает ответ string UTF-8 
string content_type = GetContentType(link); // получает тип контента
int length = html.Length; // длина контента
string headers = $"HTTP/1.1 200 OK\nContent-type: {content_type}\nContent-Length: {length}\n\n{html}"; // заголовок
byte[] data_headers = Encoding.UTF8.GetBytes(headers); // перевод строки в байты UTF-8
client.GetStream().Write(data_headers, 0, data_headers.Length); // отправка байтов по сети клиенту

1. Как передать строку: login=admin&pass=secretpass&but=%D0%92%D0%BE%D0%B9%D1%82%D0%B8 - интерпретатору на обработку
2. Как правильно сформировать заголовок ответа, для такого запроса
3. Как это реализовать на C#
Сервер пищу посредством использования TCPListener/TCPClient, не используя WebReponse/Request и HttpListener.
Проект на GitHub
  • Вопрос задан
  • 191 просмотр
Решения вопроса 2
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Для этого очень давно придумали https://en.wikipedia.org/wiki/Common_Gateway_Interface
Фактически это тот же самый cli но на стероидах: перед тем как вызвать бинарник и передать ему на stdin строку с закодированным постом, надо установить несколько обязательных переменных окружения

В составе РНР до сих пор поставляется бинарник php-cgi, который сам всё раскодирует, а так же, в качестве бонуса, сформирует все нужные заголовки ответа.

Пара ссылок:
https://stackoverflow.com/questions/4030147/how-to...
https://www.oreilly.com/openbook/cgi/ch04_02.html
Ответ написан
Комментировать
s2d1ent
@s2d1ent Автор вопроса
Специалист технической поддержки
Использование CGI с C# и передача POST
class Program
    {
        static void Main(string[] args)
        {
            string link = @"D:\csharp_server\program\program\bin\Debug\net5.0\includes\php\win86\php-cgi.exe", //ссылка на CGI
                text = @"D:\csharp_server\program\program\bin\Debug\net5.0\www\UPPDD\php\auth.php"; // ссылка на файл где идет использование POST/GET
            Console.WriteLine(UseInterpreter(link, text));// вывод в консоль для просмотра
            Console.ReadKey();
        }
        static string UseInterpreter(string php, string file)
        {
            ProcessStartInfo info = new ProcessStartInfo(php);
            string req = "login=admin&pass=secretpass&but=%D0%92%D0%BE%D0%B9%D1%82%D0%B8"; // параметры формы
            info.UseShellExecute = false;
            info.ErrorDialog = false;
            info.RedirectStandardError = true;
            info.RedirectStandardInput = true;
            info.RedirectStandardOutput = true;
            info.CreateNoWindow = true;
            // переменные среды
            info.EnvironmentVariables.Add("REQUEST_METHOD", "POST");
            info.EnvironmentVariables.Add("HTTP_CONNECTION", $"keep-alive");
            info.EnvironmentVariables.Add("REDIRECT_STATUS", "false");
            info.EnvironmentVariables.Add("GETAWAY_INTERFACE", "CGI");
            info.EnvironmentVariables.Add("CONTENT_TYPE", "application/x-www-form-urlencoded");
            info.EnvironmentVariables.Add("CONTENT_LENGTH", Encoding.UTF8.GetBytes(req).Length.ToString());
            info.EnvironmentVariables.Add("HTTP_ACCEPT", "*.*");
            info.EnvironmentVariables.Add("SCRIPT_FILENAME", file);
            // передеча информации в Process и старт процесса
            Process p = new Process();
            p.StartInfo = info;
            bool pStarted = p.Start();

            StreamWriter input = p.StandardInput; // стандартынй поток ввода
            input.WriteLine(req); // ввод
            StreamReader output = p.StandardOutput; // поток вывода
            StreamReader error = p.StandardError; // поток вывода ошибки 
            // перекодировка, при наличии кириллицы php выводит в кодировке cp866, тут мы переводим из cp866 в utf8
            byte[] cp866_byte = output.CurrentEncoding.GetBytes(output.ReadToEnd());
            string cp866_byte_to_utf8 = Encoding.UTF8.GetString(cp866_byte);

            return cp866_byte_to_utf8;
        }
    }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы