4

I'm using Pistache (pistache.2019.02.01.zip, http://pistache.io/), the REST C++ framework.

My executable provides images and I'd like to create a MJPEG Stream.

So far, my implementation looks like the following:

void PistMJPEGServer::serveMJPEG(const Rest::Request& request, Http::ResponseWriter response)
{

std::shared_ptr<Http::ResponseWriter> shared_response = std::make_shared<Http::ResponseWriter>(std::move(response));
// the "HandleMJPEG" function is declared as part of my class
handleMJPEG = [shared_response, this](ssize_t bytes)
{
    shared_response->headers()
        .add<Http::Header::Connection>(Http::ConnectionControl::Close)
        .add<Http::Header::CacheControl>(Http::CacheDirective::NoCache)
        ;
        shared_response->send(
            Http::Code::Ok,
            jpegBoundary
       ).then(
            [shared_response, this](ssize_t bytes)
            {
            shared_response->headers()
                .add<Http::Header::Connection>(Http::ConnectionControl::Close)
                .add<Http::Header::CacheControl>(Http::CacheDirective::NoCache)
            ;   
                // this method is mine, it returns an image as a buffer
                auto buf = this->getImage();
                shared_response->send(
                    Http::Code::Ok,
                    std::string{buf.begin(), buf.end()},
                    MIME(Image, Jpeg)
                ).then(
                    this->handleMJPEG,
                    Async::Throw
                )
                ;
            },
            Async::Throw
        );
    };

    shared_response->headers()
        .add<Http::Header::Connection>(Http::ConnectionControl::Close)
        .add<Http::Header::CacheControl>(Http::CacheDirective::NoCache)
    ;
    shared_response->send(
    Http::Code::Ok,
    "",
    Http::Mime::MediaType::fromString(
        boost::str(boost::format("multipart/x-mixed-replace; boundary=%1%") % jpegBoundary)
        )
    )
    .then(
        handleMJPEG,
        Async::Throw
    )
    ;

}

The recursive loop works well but I don't see any image in my browser. Actually, I don't get the Http::ConnectionControl::Close and Http::CacheDirective::NoCache I was expecting... If I try to add more headers, I don't see them or they get mixed-up (I can provide examples if needed).

I'm at all on a good way or is it that what I want to achieve cannot be done with Pistache? I had a previous implementation with boost::asio but I'd rather use Pistache and it's way more easy to use.

[ Edit 19-10 : As it was still not working, I switched my implementation to boost::asio which works like a charm]

Julien Greard
  • 969
  • 1
  • 12
  • 32

1 Answers1

1

Last week I've worked with headers and made an attempt to correct default behaviour in Connection HTTP header that was faulty. You could check again and try to implement with an earlier commit. Remeber this library is in pre-alpha version. You shouldn't use it in production.

arthur.afarias
  • 140
  • 1
  • 9
  • it doesn't change anything. I got the pistache-master today and compiled with it. With the above code, I just get the "multipart/x-mixed-replace; boundary=--jpegboundary" header. I dont get the Http::ConnectionControl::Close and Http::CacheDirective::NoCache. – Julien Greard Feb 27 '19 at 14:44
  • The "Connection: Close" behaviour will close the connection after sending the first header. – arthur.afarias Mar 13 '19 at 07:45
  • The connection is closed like we had something like this: send().then( CloseConnection, CloseConnection ).then( yourResolveHandler, yourRejectHandler ) – arthur.afarias Mar 13 '19 at 07:49
  • Try using keep-alive instead of close. – arthur.afarias Mar 13 '19 at 21:20