예제 #1
0
void LibEventServer::onResponse(int worker, evhttp_request *request,
                                int code, LibEventTransport *transport) {
  int nwritten = 0;
  bool skip_sync = false;

  if (request->evcon == nullptr) {
    evhttp_request_free(request);
    return;
  }

#ifdef _EVENT_USE_OPENSSL
  skip_sync = evhttp_is_connection_ssl(request->evcon);
#endif

  int totalSize = 0;

  if (RuntimeOption::LibEventSyncSend && !skip_sync) {
    const char *reason = HttpProtocol::GetReasonString(code);
    timespec begin, end;
    Timer::GetMonotonicTime(begin);
#ifdef EVHTTP_SYNC_SEND_REPORT_TOTAL_LEN
    nwritten = evhttp_send_reply_sync(request, code, reason, nullptr, &totalSize);
#else
    nwritten = evhttp_send_reply_sync_begin(request, code, reason, nullptr);
#endif
    Timer::GetMonotonicTime(end);
    int64_t delay = gettime_diff_us(begin, end);
    transport->onFlushBegin(totalSize);
    transport->onFlushProgress(nwritten, delay);
  }
  m_responseQueue.enqueue(worker, request, code, nwritten);
}
예제 #2
0
LibEventTransportTraits::LibEventTransportTraits(LibEventJobPtr job,
                                                 void *opaque,
                                                 int id) :
    server_((LibEventServer*)opaque),
    request_(job->request),
    transport_(server_, request_, id) {

#ifdef _EVENT_USE_OPENSSL
  if (evhttp_is_connection_ssl(request_->evcon)) {
    transport_.setSSL();
  }
#endif
}
예제 #3
0
void LibEventWorker::doJobImpl(LibEventJobPtr job, bool abort) {
  job->stopTimer();
  evhttp_request *request = job->request;
  assert(m_opaque);
  LibEventServer *server = (LibEventServer*)m_opaque;

  LibEventTransport transport(server, request, m_id);
#ifdef _EVENT_USE_OPENSSL
  if (evhttp_is_connection_ssl(job->request->evcon)) {
    transport.setSSL();
  }
#endif
  bool error = true;
  std::string errorMsg;

  if (abort) {
    transport.sendString("Service Unavailable", 503);
    return;
  }

  try {
    std::string cmd = transport.getCommand();
    cmd = std::string("/") + cmd;
    if (server->shouldHandle(cmd)) {
      transport.onRequestStart(job->getStartTimer());
      m_handler->handleRequest(&transport);
      error = false;
    } else {
      transport.sendString("Not Found", 404);
      return;
    }
  } catch (Exception &e) {
    if (Server::StackTraceOnError) {
      errorMsg = e.what();
    } else {
      errorMsg = e.getMessage();
    }
  } catch (std::exception &e) {
    errorMsg = e.what();
  } catch (...) {
    errorMsg = "(unknown exception)";
  }

  if (error) {
    if (RuntimeOption::ServerErrorMessage) {
      transport.sendString(errorMsg, 500);
    } else {
      transport.sendString(RuntimeOption::FatalErrorMessage, 500);
    }
  }
}
예제 #4
0
void PendingResponseQueue::process() {
  // clean up the pipe for next signals
  char buf[512];
  if (read(m_ready.getOut(), buf, sizeof(buf)) < 0) {
    // an error occured but nothing we can really do
  }

  // making a copy so we don't hold up the mutex very long
  ResponsePtrVec responses;
  for (int i = 0; i < RuntimeOption::ResponseQueueCount; i++) {
    ResponseQueue &q = *m_responseQueues[i];
    Lock lock(q.m_mutex);
    responses.insert(responses.end(),
                     q.m_responses.begin(), q.m_responses.end());
    q.m_responses.clear();
  }

  for (unsigned int i = 0; i < responses.size(); i++) {
    Response &res = *responses[i];
    evhttp_request *request = res.request;
    int code = res.code;

    if (request->evcon == nullptr) {
      evhttp_request_free(request);
      continue;
    }

    bool skip_sync = false;
#ifdef _EVENT_USE_OPENSSL
    skip_sync = evhttp_is_connection_ssl(request->evcon);
#endif

    if (res.chunked) {
      if (res.chunk) {
        if (res.firstChunk) {
          const char *reason = HttpProtocol::GetReasonString(code);
          evhttp_send_reply_start(request, code, reason);
        }
        evhttp_send_reply_chunk(request, res.chunk);
      } else {
        evhttp_send_reply_end(request);
      }
    } else if (RuntimeOption::LibEventSyncSend && !skip_sync) {
      evhttp_send_reply_sync_end(res.nwritten, request);
    } else {
      const char *reason = HttpProtocol::GetReasonString(code);
      evhttp_send_reply(request, code, reason, nullptr);
    }
  }
}
예제 #5
0
void LibEventServer::onResponse(int worker, evhttp_request *request,
                                int code) {
  int nwritten = 0;
  bool skip_sync = false;
#ifdef _EVENT_USE_OPENSSL
  skip_sync = evhttp_is_connection_ssl(request->evcon);
#endif

  if (RuntimeOption::LibEventSyncSend && !skip_sync) {
    const char *reason = HttpProtocol::GetReasonString(code);
    nwritten = evhttp_send_reply_sync_begin(request, code, reason, NULL);
  }
  m_responseQueue.enqueue(worker, request, code, nwritten);
}