Golang Http Server Source Reading

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

The reason this article appears is that business needs to create a Web Server. Creating the Web is one of the features that must be implemented for all languages to appear. Today, where nginx+fastcgi+php is widely used, we might as well use go to build a Web server.

Objective

There are a lot of packages using go to build a Web server, there are several ways to use the net package directly, using the Net.http package, using third-party packages (such as gorilla). The use of net package needs to start from the TCP layer encapsulation, the cost of manpower and material, decisive abandon. Direct use of packaged net.http and third-party packages is the best policy. Here we choose to use the official Net.http package to build a Web service. In addition, Gorilla's third-party package is now used or very wide, the document is also relatively full, interested students can consider using a bit.

Suggest reading this article before you look at the Net/http document http://golang.org/pkg/net/http/

There are many files in the Net.http package, which are related to the HTTP protocol, such as setting up Cookie,header and so on. One of the most important files is server.go, and this is the file we're reading here.

Several important concepts

Responsewriter: Generating interfaces for response

Handler: Processing requests and generating returned interfaces

Servemux: Route, which will say Servemux is also a handler

Conn: Network connection

Specific analysis

(Specific instructions are placed directly in the code in the form of annotations)

Several interfaces:

Handler

Type Handler Interface {servehttp (Responsewriter, *request)  //Concrete logical function}

The object that implements the handler interface means that the logic to process the request is added to the server side.

Here are three interfaces (Responsewriter, Flusher, hijacker):

Responsewriter, Flusher, hijacker

Responsewriter is used by handler to assemble the returned response type Responsewriter interface {//This method returns the header returned by response for the read and write header () header//This method writes response's Bodywrite ([]byte) (int, error)//This method writes response Headerwriteheader (int) According to the HTTP state code}// Flusher is used by handler to push data from the write cache to the client type Flusher interface {//This method pushes the data in the write cache to the client flush ()}// The hijacker function is used by handler to close the type of the connection hijacker interface {//This method allows the caller to actively manage the connection hijack () (net. Conn, *bufio. Readwriter, Error)}

Response

Implementation of the three interface structure is response (this structure is the HTTP packet private, in the document is not shown, need to see the source code)

Response contains all server-side HTTP return information type response struct {conn          *conn         //Save information for this HTTP connection req           *request// Corresponding request information chunking      BOOL//     whether to use Chunkwroteheader   bool     //header has performed write operation wrotecontinue bool     //100 Continue response was Writtenheader        Header   //return HTTP Headerwritten       Int64    // The number of bytes in the body contentlength Int64    //Content length status        int      //HTTP status needsniff bool//     Whether you need to use sniff. (When the Content-type is not set, the sniff can be determined according to the HTTP body content-type) closeafterreply bool     //whether to maintain long links. If the client sends a request that connection has keep-alive, this field is set to false. requestbodylimithit BOOL//Whether the requestbody is too large (when the requestbody is too large, response will return 411 states and close the connection)}

You can see it in the response.

Func (w *response) Header () Headerfunc (w *response) writeheader (code int) func (w *response) Write (data []byte) (n int, er R Error) func (w *response) Flush () func (w *response) Hijack () (RWC net. Conn, buf *bufio. Readwriter, err Error)

So many ways. So response realized the responsewriter,flusher,hijacker of these three interfaces

Handlerfunc

Handlerfunc is a type that is often used

The HANDLERFUNC is defined here as a function type, so after a call to A = Handlerfunc (f), the servehttp of call a is actually the corresponding method of calling F, type Handlerfunc func ( Responsewriter, *request)//Servehttp calls F (W, R). Func (f Handlerfunc) servehttp (w responsewriter, R *request) {f (W, R)}

It needs a little more aftertaste here, what does this handlerfunc definition and servehttp together explain? Illustrates that all instances of Handlerfunc implement the Servehttp method. Also, what is the Servehttp method implemented? Implements the interface handler!

So you'll see a lot of these sentences later:

Func Adminhandler (w responsewriter, R *request) {    ...} Handler: = Handlerfunc (Adminhandler) handler. Servehttp (W,r)

Please don't be surprised, you obviously did not write servehttp, how can call? Actually calling Servehttp is calling Adminhandler.

Well, it took me a long time to understand this, with a small example written by the last Play.google.

Http://play.golang.org/p/nSt_wcjc2u

Students who are interested in continuing the study can continue to experiment

If you understand handlerfunc, you will not be surprised by the following two sentences.

Func NotFound (w responsewriter, R *request) {Error (w, "404 Page Not Found", Statusnotfound)}func Notfoundhandler () Handl ER {return handlerfunc (NotFound)}

Next, look at Server.go.

SERVERMUX structure

It is the routing rule in the HTTP package. You can register your routing rules in Servermux and, when a request arrives, determine which processor (Handler) to distribute the request to, based on these routing rules.

It is structured as follows:

Type servemux struct {mu sync. Rwmutex   //Lock, because the request design to concurrent processing, so here need a lock mechanism m  map[string]muxentry  //Routing rules, a string corresponding to a MUX entity, The string here is my registered routing expression}

Here's a look at muxentry.

Type muxentry struct {explicit bool   //Whether exactly match H        Handler//This route expression corresponds to which Handler}

Seeing these two structures should be a way of thinking about how requests are routed :

When a request comes in, the server sequentially matches the string (route expression) in servemux.m, and if a matching muxentry is found, take out muxEntry.h, which is a handler, Call handler in Servehttp (Responsewriter, *request) to assemble the response and return.

The methods defined by Servemux are:

Func (Mux *servemux) match (path string) Handler   //Get Handlerfunc (Mux *servemux) Handler (R *request) based on path Handler
  //get handler based on request, internal implementation calls Matchfunc (Mux *servemux) servehttp (w responsewriter, R *request)//!! This note, Servehttp also implements the handler interface, which is actually a handler! The internal implementation calls Handlerfunc (Mux *servemux) Handle (pattern string, Handler handler)//Register Handler method func (Mux *servemux) Handlefunc ( Pattern string, handler func (Responsewriter, *request))  //Register handler method (register directly with Func)

The defaultservemux that are commonly seen in the Godoc documentation are HTTP default usage Servemux

var Defaultservemux = Newservemux ()

If we do not have a custom servemux, the system uses this Servemux by default.

In other words, the HTTP package provides several methods in the outer (non-SERVEMUX):

Func Handle (pattern string, handler handler) {Defaultservemux.handle (pattern, handler)}func Handlefunc (Pattern string, Handler func (Responsewriter, *request)) {Defaultservemux.handlefunc (pattern, handler)}

is actually called the SERVEMUX structure inside the corresponding method.

Server

There is a server structure left below

Type Server struct {Addr           string        //listening address and port Handler        Handler       // All requests need to be called by the handler (which is actually said to be servemux more precisely) if NULL is set to Defaultservemuxreadtimeout time    . Duration//Read the maximum timeout time writetimeout times   . Duration//write maximum timeout time maxheaderbytes int           //Request Header Maximum length tlsconfig      *tls. Config   //configure TLS}

The methods provided by the server are:

Func (SRV *server) Serve (l net. Listener) Error   //Listen to a port, which is called for to accept the processing of func (SRV *server) listenandserve () error  //Turn on the HTTP Server service , internal call Servefunc (SRV *server) listenandservetls (CertFile, keyfile String) error//Turn on HTTPS Server service, internal call serve

Of course, the HTTP packet also directly provides a method for external use, in fact, the internal instantiation of a server, and then call the Listenandserve method

Func listenandserve (addr string, handler handler) error   //Turn on HTTP service func listenandservetls (addr string, CertFile String, keyfile string, handler handler) error//Turn on HTTPS service

Specific example Analysis

According to the above analysis, we read an example. This example builds a simple Server service. When calling Http://XXXX:12345/hello, the page will return "Hello World"

Func HelloServer (w http. Responsewriter, req *http. Request) {io. WriteString (W, "Hello, world!\n")}func Main () {http. Handlefunc ("/hello", HelloServer) Err: = http. Listenandserve (": 12345", nil) if err! = Nil {log. Fatal ("Listenandserve:", Err)}}

First Call Http.handlefunc

In order to do a few things:

1 called the Handlefunc of Defaultservermux.

2 called the handle of Defaultservermux.

3 Add the corresponding handler and routing rules to the map[string]muxentry in Defaultservemux

Next, call HTTP. Listenandserve (": 12345", nil)

In order to do a few things:

1 instantiating the server

2 calling the server's Listenandserve ()

3 Call net. Listen ("tcp", addr) Listening port

4 Start A For loop, accept requests in the loop body

5 instantiate a conn for each request and open a Goroutine to service the request Go C.serve ()

6 read the contents of each request W, err: = C.readrequest ()

7 determine if the header is empty, if not set handler (this example does not set handler), handler is set to Defaultservemux

8 Calling Handler's Servehttp

9 In this example, the following goes into the Defaultservermux.servehttp

10 Select handler according to request and enter into this handler servehttp

Mux.handler (R). Servehttp (W, R)

11 Select handler:

A determine if there is a route to satisfy this request (looping through Servermux's muxentry)

B If there is a route to satisfy, call this route handler Servehttp

C If no route is met, call Notfoundhandler's servehttp

Postscript

It is important to understand the server in the Net.http package. Clearing Servermux, Responsewriter, Handler, Handlerfunc and other commonly used structures and functions is an important step in using the Go Web. Personal feeling because go Chinese file less, like this a bit complex package, see Godoc effect is far less than directly see the code to fast and clear. In fact, after you understand the HTTP packet, you will understand the sentences appearing in Godoc. You will also write articles about using net.http to build Web server. Please look forward to it.

Related Article

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.