Project

General

Profile

Http::Client handleHttpReponse is called twice per GET request

Added by Long Nguyễn Đức over 8 years ago

Is this behaviour normal? Because I only need to handle response one.


Replies (3)

RE: Http::Client handleHttpReponse is called twice per GET request - Added by Koen Deforche over 8 years ago

No, that's not normal and we don't see that happening in our tests.

What version of Wt and how does your code look like? Perhaps you connect twice to done() ?

RE: Http::Client handleHttpReponse is called twice per GET request - Added by Long Nguyễn Đức over 8 years ago

I use the latest Wt version, with Boost 1.58. I process the response once, then immediately delete the client object. But the handleHttpResponse is called once more on a deleted object, hence resulted in runtime error. I use condition variable and mutex to block the thread until response is processed (it shouldn't produce any error here). The client can make the GET request to localhost with handleHttpResponse called only once, but making GET request to a particular website making handleHttpReponse being called once or twice (GET http://staging.ubrand.vn/api/v1/getVideo/fIp45G9qp53TdEroNMTYqL1WGMqa7gvL?user=330&lesson=6)

#include "VideoApi.h"

VideoApi::VideoApi(Wt::WIOService &service, std::string const &token, std::string const &user, std::string const &lesson)
  :
  client_(service),
  token_(token),
  url_((boost::format(URL_API_VIDEO) % token % user % lesson).str()),
  finished(false)
{
  client_.setFollowRedirect(false);
  client_.done().connect(this, &VideoApi::handleHttpResponse);
};

VideoApi::~VideoApi()
{
  client_.abort();
};

Token VideoApi::request()
{
  boost::unique_lock<boost::mutex> lock(request_);

  finished = false;

  printf("[Call] %s\n", url_.c_str());

  if (!client_.get(url_))
    return Token();

  while (!finished)
    requestCondition_.wait(lock);

  return Token(token_, videoPath_, videoLink_);
};

void VideoApi::handleHttpResponse(boost::system::error_code err, Wt::Http::Message const &response)
{
  if (finished)
    return;

  boost::unique_lock<boost::mutex> lock(request_);

  if (!err) {
    switch (response.status()) {
    case 200: // Success
      {
        Wt::Json::Object video;
        Wt::Json::parse(response.body(), video);

        videoPath_ = video.get("video_path").orIfNull("");
        videoLink_ = video.get("video_link").orIfNull("");

        printf("[Success] Link %s\tPath %s\n", videoLink_.toUTF8().c_str(), videoPath_.toUTF8().c_str());
      };
      break;
    case 400: // Missing parameters
    case 403: // Wrong parameter
    default:
      if ((response.status() / 100) == 4)
        printf("[Error] Code %i\n", response.status());
      else
        printf("[Warning] Code %i\nBody: %s\n", response.status(), response.body().c_str());
      break;
    };
  };

  finished = true;
  client_.abort();
  requestCondition_.notify_all();
};

RE: Http::Client handleHttpReponse is called twice per GET request - Added by Long Nguyễn Đức over 8 years ago

VideoApi.h

class VideoApi
{
public:
  VideoApi(Wt::WIOService &service, std::string const &token, std::string const &user, std::string const &lesson);
  ~VideoApi();
  Token request();

private:
  void handleHttpResponse(boost::system::error_code err, Wt::Http::Message const &response);

  Wt::Http::Client client_;
  boost::mutex request_;
  boost::condition_variable requestCondition_;
  bool finished;
  std::string token_;
  Wt::WString videoPath_;
  Wt::WString videoLink_;
  std::string url_;
};

#endif//VIDEO_API_H_
    (1-3/3)