github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/simulations/http.go (about)

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