Браузер отправляет произвольное тело HTTP-сообщения на мой сервер boost.asio.Могу ли я изменить это? - PullRequest
0 голосов
/ 14 июня 2019

ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Вопрос ответил, не приводя в восторг.Но вы все равно можете найти это интересным.

РЕДАКТИРОВАТЬ: Вопрос, возможно, немного изменился.Разъяснение позже в посте

Я использую пример сервера из примеров boost.asio, на котором я построен.Когда браузер (Firefox) запрашивает изображение или затем публикует что-то с помощью ajax, он, похоже, отправляет случайные заголовки, вырезанные слова / заголовки или «фрагмент» ранее запрошенного изображения / сообщения ajax.Конкретным примером является то, что не только строка, которую я хотел отправить на сервер через ajax, но также каким-то образом часть кода javascript.

Буфер установлен в '\ 0' перед каждым новым запросомобрабатывается, поэтому я не верю, что это проблема.Кроме того, как уже упоминалось, это не только когда используется ajax, поэтому, если есть ошибка JavaScript, это, вероятно, не имеет значения.У меня очень мало опыта работы с протоколом HTTP - может быть, есть какое-то решение, о котором я не знаю?

    POST /post HTTP/1.1
    headers

    THIS IS WHAT WAS POSTEDlick = function() {
    ...
    }

    GET /index HTTP/1.1
    headers

    che-Control: max-age=0

Вот код C ++, который в значительной степени скопирован из примеров boost.asio:

    #include <iostream>

    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/asio.hpp>

    class connection
        : public boost::enable_shared_from_this<connection>
    {
    public:
        typedef boost::shared_ptr<connection> pointer;

        static pointer create(boost::asio::io_contenxt& io_context)
        {
            return pointer(new connection(io_context));
        }

        tcp::socket& socket() {
            return socket_;
        }

        void start()
        {

            buf[0] = '\0'; //apparently not necessary?

            socket_.async_read_some(boost::asio::buffer(buf,length), 
                    boost::bind(&connection::follow_up_write, shared_from_this(),
                    boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

        }
    private:

        connection(boost::asio::io_context& io_context)
            : socket_(io_context)
        {

        }

        follow_up_write(const boost::system::error_code& error, size_t by) {
            if(!error) {
                //this is a proposed solution, for simple cout-ing
                //it works, but still problems working with buffer
                //contents (part of EDIT)
                std::string s;
                for(unsigned int i = 0; i < (int)by; i++) {
                    s.push_back(buf[i]);
                }
                //this is for me to check, obviously:
                std::cout << s << std::endl;
                do_something_with_reply dswr(s);

                boost::asio::async_write(socket_, boost::asio::buffer(dswr.answer),
                        boost::bind(&connection::follow_up, shared_from_this()));
            }
            else 
                std::cout << error.message() << std::endl;
        }

        void follow_up() {
            //nothing here yet
        }

        tcp::socket socket_;

        enum {length = 10000}
        char buf[length];

    }
    //not good at naming, don't judge       
    class server
    {
    public:
        server(boost::asio::io_context& io_context)
            : io_context_(io_context), acceptor_(io_context, tcp::endpoint(tcp::v4(), 8080))
        {
            start_accept();
        }

    private:
        void start_accept()
        {
            connection::pointer new_connection = connection::create(io_context_);

            acceptor_.async_accept(new_connection->socket(),
                        boost::bind(&server::handle_accept, this,
                        new_connection, boost::asio::placeholders::error));
        }

        void handle_accept(connection::pointer new_connection, const boost::system::error_code& error)
        {
            if(!error) {
                new_connection->start();
            }

            start_accept();
        }

        boost::asio::io_context& io_context_;
        tcp::acceptor acceptor_;

    }

    int main()
    {
        try {
            boost::asio::io_context io_context;

            server server(io_context);

            io_context.run();
        }
        catch(std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

        return 0;
    }

Я бы не хотел получать ничего в теле сообщения на GET, если это возможно, иничего кроме того, что я хотел бы опубликовать в POST.

РЕДАКТИРОВАТЬ: Это на самом деле может иметь отношение к тому, как я работаю с тем, что получено в буфере.См. Пример ниже:

    #include <iostream>
    #include <string>
    #include <fstream>

    int main() {
        std::ifstream file("file.txt");
        std::string all, txt;
        if(file.is_open()) {
            while(getline(file,txt)) {
                all.append(txt + '\n');
            }
        }

        std::string s;
        s.append("Start");
        for(unsigned int i = 0; i < all.length(); i++) {
            s.push_back(all[i]);
        }
        s.append("END" + '\n');

        std::cout << s << std::endl;
    }

Это выводит:

StartContent of file

Content of file

Content of file

, но, как ни странно, он не показывает "END".

В более сложном примере My resultСтрока даже имеет часть имени файла в конце.В этом примере это будет "le.txt".

1 Ответ

0 голосов
/ 16 июня 2019

Ответ не радует: пользователь207421 нашел решение.

Значение заголовка Content-Length - это то, что нужно для получения истинного тела сообщения.

Спасибо всем, кто принялвремя взглянуть на это.

PS: вторая проблема в моем посте все еще странная, но не имеет отношения к вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...