Пример #1
0
// parseURL parses the URL. The url.Parse function is not used here because
// url.Parse mangles the path.
func parseURL(s string) (*url.URL, error) {
	// From the RFC:
	//
	// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
	// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
	//
	// We don't use the net/url parser here because the dialer interface does
	// not provide a way for applications to work around percent deocding in
	// the net/url parser.

	var u url.URL
	switch {
	case strings.HasPrefix(s, "ws://"):
		u.Scheme = "ws"
		s = s[len("ws://"):]
	case strings.HasPrefix(s, "wss://"):
		u.Scheme = "wss"
		s = s[len("wss://"):]
	default:
		return nil, errMalformedURL
	}

	u.Host = s
	u.Opaque = "/"
	if i := strings.Index(s, "/"); i >= 0 {
		u.Host = s[:i]
		u.Opaque = s[i:]
	}

	return &u, nil
}
Пример #2
0
// parseURL parses the URL.
//
// This function is a replacement for the standard library url.Parse function.
// In Go 1.4 and earlier, url.Parse loses information from the path.
func parseURL(s string) (*url.URL, error) {
	// From the RFC:
	//
	// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
	// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]

	var u url.URL
	switch {
	case strings.HasPrefix(s, "ws://"):
		u.Scheme = "ws"
		s = s[len("ws://"):]
	case strings.HasPrefix(s, "wss://"):
		u.Scheme = "wss"
		s = s[len("wss://"):]
	default:
		return nil, errMalformedURL
	}

	u.Host = s
	u.Opaque = "/"
	if i := strings.Index(s, "/"); i >= 0 {
		u.Host = s[:i]
		u.Opaque = s[i:]
	}

	if strings.Contains(u.Host, "@") {
		// Don't bother parsing user information because user information is
		// not allowed in websocket URIs.
		return nil, errMalformedURL
	}

	return &u, nil
}
Пример #3
0
func updatePath(url *url.URL, urlPath string) {
	scheme, query := url.Scheme, url.RawQuery

	// get formatted URL minus scheme so we can build this into Opaque
	url.Scheme, url.Path, url.RawQuery = "", "", ""
	s := url.String()
	url.Scheme = scheme
	url.RawQuery = query

	// build opaque URI
	url.Opaque = s + urlPath
}
Пример #4
0
func updatePath(url *url.URL, urlPath string) {
	scheme, query := url.Scheme, url.RawQuery

	hasSlash := strings.HasSuffix(urlPath, "/")

	// clean up path
	urlPath = path.Clean(urlPath)
	if hasSlash && !strings.HasSuffix(urlPath, "/") {
		urlPath += "/"
	}

	// get formatted URL minus scheme so we can build this into Opaque
	url.Scheme, url.Path, url.RawQuery = "", "", ""
	s := url.String()
	url.Scheme = scheme
	url.RawQuery = query

	// build opaque URI
	url.Opaque = s + urlPath
}
Пример #5
0
func updatePath(url *url.URL, urlPath string) {
	scheme, query := url.Scheme, url.RawQuery

	//path.Clean会去掉最后的斜杠,导致无法创建目录。所以添加以下逻辑
	add := false
	if urlPath[len(urlPath)-1] == '/' && len(urlPath) > 1 {
		add = true
	}
	// clean up path
	urlPath = path.Clean(urlPath)
	if add {
		urlPath += "/"
	}

	// get formatted URL minus scheme so we can build this into Opaque
	url.Scheme, url.Path, url.RawQuery = "", "", ""
	s := url.String()
	url.Scheme = scheme
	url.RawQuery = query

	// build opaque URI
	url.Opaque = s + urlPath
}
Пример #6
0
// SetOpaque sets u.Opaque from u.Path such that HTTP requests to it
// don't alter any hex-escaped characters in u.Path.
func SetOpaque(u *url.URL) {
	u.Opaque = "//" + u.Host + u.Path
	if !has4860Fix {
		u.Opaque = u.Scheme + ":" + u.Opaque
	}
}
Пример #7
0
func (self *Client) addToUrl(u *url.URL, s string) *url.URL {
	u.Opaque = fmt.Sprintf("%s/%s", u.Opaque, s)
	return u
}
Пример #8
0
func pushURL(l *lua.State, u *url.URL) {

	l.NewTable()

	var urlFunc = map[string]func(*url.URL) lua.Function{
		"isAbs":      urlIsAbs,
		"parse":      urlParse,
		"requestURI": urlRequestURI,
		"string":     urlString,
	}

	for name, goFn := range urlFunc {
		l.PushGoFunction(goFn(u))
		l.SetField(-2, name)
	}

	l.NewTable()

	getHook := func(l *lua.State) int {
		key := lua.CheckString(l, 2)
		switch key {
		case "scheme":
			l.PushString(u.Scheme)
		case "opaque":
			l.PushString(u.Opaque)
		case "host":
			l.PushString(u.Host)
		case "path":
			l.PushString(u.Path)
		case "rawQuery":
			l.PushString(u.RawQuery)
		case "fragment":
			l.PushString(u.Fragment)
		default:
			return 0
		}
		return 1
	}

	l.PushGoFunction(getHook)
	l.SetField(-2, "__index")

	setHook := func(l *lua.State) int {
		key := lua.CheckString(l, 2)
		val := lua.CheckString(l, 3)
		switch key {
		case "scheme":
			u.Scheme = val
		case "opaque":
			u.Opaque = val
		case "host":
			u.Host = val
		case "path":
			u.Path = val
		case "rawQuery":
			u.RawQuery = val
		case "fragment":
			u.Fragment = val
		default:
			l.RawSet(1)
		}
		return 0
	}

	l.PushGoFunction(setHook)
	l.SetField(-2, "__newindex")

	l.SetMetaTable(-2)
}
Пример #9
0
func addToURL(u *url.URL, s string) *url.URL {
	u.Opaque = fmt.Sprintf("%s/%s", u.Opaque, s)
	return u
}
Пример #10
-1
func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource string,
	headers map[string]string, data io.Reader) (*Response, error) {
	httpTimeOut := conn.config.HTTPTimeout
	method = strings.ToUpper(method)
	uri.Opaque = uri.Path
	req := &http.Request{
		Method:     method,
		URL:        uri,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Header:     make(http.Header),
		Host:       uri.Host,
	}
	conn.handleBody(req, data)

	date := time.Now().UTC().Format(http.TimeFormat)
	req.Header.Set(HTTPHeaderDate, date)
	req.Header.Set(HTTPHeaderHost, conn.config.Endpoint)
	req.Header.Set(HTTPHeaderUserAgent, conn.config.UserAgent)
	if conn.config.SecurityToken != "" {
		req.Header.Set(HTTPHeaderOssSecurityToken, conn.config.SecurityToken)
	}

	if headers != nil {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}

	conn.signHeader(req, canonicalizedResource)

	timeoutClient := &http.Client{Transport: &http.Transport{
		Dial: func(netw, addr string) (net.Conn, error) {
			conn, err := net.DialTimeout(netw, addr, httpTimeOut.ConnectTimeout)
			if err != nil {
				return nil, err
			}
			return newTimeoutConn(conn, httpTimeOut.ReadWriteTimeout, httpTimeOut.LongTimeout), nil
		},
		ResponseHeaderTimeout: httpTimeOut.HeaderTimeout,
		MaxIdleConnsPerHost:   2000,
	}}

	resp, err := timeoutClient.Do(req)
	if err != nil {
		return nil, err
	}

	return conn.handleResponse(resp)
}