Muduo Source-httpresponse.h

Source: Internet
Author: User

1 Design the HttpResponse class is used to store the data that needs to be sent to the client. The data is some raw data. There is no synthetic complete message. However, an interface is provided to populate the incoming buffer object and synthesize a complete response message. 2 Source code

#ifndef muduo_net_http_httpresponse_h#define muduo_net_http_httpresponse_h#include <muduo/base/copyable.h># Include <muduo/base/Types.h> #include <map>namespace muduo{namespace net{class buffer;//  This class is used to save the constructed response message class Httpresponse:public muduo::copyable{public://State enum HttpStatusCode {kunknown, K200ok  = $, k301movedpermanently = 301, K400badrequest = n, K404notfound = 404,};  The close parameter indicates whether the connection needs to be closed after the send is complete explicit HttpResponse (bool close): Statuscode_ (Kunknown), Closeconnection_ (Close)  {}//Set void Setstatuscode (HttpStatusCode code) {statuscode_ = code;} void Setstatusmessage (const string& message) {Statusmessage_ = message;}  If you need to close the link after sending, you can change the void setcloseconnection (bool on) {closeconnection_ = on;} at a later stage.  BOOL CloseConnection () const {return closeconnection_;}  Various settings and added void setContentType (const string& contentType) {AddHeader ("Content-type", ContentType);} void AddHeader (const string& Key, const string& value) {Headers_[key] = value;}  void Setbody (const string& body) {body_ = body;} A Buffer is passed in and the response message is completely constructed to send the void Appendtobuffer (buffer* output) const;  Private:std::map<string, string> Headers_;  HttpStatusCode Statuscode_;  Fixme:add http version string Statusmessage_;  BOOL Closeconnection_; string Body_;};} #endif//Muduo_net_http_httpresponse_h

Realize

#include <muduo/net/http/HttpResponse.h> #include <muduo/net/Buffer.h> #include <stdio.h>using  Namespace muduo;using namespace muduo::net;//filled void Httpresponse::appendtobuffer (buffer* output) const{char buf[32];  This is HTTP version snprintf (buf, sizeof buf, "http/1.1%d", statuscode_);  Output->append (BUF);  Output->append (Statusmessage_);  Output->append ("\ r \ n");  Start constructing the response header if (Closeconnection_) {output->append ("connection:close\r\n"); } else {//when it is a long connection, it needs subcontracting, so the content-length is used to subcontract snprintf (buf, sizeof buf, "Content-length:%zd\r\n", Body_.siz    E ());    Output->append (BUF);  Output->append ("connection:keep-alive\r\n");       }//Add other fields for (std::map<string, string>::const_iterator it = Headers_.begin ();       It! = Headers_.end ();    ++it) {output->append (It->first);    Output->append (":");    Output->append (It->second);  Output->append ("\ r \ n");  } output->append ("\ r \ n"); Output->append (bODY_);} 

3 Using code HttpResponse is only used here.
void Httpserver::onrequest (CONST tcpconnectionptr& conn, const httprequest& req) {  Const string& Connection = Req.getheader ("Connection");  When the request message is set to OFF, or the HTTP version is 1.0, or the 1.1 version but not set keep-alive  //Then all need to be closed after sending  bool close = Connection = = "Close" | |    (req.getversion () = = Httprequest::khttp10 && Connection! = "Keep-alive");  This generates a HttpResponse object. The parameters are the  httpresponse response (close) calculated from the above;    Httpcallback_ is a function written by the user, more request header, to generate the corresponding response message  Httpcallback_ (req, &response);  Generates a buffer object to hold the generated response message   buffer buf;  The response message is constructed from the response body.  Response.appendtobuffer (&BUF);  Sent to client  Conn->send (&BUF);  Note here that the link will be closed when the above decision should be closed.  There is also the above Httpcallback_ can be based on the request message, to set whether to shut down.  if (Response.closeconnection ())  {    conn->shutdown ();  }}

Look again, httpserver in the Httpcallback_

  void Sethttpcallback (const httpcallback& CB)  {    httpcallback_ = cb;  }

Then continue to see when it will be sent:

First of all:

Processing read event void Tcpconnection::handleread (Timestamp receivetime) {  loop_->assertinloopthread ();  int savederrno = 0;  Used is the dispersion read, then aggregated together  ssize_t n = inputbuffer_.readfd (CHANNEL_->FD (), &savederrno);  if (n > 0)  {    //If the data is read, start executing the callback function    Messagecallback_ (Shared_from_this (), &inputbuffer_, receivetime);  }  else if (n = = 0)  {    //read the data to 0, then directly close the connection, the description is Fin    handleclose ();  }  else  {    //when-1, then an error occurred, should be handled error    errno = Savederrno;    Log_syserr << "Tcpconnection::handleread";    HandleError ();  }}

While in the tcpconnection structure:

Acceptor the callback function that was executed after the new link was acquired//SOCKFD is the return value of acceptor, peeraddr the peer link void acceptor obtained within tcpserver::newconnection (int  SOCKFD, const inetaddress &peeraddr) {loop_->assertinloopthread ();  Then because TCPServer has a eventloop thread pool that is used for practical work.  So this sentence is actually a load balancer, go to a eventloop, later incoming tcpconnection eventloop *ioloop = Threadpool_->getnextloop ();  Here for Tcpconneciont named Char buf[64];  snprintf (buf, sizeof buf, "-%s#%d", Ipport_.c_str (), nextconnid_);  ++nextconnid_;  String connname = Name_ + buf;           Log_info << "tcpserver::newconnection [" << name_ << "]-New Connection [" << Connname  << "] from" << peeraddr.toipport ();  Get the Local address inetaddress localaddr (sockets::getlocaladdr (SOCKFD)); Fixme poll with zero timeout to double confirm the new connection//Fixme use make_shared if necessary//Then create Tcpco                             Nnection Tcpconnectionptr Conn (New Tcpconnection (Ioloop, Connname,             SOCKFD, LOCALADDR, peeraddr  ));  TCPServer saves each link. each//should be for management.  CONNECTIONS_[CONNNAME] = conn;  Fill the Destroy function, notice that these destroy functions, are not tcpserver.  Conn->setconnectioncallback (Connectioncallback_), which is set to tcpserver by a further layer;  Note here that the Messagecallback_ Conn->setmessagecallback (messagecallback_) is bound;  Conn->setwritecompletecallback (Writecompletecallback_); Conn->setclosecallback (Boost::bind (&tcpserver::removeconnection, this, _1));  Fixme:unsafe//Here, Tcpconnection is created.  Then the following is performed Tcpconnection connectestablished (); Ioloop->runinloop (Boost::bind (&tcpconnection::connectestablished, conn));}

Then continue up:

Messagecallback_ is httpserver incoming.
Httpserver::httpserver (eventloop* loop,                       const inetaddress& LISTENADDR,                       const string& name,                       Tcpserver::option Option)  : Server_ (Loop, LISTENADDR, name, Option),    httpcallback_ (detail:: Defaulthttpcallback) {  server_.setconnectioncallback (      boost::bind (&httpserver::onconnection, this, _1 ));      The callback function  Server_.setmessagecallback (      boost::bind (&httpserver::onmessage, this, _1, _2, _3) is called when the message is received. ;}

So after Tcpconnection read out the data, the actual implementation is this:

void Httpserver::onmessage (const tcpconnectionptr& conn,                           buffer* buf,                           Timestamp receivetime) {  //Get Tcpconn binding of the HttpContext object, parsing  httpcontext* context = boost::any_cast

At this point, we know what the call is.

Muduo Source-httpresponse.h

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.