资讯详情

从零开始自制实现WebServer(二十)---- C++ High-Performance WebServer源码实现(Http核心代码部分)

文章目录

    • 全流程实现博客链接
    • 前引
    • (二十)---- C High-Performance WebServer源码实现(Http核心代码)
      • 1、httpcontent.h
      • 1、httpcontent.cc
      • 2、httprequest.h
      • 2、httprequest.cc
      • 3、httpparsestate.h
      • 4、httpresponse.h
      • 4、httpresponse.cc
      • 5、httpresponsefile.h
      • 6、httpserver.h
      • 6、httpserver.cc


实现博客链接的全过程



前引



(二十)---- C High-Performance WebServer源码实现(Http核心代码)


1、httpcontent.h


#ifndef TINY_MUDUO_HTTPCONTENT_H_ #define TINY_MUDUO_HTTPCONTENT_H_  #include <utility> #include <algorithm>  #include "buffer.h" #include "httprequest.h" #include "httpparsestate.h"  namespace tiny_muduo { 
          class HttpContent { 
          public:   HttpContent();   ~HttpContent();    void ParseLine(Buffer* buffer);   bool ParseContent(Buffer* buffer);   bool GetCompleteRequest() { 
         return parse_state_ == kParseGotCompleteRequest; }       const HttpRequest& request() const { 
         return request_; }   void ResetContentState() { 
         
    HttpRequest tmp;
    request_.Swap(tmp);
    parse_state_ = kParseRequestLine;
  }

 private:
  HttpRequest request_;
  HttpRequestParseState parse_state_;
};

}
#endif

1、httpcontent.cc


#include "httpcontent.h"

#include <algorithm>

#include "httprequest.h"
#include "httpparsestate.h"

using namespace tiny_muduo;

HttpContent::HttpContent() : parse_state_(kParseRequestLine) { 
        
}

HttpContent::~HttpContent() { 
        }

bool HttpContent::ParseContent(Buffer* buffer) { 
        
  bool linemore = true;
  bool parseok = true;
  const char* CRLF = nullptr;
  while (linemore) { 
        
    CRLF = nullptr;
    if (parse_state_ == kParseRequestLine) { 
         
      CRLF = buffer->FindCRLF(); 
      if (CRLF) { 
        
        parseok = request_.ParseRequestLine(buffer->Peek(), CRLF);
        if (parseok) { 
        
          parse_state_ = kParseHeaders;
        } else { 
        
          linemore = false;
        }
      } else { 
        
        linemore = false;
      }
    } else if (parse_state_ == kParseHeaders) { 
        
      CRLF = buffer->FindCRLF(); 
      if (CRLF) { 
        
        const char* colon = std::find((const char*)buffer->Peek(), CRLF, ':');
        if (colon == CRLF) { 
        
          parse_state_ = kParseGotCompleteRequest;
          linemore = false;
        } else { 
        
          parseok = request_.ParseHeaders(buffer->Peek(), colon, CRLF);
          if (!parseok) linemore = false;
        }
      } else { 
        
        linemore = false;
      }
    } else if (parse_state_ == kParseGotCompleteRequest) { 
        
      linemore = false;
    } else if (parse_state_ == kParseBody) { 
        
    
    }

    if (CRLF) { 
         
      buffer->RetrieveUntilIndex(CRLF + 2);
    }
  }

  return parseok;
}

2、httprequest.h


#include "httprequest.h"

#include <utility>
#include <algorithm>
#include <string>

#include "httpparsestate.h"

using namespace tiny_muduo;
using tiny_muduo::Method;
using tiny_muduo::HttpRequestParseState;

HttpRequest::HttpRequest() { 
        }

HttpRequest::~HttpRequest() { 
        }

bool HttpRequest::ParseRequestMethod(const char* start, const char* end) { 
        
  string method(start, end);
  bool has_method = true;
  if (method == "GET") { 
        
    method_ = kGet;
  } else if (method == "POST") { 
        
    method_ = kPost;
  } else if (method == "PUT") { 
        
    method_ = kPut;
  } else if (method == "DELETE") { 
        
    method_ = kDelete;
  } else if (method == "TRACE") { 
        
    method_ = kTrace;
  } else if (method == "OPTIONS") { 
        
    method_ = kOptions;
  } else if (method == "CONNECT") { 
        
    method_ = kConnect;
  } else if (method == "PATCH") { 
        
    method_ = kPatch;
  } else { 
        
    has_method = false;
  }

  return has_method;
}

bool HttpRequest::ParseRequestLine(const char* start, const char* end) { 
        
  const char* space = nullptr;     
  space = std::find(start, end, ' ');
  if (space == end) { 
        
    return false;
  }
  
  if (!ParseRequestMethod(start, space)) { 
        
    return false;
  }
  start = space + 1; 
 
  space = std::find(start, end, ' ');
  if (space == end) { 
        
    return false;
  }

  const char* query = std::find(start, end, '?'); 
  if (query != end) { 
        
    path_.assign(start, query);
    query_.assign(query + 1, space);
  } else { 
        
    path_.assign(start, space);
  }        
  start = space + 1;
  
  bool parsehttp = (start + 8 == end) && std::equal(start, end - 1, http);
  if (!parsehttp || (*(end - 1) != '0' && *(end - 1) != '1')) { 
        
    version_ = kUnknown;
    return false;
  }

  if (*(end - 1) == '0') { 
        
    version_ = kHttp10;
  } else { 
        
    version_ = kHttp11; 
  }

  return true;
}

bool HttpRequest::ParseBody(const char* start, const char* end) { 
         
  (void)start;
  (void)end;
  return true; 
}

bool HttpRequest::ParseHeaders(const char* start, const char* colon, const char* end) { 
        
  const char* vaildstart = colon + 1; 
  while(*vaildstart == ' ') { 
         ++vaildstart; }
  headers_[std::move(string(start, colon))] = std::move(string(vaildstart, end));
  return true;
}

void HttpRequest::Swap(HttpRequest& req) { 
        
   method_ = req.method_;
   version_ = req.version_;
   path_.swap(req.path_);
   query_.swap(req.query_);
   headers_.swap(req.headers_);
}

2、httprequest.cc


#include "httprequest.h"

#include <utility>
#include <algorithm>
#include <string>

#include "httpparsestate.h"

using namespace tiny_muduo;
using tiny_muduo::Method;
using tiny_muduo::HttpRequestParseState;

HttpRequest::HttpRequest() { 
        }

HttpRequest::~HttpRequest() { 
        }

bool HttpRequest::ParseRequestMethod(const char* start, const char* end) { 
        
  string request_method(start, end);
  bool has_method = true;
  if (request_method == "GET") { 
        
    method_ = kGet;
  } else if (request_method == "POST") { 
        
    method_ = kPost;
  } else if (request_method == "PUT") { 
        
    method_ = kPut;
  } else if (request_method == "DELETE") { 
        
    method_ = kDelete;
  } else if (request_method == "TRACE") { 
        
    method_ = kTrace;
  } else if (request_method == "OPTIONS") { 
        
    method_ = kOptions;
  } else if (request_method == "CONNECT") { 
        
    method_ = kConnect;
  } else if (request_method == "PATCH") { 
        
    method_ = kPatch;
  } else { 
        
    has_method = false;
  }

  return has_method;
}

bool HttpRequest::ParseRequestLine(const char* start, const char* end) { 
        
  const char* space = nullptr;     
  space = std::find(start, end, ' ');
  if (space == end) { 
        
    return false;
  }
  
  if (!ParseRequestMethod(start, space)) { 
        
    return false;
  }
  start = space + 1; 
 
  space = std::find(start, end, ' ');
  if (space == end) { 
        
    return false;
  }

  const char* query_ptr = std::find(start, end, '?'); 
  if (query_ptr != end) { 
        
    path_.assign(start, query_ptr);
    query_.assign(query_ptr + 1, space);
  } else { 
        
    path_.assign(start, space);
  }        
  start = space + 1;
  
  bool parsehttp = (start + 8 == end) && std::equal(start, end - 1, http);
  if (!parsehttp || (*(end - 1) != '0' && *(end - 1) != '1')) { 
        
    version_ = kUnknown;
    return false;
  }

  if (*(end - 1) == '0') { 
        
    version_ = kHttp10;
  } else { 
        
    version_ = kHttp11; 
  }

  return true;
}

bool HttpRequest::ParseBody(const char* start, const char* end) { 
         
  (void)start;
  (void)end;
  return true; 
}

bool HttpRequest::ParseHeaders(const char* start, const char* colon, const char* end) { 
        
  const char* vaildstart = colon + 1; 
  while(*vaildstart == ' ') { 
         ++vaildstart; }
  headers_[std::move(string(start, colon))] = std::move(string(vaildstart, end));
  return true;
}

void HttpRequest::Swap(HttpRequest& req) { 
        
   method_ = req.method_;
   version_ = req.version_;
   path_.swap(req.path_);
   query_.swap(req.query_);
   headers_.swap(req.headers_);
}

3、httpparsestate.h


#ifndef TINY_MUDUO_HTTPSTATE_H_
#define TINY_MUDUO_HTTPSTATE_H_

namespace tiny_muduo { 
        

enum HttpRequestParseState { 
        
  kParseRequestLine,
  kParseHeaders,
  kParseBody,
  kParseGotCompleteRequest,
  kParseErrno,
};

}

#endif

4、httpresponse.h


#ifndef TINY_MUDUO_HTTPRESPONSE_H_
#define TINY_MUDUO_HTTPRESPONSE_H_

#include <string>
#include <utility>

#include "httprequest.h"

using std::string;

namespace tiny_muduo { 
        

static const string CRLF = "\r\n";

enum HttpStatusCode { 
        
  k100Continue = 100,
  k200OK = 200,
  k400BadRequest = 400,
  k403Forbidden = 403,
  k404NotFound = 404,
  k500InternalServerErrno = 500
};

class Buffer;

class HttpResponse { 
        
 public:
  HttpResponse(bool close_connection) : type_("text/plain"),
                                        close_connection_(close_connection) { 
        
  }
  ~HttpResponse() { 
        }

  void SetStatusCode(HttpStatusCode status_code) { 
         status_code_ = status_code; }
  void SetStatusMessage(const string& status_message) { 
         status_message_ = std::move(status_message); }
  void SetCloseConnection(bool close_connection) { 
         close_connection_ = close_connection; }

  void SetBodyType(const string& type) { 
         type_ = type; }
  void SetBody(const string& body) { 
         body_ = body; }
  void AppendToBuffer(Buffer* buffer);

  bool CloseConnection() { 
         return close_connection_; }

 private:
  static const string server_name_;
  HttpStatusCode status_code_;
  string status_message_;
  string body_;
  string type_;
  bool close_connection_;
};

}

#endif

4、httpresponse.cc


#include "httpresponse.h"

#include <stdio.h>

#include <string>

#include "buffer.h"

using namespace tiny_muduo;
using std::string;

const string HttpResponse::server_name_ = "Tiny_muduo";

void HttpResponse::AppendToBuffer(Buffer* buffer) { 
        
  char buf[32] = { 
        0};

  snprintf(buf, sizeof(buf), "HTTP/1.1 %d ",status_code_);
  buffer->Append(buf);
  buffer->Append(status_message_);
  buffer->Append(CRLF);
  
  if (close_connection_) { 
        
    buffer->Append("Connection: close\r\n");
  } else { 
        
    snprintf(buf, sizeof(buf), "Content-Length: %zd\r\n", body_.size()); // no need to memset this is longer than HTTP... one
    buffer->Append(buf);
    buffer->Append("Connection: Keep-Alive\r\n");
  }

  buffer->Append("Content-Type: ");
  buffer->Append(type_);
  buffer->Append(CRLF);

  buffer->Append("Server: ");
  buffer->Append(server_name_);
  buffer->Append(CRLF);
  buffer->Append(CRLF);

  buffer->Append(body_);
  return;
}

5、httpresponsefile.h


#ifndef TINY_MUDUO_HTTPRESPONSEFILE_H_
#define TINY_MUDUO_HTTPRESPONSEFILE_H_

namespace tiny_muduo { 
        

const char favicon[555] = { 
        
  '\x89', 'P', 'N', 'G', '\xD', '\xA', '\x1A', '\xA',
  '\x0', '\x0', '\x0', '\xD', 'I', 'H', 'D', 'R',
  '\x0', '\x0', '\x0', '\x10', '\x0', '\x0', '\x0', '\x10',
  '\x8', '\x6', '\x0', '\x0', '\x0', '\x1F', '\xF3', '\xFF',
  'a', '\x0', '\x0', '\x0', '\x19', 't', 'E', 'X',
  't', 'S', 'o', 'f', 't', 'w', 'a', 'r',
  'e', '\x0', 'A', 'd', 'o', 'b', 'e', '\x20',
  'I', 'm', 'a', 'g', 'e', 'R', 'e', 'a',
  'd', 'y', 'q', '\xC9', 'e', '\x3C', '\x0', '\x0',
  '\x1', '\xCD', 'I', 'D', 'A', 'T', 'x', '\xDA',
  '\x94', '\x93', '9', 'H', '\x3', 'A', '\x14', '\x86',
  '\xFF', '\x5D', 'b', '\xA7', '\x4', 'R', '\xC4', 'm',
  '\x22', '\x1E', '\xA0', 'F', '\x24', '\x8', '\x16', '\x16',
  'v', '\xA', '6', '\xBA', 'J', '\x9A', '\x80', '\x8',
  'A', '\xB4', 'q', '\x85', 'X', '\x89', 'G', '\xB0',
  'I', '\xA9', 'Q', '\x24', '\xCD', '\xA6', '\x8', '\xA4',
  'H', 'c', '\x91', 'B', '\xB', '\xAF', 'V', '\xC1',
  'F', '\xB4', '\x15', '\xCF', '\x22', 'X', '\x98', '\xB',
  'T', 'H', '\x8A', 'd', '\x93', '\x8D', '\xFB', 'F',
  'g', '\xC9', '\x1A', '\x14', '\x7D', '\xF0', 'f', 'v',
  'f', '\xDF', '\x7C', '\xEF', '\xE7', 'g', 'F', '\xA8',
  '\xD5', 'j', 'H', '\x24', '\x12', '\x2A', '\x0', '\x5',
  '\xBF', 'G', '\xD4', '\xEF', '\xF7', '\x2F', '6', '\xEC',
  '\x12', '\x20', '\x1E', '\x8F', '\xD7', '\xAA', '\xD5', '\xEA',
  '\xAF', 'I', '5', 'F', '\xAA', 'T', '\x5F', '\x9F',
  '\x22', 'A', '\x2A', '\x95', '\xA', '\x83', '\xE5', 'r',
  '9', 'd', '\xB3', 'Y', '\x96', '\x99', 'L', '\x6',
  '\xE9', 't', '\x9A', '\x25', '\x85', '\x2C', '\xCB', 'T',
  '\xA7', '\xC4', 'b', '1', '\xB5', '\x5E', '\x0', '\x3',
  'h', '\x9A', '\xC6', '\x16', '\x82', '\x20', 'X', 'R',
  '\x14', 'E', '6', 'S', '\x94', '\xCB', 'e', 'x',
  '\xBD', '\x5E', '\xAA', 'U', 'T', '\x23', 'L', '\xC0',
  '\xE0', '\xE2', '\xC1', '\x8F', '\x0', '\x9E', '\xBC', '\x9',
  'A', '\x7C', '\x3E', '\x1F', '\x83', 'D', '\x22', '\x11',
  '\xD5', 'T', '\x40', '\x3F', '8', '\x80', 'w', '\xE5',
  '3', '\x7', '\xB8', '\x5C', '\x2E', 'H', '\x92', '\x4',
  '\x87', '\xC3', '\x81', '\x40', '\x20', '\x40', 'g', '\x98',
  '\xE9', '6', '\x1A', '\xA6', 'g', '\x15', '\x4', '\xE3',
  '\xD7', '\xC8', '\xBD', '\x15', '\xE1', 'i', '\xB7', 'C',
  '\xAB', '\xEA', 'x', '\x2F', 'j', 'X', '\x92', '\xBB',
  '\x18', '\x20', '\x9F', '\xCF', '3', '\xC3', '\xB8', '\xE9',
  'N', '\xA7', '\xD3', 'l', 'J', '\x0', 'i', '6',
  '\x7C', '\x8E', '\xE1', '\xFE', 'V', '\x84', '\xE7', '\x3C',
  '\x9F', 'r', '\x2B', '\x3A', 'B', '\x7B', '7', 'f',
  'w', '\xAE', '\x8E', '\xE', '\xF3', '\xBD', 'R', '\xA9',
  'd', '\x2', 'B', '\xAF', '\x85', '2', 'f', 'F',
  '\xBA', '\xC', '\xD9', '\x9F', '\x1D', '\x9A', 'l', '\x22',
  '\xE6', '\xC7', '\x3A', '\x2C', '\x80', '\xEF', '\xC1', '\x15',
  '\x90', '\x7', '\x93', '\xA2', '\x28', '\xA0', 'S', 'j',
  '\xB1', '\xB8', '\xDF', '\x29', '5', 'C', '\xE', '\x3F',
  'X', '\xFC', '\x98', '\xDA', 'y', 'j', 'P', '\x40',
  '\x0', '\x87', '\xAE', '\x1B', '\x17', 'B', '\xB4', '\x3A',
  '\x3F', '\xBE', 'y', '\xC7', '\xA', '\x26', '\xB6', '\xEE',
  '\xD9', '\x9A', '\x60', '\x14', '\x93', '\xDB', '\x8F', '\xD',
  '\xA', '\x2E', '\xE9', '\x23', '\x95', '\x29', 'X', '\x0',
  '\x27', '\xEB', 'n', 'V', 'p', '\xBC', '\xD6', '\xCB',
  '\xD6', 'G', '\xAB', '\x3D', 'l', '\x7D', '\xB8', '\xD2',
  '\xDD', '\xA0', '\x60', '\x83', '\xBA', '\xEF', '\x5F', '\xA4',
  '\xEA', '\xCC', '\x2', 'N', '\xAE', '\x5E', 'p', '\x1A',
  '\xEC', '\xB3', '\x40', '9', '\xAC', '\xFE', '\xF2', '\x91',
  '\x89', 'g', '\x91', '\x85', '\x21', '\xA8', '\x87', '\xB7',
  'X', '\x7E', '\x7E', '\x85', '\xBB', '\xCD', 'N', 'N',
  'b', 't', '\x40', '\xFA', '\x93', '\x89', '\xEC', '\x1E',
  '\xEC', '\x86', '\x2', 'H', '\x26', '\x93', '\xD0', 'u',
  '\x1D', '\x7F', '\x9', '2', '\x95', '\xBF', '\x1F', '\xDB',
  '\xD7', 'c', '\x8A', '\x1A', '\xF7', '\x5C', '\xC1', '\xFF',
  '\x22', 'J', '\xC3', '\x87', '\x0', '\x3', '\x0', 'K',
  '\xBB', '\xF8', '\xD6', '\x2A', 'v', '\x98', 'I', '\x0',
  '\x0', '\x0', '\x0', 'I', 'E', 'N', 'D', '\xAE',
  'B', '\x60', '\x82',
};

const string love6_website = "<p align = \"middle\"><label> <font color=\"#84C1FF\">Sharing And Geting. I'm Always Here</font> </label> </p><hr />\ <p align = \"middle\"><label> <font color=\"#84C1FF\">Love 6's Info</font> </label> <br />\ <label><font color=\"#AAAAFF\">Love 6's School: Hogwarts School </font></label> <br />\ <label><font color=\"#C1FFE4\">Love 6's Year In Univ: Sophomore </font></label> <br />\ <label><font color=\"#FFBFFF\">Love 6's Interests: Gaming Coding </font></label> <br />\ <label><font color=\"#A3D1D1\">Love 6's Occupation: Sorcerer </font></label> <br /> \ <label><font color=\"#A6FFA6\">Love 6's QQ Wechat: Personal Secret </font></label> <br /> </p>\ <hr />\ <p align = \"middle\"><label><font color=\"#84C1FF\"> Cat </font><br /> </label> </p>\ <p align = \"middle\"><img src=\"https://img-blog.csdnimg.cn/6d28d9f8ad2b4c79be7a90a33e552caf.GIF\" alt=\"Cat\" width=\"200\" height=\"200\"></p>\ <hr />\ <p align = \"middle\"><label><font color=\"#84C1FF\"> Love 6's Some Blogs - Keep Updating </font><br /> </label></p></hr >\ <label><font color=\"#AAAAFF\"> Touch Here -> </font></label><a href=\"https://love6.blog.csdn.net/article/details/119133589\"> Operating system truth restore self-made operating system whole process records from scratch </a><br />\ <label><font color=\"#FFBFFF\"> Touch Here -> </font></label><a href=\"https://love6.blog.csdn.net/article/details/117517529\"> Harbin Institute of technology operating system lab full experiment blog link </a><br />\ <label><font color=\"#C1FFE4\"> Touch Here -> </font></label><a href=\"https://love6.blog.csdn.net/article/details/120071337\"> Computer network top-down lab full experiment blog link </a><br />\ <label><font color=\"#A3D1D1\"> Touch Here -> </font></label><a href=\"https://love6.blog.csdn.net/article/details/116152266\"> CSAPP Labs 1-6 Blog Link</a><hr />\ <p align = \"middle\"><label><font color=\"#84C1FF\"> Do good deeds Don't ask future </font><br /> </label></p>"; 

}

#endif

6、httpserver.h


#ifndef TINY_MUDUO_HTTPSERVER_H_
#define TINY_MUDUO_HTTPSERVER_H_

#include <stdio.h>

#include <functional>
#include <utility>
#include <memory>

#include "callback.h"
#include "eventloop.h"
#include "tcpserver.h"
#include "tcpconnection.h"
#include "buffer.h"
#include "httpcontent.h"
#include "httprequest.h"
#include "httpresponse.h"
#include "timestamp.h"
#include "logging.h"

using tiny_muduo::HttpStatusCode;

namespace tiny_muduo { 
        

static const double kIdleConnectionTimeOuts = 8.0;

class HttpServer { 
        
 typedef std::function<void (const HttpRequest&, HttpResponse&)> HttpResponseCallback;

 public:
  HttpServer(EventLoop* loop, const Address& address, 
             bool auto_close_idleconnection = false);
  ~HttpServer();

  void Start() { 
        
    server_.Start();
  }

  void HttpDefaultCallback(const HttpRequest& request, HttpResponse& response) { 
        
    response.SetStatusCode(k404NotFound);
    response.SetStatusMessage("Not Found");
    response.SetCloseConnection(true);
    (void)request;
  }

  void HandleIdleConnection(std::weak_ptr<TcpConnection>& connection) { 
        
    TcpConnectionPtr conn(connection.lock());
    if (conn) { 
        
      if (Timestamp::AddTime(conn->timestamp(), kIdleConnectionTimeOuts) < Timestamp::Now()) { 
        
        conn->Shutdown();
      } else { 
            
        loop_->RunAfter(kIdleConnectionTimeOuts, 
                        std::move(std::bind(&HttpServer::HandleIdleConnection,
                        this, connection))); 
      }
    }
  }

  void ConnectionCallback(const TcpConnectionPtr& connection) { 
        
    if (auto_close_idleconnection_) { 
        
      loop_->RunAfter(kIdleConnectionTimeOuts, 
                      std::bind(&HttpServer::HandleIdleConnection, 
                      this, std::weak_ptr<TcpConnection>(connection))); 
    }
  }

  void MessageCallback(const TcpConnectionPtr& connection, Buffer* buffer);

  void SetHttpResponseCallback(const HttpResponseCallback& response_callback) { 
         
    response_callback_ = response_callback; 
  }

  void SetHttpResponseCallback(HttpResponseCallback&& response_callback) { 
         
    response_callback_ = std::move(response_callback); 
  } 
  
  void SetThreadNums(int thread_nums) { 
        
  	server_.SetThreadNums(thread_nums);
  }

  void DealWithRequest(const HttpRequest& request, const TcpConnectionPtr& connection);

 private:
  EventLoop* loop_;
  TcpServer server_;
  bool auto_close_idleconnection_;

  HttpResponseCallback response_callback_;
};

}

#endif

6、httpserver.cc


#include "httpserver.h"

#include <functional>

#include "address.h"

using namespace tiny_muduo;

using tiny_muduo::Version;

HttpServer::HttpServer(EventLoop* loop, 
                       const Address& address,
                       bool auto_close_idleconnection) 
    : loop_(loop),
      server_(loop, address),
      auto_close_idleconnection_(auto_close_idleconnection) { 
        
  server_.SetConnectionCallback(
          std::bind(&HttpServer::ConnectionCallback, this, _1));
  server_.SetMessageCallback(
          std::bind(&HttpServer::MessageCallback, this, _1, _2));
  SetHttpResponseCallback(std::bind(&HttpServer::HttpDefaultCallback, this, _1, _2));
  LOG_INFO << "Httpserver listening on " << address.ip() << ':' << address.port();
}

HttpServer::~HttpServer() { 
        
}

void HttpServer::MessageCallback(const TcpConnectionPtr& connection, 
                                 Buffer* buffer) { 
        
 HttpContent* content = connection->GetHttpContent();
 if (auto_close_idleconnection_) connection->UpdateTimestamp(Timestamp::Now());
 if (connection->IsShutdown()) return;

 if (!content->ParseContent(buffer)) { 
        
   connection->Send("HTTP/1.1 400 Bad Request\r\n\r\n");
   connection->Shutdown();
 }   

 if (content->GetCompleteRequest()) { 
        
   DealWithRequest(content->request(), connection);
   content->ResetContentState();
 }   
}

void HttpServer::DealWithRequest(const HttpRequest& request, 
                                 const TcpConnectionPtr& connection) { 
        
  string connection_state = std::move(request.GetHeader("Connection"));
  bool close = (connection_state == "Close" || 
               (request.version() == kHttp10 &&
                connection_state != "Keep-Alive"));

  HttpResponse response(close); 
  response_callback_(request, response);
  Buffer buffer;
  response.AppendToBuffer(&buffer);
  connection->Send(&buffer);

  if (response.CloseConnection()) { 
        
    connection->Shutdown();
  }   
}

标签: 连接器xcd45t4k1p40102k400vac瓷片电容221k400vac陶瓷电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台