⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpserver.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
字号:
#include <algorithm>#include "httpcommon-inl.h"#include "asyncsocket.h"#include "common.h"#include "httpserver.h"#include "logging.h"#include "socketstream.h"namespace utils_base {///////////////////////////////////////////////////////////////////////////////// HttpServer///////////////////////////////////////////////////////////////////////////////HttpServer::HttpServer() : next_connection_id_(1) {}HttpServer::~HttpServer() {  for (ConnectionMap::iterator it = connections_.begin();       it != connections_.end();       ++it) {    StreamInterface* stream = it->second->EndProcess();    delete stream;    delete it->second;  }}intHttpServer::HandleConnection(StreamInterface* stream) {  int connection_id = next_connection_id_++;  ASSERT(connection_id != HTTP_INVALID_CONNECTION_ID);  Connection* connection = new Connection(connection_id, this);  connections_.insert(ConnectionMap::value_type(connection_id, connection));  connection->BeginProcess(stream);  return connection_id;}voidHttpServer::Respond(HttpTransaction* transaction) {  int connection_id = transaction->connection_id();     if (Connection* connection = Find(connection_id)) {          connection->Respond(transaction);  } else {    delete transaction;    // We may be tempted to SignalHttpComplete, but that implies that a    // connection still exists.  }}voidHttpServer::Close(int connection_id, bool force) {     if (Connection* connection = Find(connection_id)) {          connection->InitiateClose(force);     }}voidHttpServer::CloseAll(bool force) {  std::list<Connection*> connections;  for (ConnectionMap::const_iterator it = connections_.begin();       it != connections_.end(); ++it) {     connections.push_back(it->second);  }  for (std::list<Connection*>::const_iterator it = connections.begin();      it != connections.end(); ++it) {    (*it)->InitiateClose(force);  }}HttpServer::Connection*HttpServer::Find(int connection_id) {  ConnectionMap::iterator it = connections_.find(connection_id);  if (it == connections_.end())    return NULL;  return it->second;}voidHttpServer::Remove(int connection_id) {  ConnectionMap::iterator it = connections_.find(connection_id);  if (it == connections_.end()) {    ASSERT(false);    return;  }  Connection* connection = it->second;  connections_.erase(it);  SignalConnectionClosed(this, connection_id, connection->EndProcess());  delete connection;}///////////////////////////////////////////////////////////////////////////////// HttpServer::Connection///////////////////////////////////////////////////////////////////////////////HttpServer::Connection::Connection(int connection_id, HttpServer* server)   : connection_id_(connection_id), server_(server),    current_(NULL), signalling_(false), close_(false) { }HttpServer::Connection::~Connection() {  delete current_;}voidHttpServer::Connection::BeginProcess(StreamInterface* stream) {  base_.notify(this);   base_.attach(stream);  current_ = new HttpTransaction(connection_id_);  current_->request()->document.reset(new MemoryStream);  if (base_.mode() != HM_CONNECT)    base_.recv(current_->request());}StreamInterface*HttpServer::Connection::EndProcess() {  base_.notify(NULL);  base_.abort(HE_DISCONNECTED);  return base_.detach();}voidHttpServer::Connection::Respond(HttpTransaction* transaction) {  ASSERT(current_ == NULL);  current_ = transaction;  if (current_->response()->begin() == current_->response()->end()) {    current_->response()->set_error(HC_INTERNAL_SERVER_ERROR);  }  bool keep_alive = HttpShouldKeepAlive(*transaction->request());  current_->response()->setHeader(HH_CONNECTION,                                  keep_alive ? "Keep-Alive" : "Close",                                  false);  close_ = !HttpShouldKeepAlive(*transaction->response());  base_.send(current_->response());}voidHttpServer::Connection::InitiateClose(bool force) {  if (!signalling_ && (force || (base_.mode() != HM_SEND))) {    server_->Remove(connection_id_);  } else {    close_ = true;  }}//// IHttpNotify Implementation//  HttpErrorHttpServer::Connection::onHttpHeaderComplete(bool chunked, size_t& data_size) {  if (data_size == SIZE_UNKNOWN) {    data_size = 0;  }  return HE_NONE;}voidHttpServer::Connection::onHttpComplete(HttpMode mode, HttpError err) {  if (mode == HM_SEND) {    ASSERT(current_ != NULL);    signalling_ = true;    server_->SignalHttpRequestComplete(server_, current_, err);    signalling_ = false;    if (close_) {      // Force a close      err = HE_DISCONNECTED;    }  }  if (err != HE_NONE) {    server_->Remove(connection_id_);  } else if (mode == HM_CONNECT) {    base_.recv(current_->request());  } else if (mode == HM_RECV) {    ASSERT(current_ != NULL);    // TODO: do we need this?    //request_.document_->rewind();    HttpTransaction* transaction = current_;    current_ = NULL;    server_->SignalHttpRequest(server_, transaction);  } else if (mode == HM_SEND) {    current_->request()->clear(true);    current_->request()->document.reset(new MemoryStream);    current_->response()->clear(true);    base_.recv(current_->request());  } else {    ASSERT(false);  }}voidHttpServer::Connection::onHttpClosed(HttpError err) {  UNUSED(err);  server_->Remove(connection_id_);}///////////////////////////////////////////////////////////////////////////////// HttpListenServer///////////////////////////////////////////////////////////////////////////////HttpListenServer::HttpListenServer(AsyncSocket* listener)  : listener_(listener) {  listener_->SignalReadEvent.connect(this, &HttpListenServer::OnReadEvent);}HttpListenServer::~HttpListenServer() {}intHttpListenServer::Listen(const SocketAddress& address) {  if ((listener_->Bind(address) != SOCKET_ERROR) &&      (listener_->Listen(5) != SOCKET_ERROR))    return 0;  return listener_->GetError();}boolHttpListenServer::GetAddress(SocketAddress& address) {  address = listener_->GetLocalAddress();  return !address.IsNil();}voidHttpListenServer::OnReadEvent(AsyncSocket* socket) {  ASSERT(socket == listener_);  AsyncSocket* incoming = static_cast<AsyncSocket*>(listener_->Accept(NULL));  if (incoming)    HandleConnection(new SocketStream(incoming));}///////////////////////////////////////////////////////////////////////////////}  // namespace utils_base

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -