H
H
HPositron2020-11-29 18:21:32
C++ / C#
HPositron, 2020-11-29 18:21:32

Why doesn't this proxy work for HTTPS?

Why doesn't this simple proxy server work for HTTPS requests?
When trying to make an HTTPS request, the target resource returns 400 Bad Request
What changes do I need to make to make it work?

Own code

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Configuration;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Proxy
{
    class Program
    {

        static void Main(string[] args)
        {
            var listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8111); // слушаем соединение
            listener.Start();
            while (true)
            {
                var client = listener.AcceptTcpClient();
                Thread thread = new Thread(() => RecvData(client)); // и когда нам приходит запрос на подключение создаем новый поток
                thread.Start();
            }
        }

        public static void RecvData(TcpClient client) 
        {
            NetworkStream browser = client.GetStream();
            byte[] buf;
            buf = new byte[16000];
            while (true) // здесь мы читаем данные которые отправляет нам браузер и передаем их на обработку в httpserv
            {
                if (!browser.CanRead)
                    return;
                try
                {
                    browser.Read(buf, 0, buf.Length);
                }
                catch (IOException)
                {
                    return;
                }
                HTTPserv(buf, browser, client);
            }
        }

        public static void HTTPserv(byte[] buf, NetworkStream browser, TcpClient client)
        {
            try
            {
                string[] temp = Encoding.ASCII.GetString(buf).Trim().Split(new char[] { '\r', '\n' });
                
                string req = temp.FirstOrDefault(x => x.Contains("Host")); 
                req = req.Substring(req.IndexOf(":") + 2);
                string[] port = req.Trim().Split(new char[] { ':' }); // получаем имя домена и номер порта (если есть)

                TcpClient server;
                if (port.Length == 2) // тут мы соединяемся с сервером по имени хоста и если есть порт в запросе то по порту, а если нет то по стандартному 80
                {
                    server = new TcpClient(port[0], int.Parse(port[1]));
                }
                else
                {
                    server = new TcpClient(port[0], 80);
                }

                NetworkStream servStream = server.GetStream(); // поток с сервером
                servStream.Write(buf, 0, buf.Length); // отправляем данные на сервер, которые получили от браузера
                var respBuf = new byte[32]; // для заголовка
                
               
                servStream.Read(respBuf, 0, respBuf.Length); // ответ от сервера

                browser.Write(respBuf, 0, respBuf.Length); // отправляем этот ответ браузеру

                string[] head = Encoding.UTF8.GetString(respBuf).Split(new char[] { '\r', '\n' }); // получаем код ответа
         
                string ResponseCode = head[0].Substring(head[0].IndexOf(" ") + 1);
                Console.WriteLine($"\n{req} {ResponseCode}");
                servStream.CopyTo(browser); // перенаправляем остальные данные от сервера к браузеру

            }
            catch
            {
                return;
            }
            finally
            {
                client.Dispose();
            }

        }

    }

}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
galaxy, 2020-11-29
@HPositron

Do you understand that HTTPS differs from HTTP not only in the port number?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question