Giter Club home page Giter Club logo

s's People

Contributors

agilesw avatar hylon-w avatar star3s avatar xujintao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

s's Issues

请支持自动响应options请求

主流go语言http路由解析组件默认是这么玩的:
当收到options请求,只要请求路径能匹配到路由表中的任一url模式(不管http方法为何),则返回200,否则返回404

目前ssgo不支持该特性,请支持

路由错误

{
  "listen": ":8080",
  "httpVersion": 1,
  "rwTimeout": 5000,
  "keepaliveTimeout": 15000,
  "rewriteTimeout": 10000,
  "noLogGets": false,
  "noLogHeaders": "Accept,Accept-Encoding,Cache-Control,Pragma,Connection",
  "noLogInputFields": false,
  "logInputArrayNum": 0,
  "logOutputFields": "code,message",
  "logOutputArrayNum": 2,
  "logWebsocketAction": false,
  "compress": true,
  "certFile": "",
  "keyFile": ""
}
package main

import (
	"github.com/ssgo/s"
	"net/http"
)

func main() {
	s.Restful(0, http.MethodGet, "/hello/{id}/uploadlog", func() string {
		return "Hello upload\n"
	})
	s.Restful(0, http.MethodGet, "/hello/{id}", func() string {
		return "Hello id\n"
	})
	s.Start()
}

以上是源码,在本地请求的时候:

http://192.168.50.50:8080/hello/1/uploadlog

结果:

Hello id

日志:

2019/08/19 22:16:30.793360 {"app":"","info":"starting","logTime":1566224190.7933598,"logType":"server","node":":8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
2019/08/19 22:16:30.868963 {"app":"","info":"started","logTime":1566224190.8689635,"logType":"server","node":"192.168.50.50:8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
2019/08/19 22:16:57.273251 {"app":"","authLevel":0,"clientId":"","clientIp":"192.168.50.50","fromApp":"","fromNode":"","host":"192.168.50.50:8080","logTime":1566224217.2732513,"logType":"request","method":"GET","node":"192.168.50.50:8080","path":"/hello/1/uploadlog","priority":0,"proto":"1.1","requestData":{"id":"1/uploadlog"},"requestHeaders":{"Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36","X-Host":"192.168.50.50:8080","X-Real-Ip":"192.168.50.50","X-Request-Id":"PMTaIkuC4Zuk5BcAo8BodX","X-Scheme":"http"},"requestId":"PMTaIkuC4Zuk5BcAo8BodX","responseCode":200,"responseData":"Hello id\n","responseDataLength":9,"responseHeaders":{},"scheme":"http","serverId":"CEVk7dIHEfs","sessionId":"","traceId":"PMTaIkuC4Zuk5BcAo8BodX","usedTime":0,"type":"ACCESS"}
2019/08/19 22:17:09.333941 {"app":"","info":"stopping router","logTime":1566224229.333941,"logType":"server","node":"192.168.50.50:8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
2019/08/19 22:17:09.333941 {"app":"","info":"waiting router","logTime":1566224229.333941,"logType":"server","node":"192.168.50.50:8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
2019/08/19 22:17:09.333941 {"app":"","info":"waiting discover","logTime":1566224229.333941,"logType":"server","node":"192.168.50.50:8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
2019/08/19 22:17:09.333941 {"app":"","info":"stopped","logTime":1566224229.333941,"logType":"server","node":"192.168.50.50:8080","proto":"http","startTime":1566224190.7933598,"traceId":"CEVk7dIHEfs","weight":100}
```json

我的本意是需要请求:/hello/{id}/uploadlog 这个路由,可是路由错了

如果同时存在url变量和json实体,怎么玩??

目前,从我了解到的情况,无论查询参数、表单参数、其它实体内容,都被放到in struct中。假如那几项同时需要,怎么玩??

假如有下面的请求:

POST /api/users/123 HTTP/1.1
Host: 127.0.0.1:14176
Content-Type: application/json
Cache-Control: no-cache

{
	"name": "wencan",
	"age": 18
}

需要获取到url中的123,还需要获取到json实体,怎么玩??

panic: runtime error: invalid memory address or nil pointer dereference

go run 下面的代码,触发该bug

package main

import (
	"fmt"
    "net/http"
    "os"
    "log"
	"github.com/ssgo/s"
)

func main() {
	 os.Setenv("SERVICE_APP", "s1")
	 os.Setenv("service_LOGFILE", os.DevNull)
	 os.Setenv("SERVICE_LISTEN", ":8080")
	 s.Restful(0, http.MethodGet, "/hello/{name}", func(args map[string]interface{}, w http.ResponseWriter, r *http.Request) {
	 	fmt.Fprintln(os.Stdout, args)
	 	log.Println(r.URL.Path)
	 	fmt.Fprintf(w, "Hello world\n")
	 })
	 s.Start1()
}

输出的错误信息:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x7ce6a6]

goroutine 1 [running]:
github.com/ssgo/s.start(0x1, 0x0, 0x0, 0xc0000e3f88)
	/home/wencan/Projects/Go/src/github.com/ssgo/s/Server.go:426 +0x27c6
github.com/ssgo/s.Start1()
	/home/wencan/Projects/Go/src/github.com/ssgo/s/Server.go:116 +0x33
main.main()
	/home/wencan/Projects/main.go:20 +0xff
exit status 2

源码分析:

	if err != nil {
		Error("S", Map{
			"subLogType": "server",
			"type":       "listenFailed",
			"listen":     config.Listen,
			"error":      err.Error(),
		})
		//log.Print("SERVER	", err)
		if as != nil {
			as.startChan <- false
		}
		return err
	}

        // 这里,err == nil

	closeChan := make(chan os.Signal, 2)
	signal.Notify(closeChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-closeChan
		listener.Close()
	}()

	addrInfo := listener.Addr().(*net.TCPAddr)
	ip := addrInfo.IP
	port := addrInfo.Port
	if !ip.IsGlobalUnicast() {
		// 如果监听的不是外部IP,使用第一个外部IP
		addrs, _ := net.InterfaceAddrs()
		for _, a := range addrs {
			an := a.(*net.IPNet)
			// 忽略 Docker 私有网段
			if an.IP.IsGlobalUnicast() && !strings.HasPrefix(an.IP.To4().String(), "172.17.") {
				ip = an.IP.To4()
			}
		}
	}
	serverAddr = fmt.Sprintf("%s:%d", ip.String(), port)

	dconf := discover.Config{
		Registry:             config.Registry,
		RegistryAllowTimeout: config.RegistryAllowTimeout,
		RegistryPrefix:       config.RegistryPrefix,
		RegistryCalls:        config.RegistryCalls,
		App:                  config.App,
		Weight:               config.Weight,
		CallRetryTimes:       config.CallRetryTimes,
		XUniqueId:            config.XUniqueId,
		XForwardedForName:    config.XForwardedForName,
		XRealIpName:          config.XRealIpName,
		CallTimeout:          config.CallTimeout,
	}
	calls := map[string]*discover.CallInfo{}
	if config.Calls == nil {
		config.Calls = map[string]*Call{}
	}
	for k, v := range config.Calls {
		call := discover.CallInfo{
			Timeout:     v.Timeout,
			HttpVersion: v.HttpVersion,
			WithSSL:     v.WithSSL,
		}
		call.Headers = map[string]string{}
		if v.AccessToken != "" {
			call.Headers["Access-Token"] = v.AccessToken
		}
		if v.Host != "" {
			call.Headers["Host"] = v.Host
		}
		calls[k] = &call
	}
	dconf.Calls = calls
	if discover.Start(serverAddr, dconf) == false {
		Error("S", Map{
			"subLogType": "server",
			"type":       "startDiscoverFailed",
			"serverAddr": serverAddr,
			"error":      err.Error(),     // panic: runtime error: invalid memory address or nil pointer dereference
		})
		//log.Printf("SERVER	failed to start discover")
		listener.Close()
		return errors.New("failed to start discover")
	}

向redis注册服务的时候,获取service提供者的ip时,在windows系统上获取的ip不正确

s/Server.go
通过addrs, _ := net.InterfaceAddrs()获取的ip为:addrs, _ := net.InterfaceAddrs()
得到结果:
[fe80::150d:b4b3:cf2c:2d02/64 169.254.45.2/16 192.168.137.1/24 fe80::fd3d:1ddd:40b2:f6fc/64 169.254.246.252/16 fe80::a4cf:b26f:e2ec:3c15/64 169.254.60.21/16 fe80::7982:86dd:4f4:c5b4/64 10.59.6.79/20 fe80::a925:65ee:23ec:24
9a/64 10.51.12.165/24 ::1/128 127.0.0.1/8 fe80::5efe:a33:ca5/128]
通过以下代码段获取到ip地址:
if an.IP.IsGlobalUnicast() && !strings.HasPrefix(an.IP.To4().String(), "172.17.") {
ip = an.IP.To4()
break
}
得到192.168.137.1,这个ip提供的server是无法访问的
实际可用的ip 10.51.12.165

没有处理错误

添加下面的处理:

	s.Restful(0, http.MethodGet, "/api/hello", func(w http.ResponseWriter, r *http.Request) {
		panic(errors.New("Test"))
	})

调用结果:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.