github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/p2p/simulations/http.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:44</date>
    10  //</624342661293150208>
    11  
    12  
    13  package simulations
    14  
    15  import (
    16  	"bufio"
    17  	"bytes"
    18  	"context"
    19  	"encoding/json"
    20  	"fmt"
    21  	"io"
    22  	"io/ioutil"
    23  	"net/http"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  
    28  	"github.com/ethereum/go-ethereum/event"
    29  	"github.com/ethereum/go-ethereum/p2p"
    30  	"github.com/ethereum/go-ethereum/p2p/discover"
    31  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    32  	"github.com/ethereum/go-ethereum/rpc"
    33  	"github.com/julienschmidt/httprouter"
    34  	"golang.org/x/net/websocket"
    35  )
    36  
    37  //DefaultClient是默认的模拟API客户端,它需要API
    38  //在http://localhost:8888上运行
    39  var DefaultClient = NewClient("http://本地主机:8888“)
    40  
    41  //客户端是支持创建的模拟HTTP API的客户端
    42  //以及管理模拟网络
    43  type Client struct {
    44  	URL string
    45  
    46  	client *http.Client
    47  }
    48  
    49  //new client返回新的模拟API客户端
    50  func NewClient(url string) *Client {
    51  	return &Client{
    52  		URL:    url,
    53  		client: http.DefaultClient,
    54  	}
    55  }
    56  
    57  //GetNetwork返回网络的详细信息
    58  func (c *Client) GetNetwork() (*Network, error) {
    59  	network := &Network{}
    60  	return network, c.Get("/", network)
    61  }
    62  
    63  //StartNetwork启动模拟网络中的所有现有节点
    64  func (c *Client) StartNetwork() error {
    65  	return c.Post("/start", nil, nil)
    66  }
    67  
    68  //stopNetwork停止模拟网络中的所有现有节点
    69  func (c *Client) StopNetwork() error {
    70  	return c.Post("/stop", nil, nil)
    71  }
    72  
    73  //创建快照创建网络快照
    74  func (c *Client) CreateSnapshot() (*Snapshot, error) {
    75  	snap := &Snapshot{}
    76  	return snap, c.Get("/snapshot", snap)
    77  }
    78  
    79  //LoadSnapshot将快照加载到网络中
    80  func (c *Client) LoadSnapshot(snap *Snapshot) error {
    81  	return c.Post("/snapshot", snap, nil)
    82  }
    83  
    84  //subscribeopts是订阅网络时要使用的选项集合
    85  //事件
    86  type SubscribeOpts struct {
    87  //current指示服务器发送现有节点的事件和
    88  //先连接
    89  	Current bool
    90  
    91  //筛选器指示服务器仅发送消息事件的子集
    92  	Filter string
    93  }
    94  
    95  //订阅网络订阅从服务器发送的网络事件
    96  //作为服务器发送的事件流,可以选择接收现有事件
    97  //节点和连接以及筛选消息事件
    98  func (c *Client) SubscribeNetwork(events chan *Event, opts SubscribeOpts) (event.Subscription, error) {
    99  	url := fmt.Sprintf("%s/events?current=%t&filter=%s", c.URL, opts.Current, opts.Filter)
   100  	req, err := http.NewRequest("GET", url, nil)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	req.Header.Set("Accept", "text/event-stream")
   105  	res, err := c.client.Do(req)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  	if res.StatusCode != http.StatusOK {
   110  		response, _ := ioutil.ReadAll(res.Body)
   111  		res.Body.Close()
   112  		return nil, fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response)
   113  	}
   114  
   115  //定义要传递到事件的生产者函数。订阅
   116  //从Res.Body读取服务器发送的事件并发送
   117  //他们到活动频道
   118  	producer := func(stop <-chan struct{}) error {
   119  		defer res.Body.Close()
   120  
   121  //在Goroutine中阅读Res.Body的台词,这样我们
   122  //总是从停止通道读取
   123  		lines := make(chan string)
   124  		errC := make(chan error, 1)
   125  		go func() {
   126  			s := bufio.NewScanner(res.Body)
   127  			for s.Scan() {
   128  				select {
   129  				case lines <- s.Text():
   130  				case <-stop:
   131  					return
   132  				}
   133  			}
   134  			errC <- s.Err()
   135  		}()
   136  
   137  //检测以“数据:”开头的任何行,解码数据
   138  //将其发送到事件频道
   139  		for {
   140  			select {
   141  			case line := <-lines:
   142  				if !strings.HasPrefix(line, "data:") {
   143  					continue
   144  				}
   145  				data := strings.TrimSpace(strings.TrimPrefix(line, "data:"))
   146  				event := &Event{}
   147  				if err := json.Unmarshal([]byte(data), event); err != nil {
   148  					return fmt.Errorf("error decoding SSE event: %s", err)
   149  				}
   150  				select {
   151  				case events <- event:
   152  				case <-stop:
   153  					return nil
   154  				}
   155  			case err := <-errC:
   156  				return err
   157  			case <-stop:
   158  				return nil
   159  			}
   160  		}
   161  	}
   162  
   163  	return event.NewSubscription(producer), nil
   164  }
   165  
   166  //getnodes返回网络中存在的所有节点
   167  func (c *Client) GetNodes() ([]*p2p.NodeInfo, error) {
   168  	var nodes []*p2p.NodeInfo
   169  	return nodes, c.Get("/nodes", &nodes)
   170  }
   171  
   172  //createNode使用给定的配置在网络中创建节点
   173  func (c *Client) CreateNode(config *adapters.NodeConfig) (*p2p.NodeInfo, error) {
   174  	node := &p2p.NodeInfo{}
   175  	return node, c.Post("/nodes", config, node)
   176  }
   177  
   178  //getnode返回节点的详细信息
   179  func (c *Client) GetNode(nodeID string) (*p2p.NodeInfo, error) {
   180  	node := &p2p.NodeInfo{}
   181  	return node, c.Get(fmt.Sprintf("/nodes/%s", nodeID), node)
   182  }
   183  
   184  //startnode启动节点
   185  func (c *Client) StartNode(nodeID string) error {
   186  	return c.Post(fmt.Sprintf("/nodes/%s/start", nodeID), nil, nil)
   187  }
   188  
   189  //停止节点停止节点
   190  func (c *Client) StopNode(nodeID string) error {
   191  	return c.Post(fmt.Sprintf("/nodes/%s/stop", nodeID), nil, nil)
   192  }
   193  
   194  //ConnectNode将节点连接到对等节点
   195  func (c *Client) ConnectNode(nodeID, peerID string) error {
   196  	return c.Post(fmt.Sprintf("/nodes/%s/conn/%s", nodeID, peerID), nil, nil)
   197  }
   198  
   199  //断开节点断开节点与对等节点的连接
   200  func (c *Client) DisconnectNode(nodeID, peerID string) error {
   201  	return c.Delete(fmt.Sprintf("/nodes/%s/conn/%s", nodeID, peerID))
   202  }
   203  
   204  //rpc client返回连接到节点的rpc客户端
   205  func (c *Client) RPCClient(ctx context.Context, nodeID string) (*rpc.Client, error) {
   206  	baseURL := strings.Replace(c.URL, "http", "ws", 1)
   207  	return rpc.DialWebsocket(ctx, fmt.Sprintf("%s/nodes/%s/rpc", baseURL, nodeID), "")
   208  }
   209  
   210  //GET执行HTTP GET请求,对结果JSON响应进行解码。
   211  //入“出”
   212  func (c *Client) Get(path string, out interface{}) error {
   213  	return c.Send("GET", path, nil, out)
   214  }
   215  
   216  //post执行一个HTTP post请求,将“in”作为JSON主体发送,并且
   217  //将得到的JSON响应解码为“out”
   218  func (c *Client) Post(path string, in, out interface{}) error {
   219  	return c.Send("POST", path, in, out)
   220  }
   221  
   222  //删除执行HTTP删除请求
   223  func (c *Client) Delete(path string) error {
   224  	return c.Send("DELETE", path, nil, nil)
   225  }
   226  
   227  //send执行一个HTTP请求,将“in”作为JSON请求体发送,并且
   228  //将JSON响应解码为“out”
   229  func (c *Client) Send(method, path string, in, out interface{}) error {
   230  	var body []byte
   231  	if in != nil {
   232  		var err error
   233  		body, err = json.Marshal(in)
   234  		if err != nil {
   235  			return err
   236  		}
   237  	}
   238  	req, err := http.NewRequest(method, c.URL+path, bytes.NewReader(body))
   239  	if err != nil {
   240  		return err
   241  	}
   242  	req.Header.Set("Content-Type", "application/json")
   243  	req.Header.Set("Accept", "application/json")
   244  	res, err := c.client.Do(req)
   245  	if err != nil {
   246  		return err
   247  	}
   248  	defer res.Body.Close()
   249  	if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated {
   250  		response, _ := ioutil.ReadAll(res.Body)
   251  		return fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response)
   252  	}
   253  	if out != nil {
   254  		if err := json.NewDecoder(res.Body).Decode(out); err != nil {
   255  			return err
   256  		}
   257  	}
   258  	return nil
   259  }
   260  
   261  //服务器是一个HTTP服务器,提供用于管理模拟网络的API
   262  type Server struct {
   263  	router     *httprouter.Router
   264  	network    *Network
   265  mockerStop chan struct{} //设置后,停止当前mocker
   266  mockerMtx  sync.Mutex    //同步访问Mockerstop字段
   267  }
   268  
   269  //NewServer返回新的模拟API服务器
   270  func NewServer(network *Network) *Server {
   271  	s := &Server{
   272  		router:  httprouter.New(),
   273  		network: network,
   274  	}
   275  
   276  	s.OPTIONS("/", s.Options)
   277  	s.GET("/", s.GetNetwork)
   278  	s.POST("/start", s.StartNetwork)
   279  	s.POST("/stop", s.StopNetwork)
   280  	s.POST("/mocker/start", s.StartMocker)
   281  	s.POST("/mocker/stop", s.StopMocker)
   282  	s.GET("/mocker", s.GetMockers)
   283  	s.POST("/reset", s.ResetNetwork)
   284  	s.GET("/events", s.StreamNetworkEvents)
   285  	s.GET("/snapshot", s.CreateSnapshot)
   286  	s.POST("/snapshot", s.LoadSnapshot)
   287  	s.POST("/nodes", s.CreateNode)
   288  	s.GET("/nodes", s.GetNodes)
   289  	s.GET("/nodes/:nodeid", s.GetNode)
   290  	s.POST("/nodes/:nodeid/start", s.StartNode)
   291  	s.POST("/nodes/:nodeid/stop", s.StopNode)
   292  	s.POST("/nodes/:nodeid/conn/:peerid", s.ConnectNode)
   293  	s.DELETE("/nodes/:nodeid/conn/:peerid", s.DisconnectNode)
   294  	s.GET("/nodes/:nodeid/rpc", s.NodeRPC)
   295  
   296  	return s
   297  }
   298  
   299  //GetNetwork返回网络的详细信息
   300  func (s *Server) GetNetwork(w http.ResponseWriter, req *http.Request) {
   301  	s.JSON(w, http.StatusOK, s.network)
   302  }
   303  
   304  //StartNetwork启动网络中的所有节点
   305  func (s *Server) StartNetwork(w http.ResponseWriter, req *http.Request) {
   306  	if err := s.network.StartAll(); err != nil {
   307  		http.Error(w, err.Error(), http.StatusInternalServerError)
   308  		return
   309  	}
   310  
   311  	w.WriteHeader(http.StatusOK)
   312  }
   313  
   314  //stopNetwork停止网络中的所有节点
   315  func (s *Server) StopNetwork(w http.ResponseWriter, req *http.Request) {
   316  	if err := s.network.StopAll(); err != nil {
   317  		http.Error(w, err.Error(), http.StatusInternalServerError)
   318  		return
   319  	}
   320  
   321  	w.WriteHeader(http.StatusOK)
   322  }
   323  
   324  //StartMocker启动Mocker节点模拟
   325  func (s *Server) StartMocker(w http.ResponseWriter, req *http.Request) {
   326  	s.mockerMtx.Lock()
   327  	defer s.mockerMtx.Unlock()
   328  	if s.mockerStop != nil {
   329  		http.Error(w, "mocker already running", http.StatusInternalServerError)
   330  		return
   331  	}
   332  	mockerType := req.FormValue("mocker-type")
   333  	mockerFn := LookupMocker(mockerType)
   334  	if mockerFn == nil {
   335  		http.Error(w, fmt.Sprintf("unknown mocker type %q", mockerType), http.StatusBadRequest)
   336  		return
   337  	}
   338  	nodeCount, err := strconv.Atoi(req.FormValue("node-count"))
   339  	if err != nil {
   340  		http.Error(w, "invalid node-count provided", http.StatusBadRequest)
   341  		return
   342  	}
   343  	s.mockerStop = make(chan struct{})
   344  	go mockerFn(s.network, s.mockerStop, nodeCount)
   345  
   346  	w.WriteHeader(http.StatusOK)
   347  }
   348  
   349  //StopMocker停止Mocker节点模拟
   350  func (s *Server) StopMocker(w http.ResponseWriter, req *http.Request) {
   351  	s.mockerMtx.Lock()
   352  	defer s.mockerMtx.Unlock()
   353  	if s.mockerStop == nil {
   354  		http.Error(w, "stop channel not initialized", http.StatusInternalServerError)
   355  		return
   356  	}
   357  	close(s.mockerStop)
   358  	s.mockerStop = nil
   359  
   360  	w.WriteHeader(http.StatusOK)
   361  }
   362  
   363  //getmokerlist返回可用mocker的列表
   364  func (s *Server) GetMockers(w http.ResponseWriter, req *http.Request) {
   365  
   366  	list := GetMockerList()
   367  	s.JSON(w, http.StatusOK, list)
   368  }
   369  
   370  //ResetNetwork将网络的所有属性重置为其初始(空)状态
   371  func (s *Server) ResetNetwork(w http.ResponseWriter, req *http.Request) {
   372  	s.network.Reset()
   373  
   374  	w.WriteHeader(http.StatusOK)
   375  }
   376  
   377  //streamNetworkEvents将网络事件作为服务器发送的事件流进行流式处理
   378  func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
   379  	events := make(chan *Event)
   380  	sub := s.network.events.Subscribe(events)
   381  	defer sub.Unsubscribe()
   382  
   383  //如果客户端不在,则停止流
   384  	var clientGone <-chan bool
   385  	if cn, ok := w.(http.CloseNotifier); ok {
   386  		clientGone = cn.CloseNotify()
   387  	}
   388  
   389  //写入将给定事件和数据写入流,如下所示:
   390  //
   391  //事件:<事件>
   392  //数据:<数据>
   393  //
   394  	write := func(event, data string) {
   395  		fmt.Fprintf(w, "event: %s\n", event)
   396  		fmt.Fprintf(w, "data: %s\n\n", data)
   397  		if fw, ok := w.(http.Flusher); ok {
   398  			fw.Flush()
   399  		}
   400  	}
   401  	writeEvent := func(event *Event) error {
   402  		data, err := json.Marshal(event)
   403  		if err != nil {
   404  			return err
   405  		}
   406  		write("network", string(data))
   407  		return nil
   408  	}
   409  	writeErr := func(err error) {
   410  		write("error", err.Error())
   411  	}
   412  
   413  //检查是否已请求筛选
   414  	var filters MsgFilters
   415  	if filterParam := req.URL.Query().Get("filter"); filterParam != "" {
   416  		var err error
   417  		filters, err = NewMsgFilters(filterParam)
   418  		if err != nil {
   419  			http.Error(w, err.Error(), http.StatusBadRequest)
   420  			return
   421  		}
   422  	}
   423  
   424  	w.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
   425  	w.WriteHeader(http.StatusOK)
   426  	fmt.Fprintf(w, "\n\n")
   427  	if fw, ok := w.(http.Flusher); ok {
   428  		fw.Flush()
   429  	}
   430  
   431  //可选发送现有节点和连接
   432  	if req.URL.Query().Get("current") == "true" {
   433  		snap, err := s.network.Snapshot()
   434  		if err != nil {
   435  			writeErr(err)
   436  			return
   437  		}
   438  		for _, node := range snap.Nodes {
   439  			event := NewEvent(&node.Node)
   440  			if err := writeEvent(event); err != nil {
   441  				writeErr(err)
   442  				return
   443  			}
   444  		}
   445  		for _, conn := range snap.Conns {
   446  			event := NewEvent(&conn)
   447  			if err := writeEvent(event); err != nil {
   448  				writeErr(err)
   449  				return
   450  			}
   451  		}
   452  	}
   453  
   454  	for {
   455  		select {
   456  		case event := <-events:
   457  //仅发送与筛选器匹配的消息事件
   458  			if event.Msg != nil && !filters.Match(event.Msg) {
   459  				continue
   460  			}
   461  			if err := writeEvent(event); err != nil {
   462  				writeErr(err)
   463  				return
   464  			}
   465  		case <-clientGone:
   466  			return
   467  		}
   468  	}
   469  }
   470  
   471  //newmsgfilters从URL查询构造消息筛选器集合
   472  //参数。
   473  //
   474  //该参数应为单独过滤器的虚线分隔列表,
   475  //每个都具有格式“<proto>:<codes>”,其中<proto>是
   476  //Protocol和<codes>是以逗号分隔的消息代码列表。
   477  //
   478  //“*”或“-1”的消息代码被视为通配符并与任何代码匹配。
   479  func NewMsgFilters(filterParam string) (MsgFilters, error) {
   480  	filters := make(MsgFilters)
   481  	for _, filter := range strings.Split(filterParam, "-") {
   482  		protoCodes := strings.SplitN(filter, ":", 2)
   483  		if len(protoCodes) != 2 || protoCodes[0] == "" || protoCodes[1] == "" {
   484  			return nil, fmt.Errorf("invalid message filter: %s", filter)
   485  		}
   486  		proto := protoCodes[0]
   487  		for _, code := range strings.Split(protoCodes[1], ",") {
   488  			if code == "*" || code == "-1" {
   489  				filters[MsgFilter{Proto: proto, Code: -1}] = struct{}{}
   490  				continue
   491  			}
   492  			n, err := strconv.ParseUint(code, 10, 64)
   493  			if err != nil {
   494  				return nil, fmt.Errorf("invalid message code: %s", code)
   495  			}
   496  			filters[MsgFilter{Proto: proto, Code: int64(n)}] = struct{}{}
   497  		}
   498  	}
   499  	return filters, nil
   500  }
   501  
   502  //msgfilters是用于筛选消息的筛选器的集合
   503  //事件
   504  type MsgFilters map[MsgFilter]struct{}
   505  
   506  //匹配检查给定消息是否与任何筛选器匹配
   507  func (m MsgFilters) Match(msg *Msg) bool {
   508  //检查是否存在消息协议的通配符筛选器
   509  	if _, ok := m[MsgFilter{Proto: msg.Protocol, Code: -1}]; ok {
   510  		return true
   511  	}
   512  
   513  //检查是否有消息协议和代码的筛选器
   514  	if _, ok := m[MsgFilter{Proto: msg.Protocol, Code: int64(msg.Code)}]; ok {
   515  		return true
   516  	}
   517  
   518  	return false
   519  }
   520  
   521  //msgfilter用于根据协议和消息筛选消息事件
   522  //代码
   523  type MsgFilter struct {
   524  //协议与消息的协议匹配
   525  	Proto string
   526  
   527  //代码与消息的代码匹配,其中-1与所有代码匹配
   528  	Code int64
   529  }
   530  
   531  //创建快照创建网络快照
   532  func (s *Server) CreateSnapshot(w http.ResponseWriter, req *http.Request) {
   533  	snap, err := s.network.Snapshot()
   534  	if err != nil {
   535  		http.Error(w, err.Error(), http.StatusInternalServerError)
   536  		return
   537  	}
   538  
   539  	s.JSON(w, http.StatusOK, snap)
   540  }
   541  
   542  //LoadSnapshot将快照加载到网络中
   543  func (s *Server) LoadSnapshot(w http.ResponseWriter, req *http.Request) {
   544  	snap := &Snapshot{}
   545  	if err := json.NewDecoder(req.Body).Decode(snap); err != nil {
   546  		http.Error(w, err.Error(), http.StatusBadRequest)
   547  		return
   548  	}
   549  
   550  	if err := s.network.Load(snap); err != nil {
   551  		http.Error(w, err.Error(), http.StatusInternalServerError)
   552  		return
   553  	}
   554  
   555  	s.JSON(w, http.StatusOK, s.network)
   556  }
   557  
   558  //createNode使用给定的配置在网络中创建节点
   559  func (s *Server) CreateNode(w http.ResponseWriter, req *http.Request) {
   560  	config := &adapters.NodeConfig{}
   561  
   562  	err := json.NewDecoder(req.Body).Decode(config)
   563  	if err != nil && err != io.EOF {
   564  		http.Error(w, err.Error(), http.StatusBadRequest)
   565  		return
   566  	}
   567  
   568  	node, err := s.network.NewNodeWithConfig(config)
   569  	if err != nil {
   570  		http.Error(w, err.Error(), http.StatusInternalServerError)
   571  		return
   572  	}
   573  
   574  	s.JSON(w, http.StatusCreated, node.NodeInfo())
   575  }
   576  
   577  //getnodes返回网络中存在的所有节点
   578  func (s *Server) GetNodes(w http.ResponseWriter, req *http.Request) {
   579  	nodes := s.network.GetNodes()
   580  
   581  	infos := make([]*p2p.NodeInfo, len(nodes))
   582  	for i, node := range nodes {
   583  		infos[i] = node.NodeInfo()
   584  	}
   585  
   586  	s.JSON(w, http.StatusOK, infos)
   587  }
   588  
   589  //getnode返回节点的详细信息
   590  func (s *Server) GetNode(w http.ResponseWriter, req *http.Request) {
   591  	node := req.Context().Value("node").(*Node)
   592  
   593  	s.JSON(w, http.StatusOK, node.NodeInfo())
   594  }
   595  
   596  //startnode启动节点
   597  func (s *Server) StartNode(w http.ResponseWriter, req *http.Request) {
   598  	node := req.Context().Value("node").(*Node)
   599  
   600  	if err := s.network.Start(node.ID()); err != nil {
   601  		http.Error(w, err.Error(), http.StatusInternalServerError)
   602  		return
   603  	}
   604  
   605  	s.JSON(w, http.StatusOK, node.NodeInfo())
   606  }
   607  
   608  //停止节点停止节点
   609  func (s *Server) StopNode(w http.ResponseWriter, req *http.Request) {
   610  	node := req.Context().Value("node").(*Node)
   611  
   612  	if err := s.network.Stop(node.ID()); err != nil {
   613  		http.Error(w, err.Error(), http.StatusInternalServerError)
   614  		return
   615  	}
   616  
   617  	s.JSON(w, http.StatusOK, node.NodeInfo())
   618  }
   619  
   620  //ConnectNode将节点连接到对等节点
   621  func (s *Server) ConnectNode(w http.ResponseWriter, req *http.Request) {
   622  	node := req.Context().Value("node").(*Node)
   623  	peer := req.Context().Value("peer").(*Node)
   624  
   625  	if err := s.network.Connect(node.ID(), peer.ID()); err != nil {
   626  		http.Error(w, err.Error(), http.StatusInternalServerError)
   627  		return
   628  	}
   629  
   630  	s.JSON(w, http.StatusOK, node.NodeInfo())
   631  }
   632  
   633  //断开节点断开节点与对等节点的连接
   634  func (s *Server) DisconnectNode(w http.ResponseWriter, req *http.Request) {
   635  	node := req.Context().Value("node").(*Node)
   636  	peer := req.Context().Value("peer").(*Node)
   637  
   638  	if err := s.network.Disconnect(node.ID(), peer.ID()); err != nil {
   639  		http.Error(w, err.Error(), http.StatusInternalServerError)
   640  		return
   641  	}
   642  
   643  	s.JSON(w, http.StatusOK, node.NodeInfo())
   644  }
   645  
   646  //选项通过返回200 OK响应来响应选项HTTP方法
   647  //将“访问控制允许邮件头”邮件头设置为“内容类型”
   648  func (s *Server) Options(w http.ResponseWriter, req *http.Request) {
   649  	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
   650  	w.WriteHeader(http.StatusOK)
   651  }
   652  
   653  //node rpc通过websocket将rpc请求转发到网络中的节点
   654  //连接
   655  func (s *Server) NodeRPC(w http.ResponseWriter, req *http.Request) {
   656  	node := req.Context().Value("node").(*Node)
   657  
   658  	handler := func(conn *websocket.Conn) {
   659  		node.ServeRPC(conn)
   660  	}
   661  
   662  	websocket.Server{Handler: handler}.ServeHTTP(w, req)
   663  }
   664  
   665  //servehtp通过委托给
   666  //底层httprouter.router
   667  func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
   668  	s.router.ServeHTTP(w, req)
   669  }
   670  
   671  //get为特定路径的get请求注册一个处理程序
   672  func (s *Server) GET(path string, handle http.HandlerFunc) {
   673  	s.router.GET(path, s.wrapHandler(handle))
   674  }
   675  
   676  //post为特定路径的post请求注册一个处理程序
   677  func (s *Server) POST(path string, handle http.HandlerFunc) {
   678  	s.router.POST(path, s.wrapHandler(handle))
   679  }
   680  
   681  //delete为特定路径的删除请求注册处理程序
   682  func (s *Server) DELETE(path string, handle http.HandlerFunc) {
   683  	s.router.DELETE(path, s.wrapHandler(handle))
   684  }
   685  
   686  //选项为特定路径的选项请求注册处理程序
   687  func (s *Server) OPTIONS(path string, handle http.HandlerFunc) {
   688   /*outer.options(“/*路径”,s.wraphandler(handle))
   689  }
   690  
   691  //JSON以JSON HTTP响应的形式发送“data”
   692  func(s*server)json(w http.responsewriter,status int,数据接口)
   693   w.header().set(“内容类型”,“应用程序/json”)。
   694   w.writeheader(状态)
   695   json.newencoder(w).encode(数据)
   696  }
   697  
   698  //wraphandler返回一个httprouter.handle,它将http.handlerFunc包装为
   699  //用URL参数中的任何对象填充request.context
   700  func(s*server)wraphandler(handlerHTTP.handlerFunc)httprouter.handle_
   701   返回func(w http.responsewriter,req*http.request,params httprouter.params)
   702    w.header().set(“访问控制允许来源”,“*”)
   703    w.header().set(“访问控制允许方法”、“获取、发布、放置、删除、选项”)。
   704  
   705    ctx:=context.background()。
   706  
   707    如果id:=params.byname(“nodeid”);id!=“{”
   708     VAR节点*节点
   709     如果nodeid,则错误:=discover.hexid(id);err==nil
   710      node=s.network.getnode(nodeid)
   711     }否则{
   712      node=s.network.getnodebyname(id)
   713     }
   714     如果节点==nil
   715      未找到(w,req)
   716      返回
   717     }
   718     ctx=context.withValue(ctx,“节点”,节点)
   719    }
   720  
   721    如果id:=params.byname(“peerid”);id!=“{”
   722     VaR对等节点
   723     如果peerID,则错误:=discover.hexid(id);err==nil
   724      peer=s.network.getnode(peerid)
   725     }否则{
   726      peer=s.network.getnodebyname(id)
   727     }
   728     如果peer==nil
   729      未找到(w,req)
   730      返回
   731     }
   732     ctx=context.withValue(ctx,“对等”,对等)
   733    }
   734  
   735    处理程序(w,req.withContext(ctx))。
   736   }
   737  }
   738