当前位置: 首页>>代码示例>>Golang>>正文


Golang Request.ProtoMinor方法代码示例

本文整理汇总了Golang中net/http.Request.ProtoMinor方法的典型用法代码示例。如果您正苦于以下问题:Golang Request.ProtoMinor方法的具体用法?Golang Request.ProtoMinor怎么用?Golang Request.ProtoMinor使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在net/http.Request的用法示例。


在下文中一共展示了Request.ProtoMinor方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: increaseTime

func increaseTime(writer http.ResponseWriter, req *http.Request) {
	//This function allows a user, if it owns the allocation, to free an allocation
	//number and all associated nodes.  It resets the resource map and current
	//requests map.
	var end time.Time
	heckleDaemon.DaemonLog.DebugHttp(req)
	heckleDaemon.DaemonLog.LogDebug("Increasing allocation time on an allocation number.")

	req.ProtoMinor = 0
	err := heckleDaemon.AuthN.HTTPAuthenticate(req, false)
	if err != nil {
		heckleDaemon.DaemonLog.LogError("Permission Denied", err)
		writer.WriteHeader(http.StatusUnauthorized)
	}
	heckleDaemon.UpdateActivity()
	username, _, _ := heckleDaemon.AuthN.GetHTTPAuthenticateInfo(req)

	jsonType := heckleDaemon.ProcessJson(req, new(int64))
	timeIncrease := jsonType.(int64)

	resourcesLock.Lock()
	for _, value := range resources {
		if value.Owner == username {
			value.AllocationEndTime = value.AllocationEndTime.Add(time.Duration(timeIncrease))
			end = value.AllocationEndTime
		}
	}
	resourcesLock.Unlock()
	heckleDaemon.DaemonLog.Log(fmt.Sprintf("Increased timeout by %d for %s. Allocation will end at %d", timeIncrease, username, end.Unix()))
	updateDatabase(false)
}
开发者ID:raffenet,项目名称:heckle,代码行数:31,代码来源:heckle.go

示例2: copyRequest

func (l *HttpLocation) copyRequest(req *http.Request, body netutils.MultiReader, endpoint endpoint.Endpoint) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	// Set the body to the enhanced body that can be re-read multiple times and buffered to disk
	outReq.Body = body

	endpointURL := endpoint.GetUrl()
	outReq.URL.Scheme = endpointURL.Scheme
	outReq.URL.Host = endpointURL.Host
	outReq.URL.Opaque = req.RequestURI
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""

	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1

	// Overwrite close flag so we can keep persistent connection for the backend servers
	outReq.Close = false

	outReq.Header = make(http.Header)
	netutils.CopyHeaders(outReq.Header, req.Header)
	return outReq
}
开发者ID:irasmaster,项目名称:vulcan,代码行数:25,代码来源:httploc.go

示例3: post

func post(url_ string, oauthHeaders map[string]string) (r *http.Response, err error) {
	var req http.Request
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Header = map[string][]string{
		"Authorization": {"OAuth "},
	}
	req.TransferEncoding = []string{"chunked"}

	first := true
	for k, v := range oauthHeaders {
		if first {
			first = false
		} else {
			req.Header["Authorization"][0] += ",\n    "
		}
		req.Header["Authorization"][0] += k + "=\"" + v + "\""
	}

	req.URL, err = url.Parse(url_)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
开发者ID:alloy-d,项目名称:goauth,代码行数:28,代码来源:http.go

示例4: copyRequest

func (f *Forwarder) copyRequest(req *http.Request, u *url.URL) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	outReq.URL = utils.CopyURL(req.URL)
	outReq.URL.Scheme = u.Scheme
	outReq.URL.Host = u.Host
	outReq.URL.Opaque = req.RequestURI
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""
	// Go doesn't implicitly pass the host header unless you set Host on the request
	outReq.Host = u.Host

	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1

	// Overwrite close flag so we can keep persistent connection for the backend servers
	outReq.Close = false

	outReq.Header = make(http.Header)
	utils.CopyHeaders(outReq.Header, req.Header)

	if f.rewriter != nil {
		f.rewriter.Rewrite(outReq)
	}
	return outReq
}
开发者ID:pasdoy,项目名称:oxy,代码行数:28,代码来源:fwd.go

示例5: NewFastHTTPHandler

// NewFastHTTPHandler wraps net/http handler to fasthttp request handler,
// so it can be passed to fasthttp server.
//
// While this function may be used for easy switching from net/http to fasthttp,
// it has the following drawbacks comparing to using manually written fasthttp
// request handler:
//
//     * A lot of useful functionality provided by fasthttp is missing
//       from net/http handler.
//     * net/http -> fasthttp handler conversion has some overhead,
//       so the returned handler will be always slower than manually written
//       fasthttp handler.
//
// So it is advisable using this function only for quick net/http -> fasthttp
// switching. Then manually convert net/http handlers to fasthttp handlers
// according to https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp .
func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {
		var r http.Request

		body := ctx.PostBody()
		r.Method = string(ctx.Method())
		r.Proto = "HTTP/1.1"
		r.ProtoMajor = 1
		r.ProtoMinor = 1
		r.RequestURI = string(ctx.RequestURI())
		r.ContentLength = int64(len(body))
		r.Host = string(ctx.Host())
		r.RemoteAddr = ctx.RemoteAddr().String()

		hdr := make(http.Header)
		ctx.Request.Header.VisitAll(func(k, v []byte) {
			hdr.Set(string(k), string(v))
		})
		r.Header = hdr
		r.Body = &netHTTPBody{body}

		var w netHTTPResponseWriter
		h.ServeHTTP(&w, &r)

		ctx.SetStatusCode(w.StatusCode())
		for k, vv := range w.Header() {
			for _, v := range vv {
				ctx.Response.Header.Set(k, v)
			}
		}
		ctx.Write(w.body)
	}
}
开发者ID:xiaoma20082008,项目名称:fasthttp,代码行数:49,代码来源:adaptor.go

示例6: copyRequest

// copyRequest creates a new proxy request with some modifications from an original request.
func copyRequest(originalRequest *http.Request) *http.Request {
	pr := new(http.Request)
	*pr = *originalRequest
	pr.Proto = "HTTP/1.1"
	pr.ProtoMajor = 1
	pr.ProtoMinor = 1
	pr.Close = false
	pr.Header = make(http.Header)
	pr.URL.Scheme = "http"
	pr.URL.Path = originalRequest.URL.Path

	// Copy all header fields.
	for key, values := range originalRequest.Header {
		for _, value := range values {
			pr.Header.Add(key, value)
		}
	}

	// Remove ignored header fields.
	for _, header := range ignoredHeaderNames {
		pr.Header.Del(header)
	}

	// Append this machine's host name into X-Forwarded-For.
	if requestHost, _, err := net.SplitHostPort(originalRequest.RemoteAddr); err == nil {
		if originalValues, ok := pr.Header["X-Forwarded-For"]; ok {
			requestHost = strings.Join(originalValues, ", ") + ", " + requestHost
		}
		pr.Header.Set("X-Forwarded-For", requestHost)
	}

	return pr
}
开发者ID:noonat,项目名称:pruxy,代码行数:34,代码来源:proxy.go

示例7: copyRequest

func (proxy *Proxy) copyRequest(r *http.Request) *http.Request {
	proxyRequest := new(http.Request)
	*proxyRequest = *r
	proxyRequest.Proto = "HTTP/1.1"
	proxyRequest.ProtoMajor = 1
	proxyRequest.ProtoMinor = 1
	proxyRequest.Close = false
	proxyRequest.Header = make(http.Header)
	proxyRequest.URL.Scheme = "http"
	proxyRequest.URL.Path = r.URL.Path

	for key, values := range r.Header {
		for _, value := range values {
			proxyRequest.Header.Add(key, value)
		}
	}
	for _, headerName := range ignoredHeaderNames {
		proxyRequest.Header.Del(headerName)
	}
	if requestHost, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
		if values, ok := proxyRequest.Header["X-Forwarded-For"]; ok {
			requestHost = strings.Join(values, ", ") + ", " + requestHost
		}
		proxyRequest.Header.Set("X-Forwarded-For", requestHost)
	}

	return proxyRequest
}
开发者ID:corrupt952,项目名称:courier,代码行数:28,代码来源:courier.go

示例8: nodeStatus

func nodeStatus(writer http.ResponseWriter, req *http.Request) {
	heckleDaemon.DaemonLog.LogDebug("Sending back node status.")
	response := ""
	req.ProtoMinor = 0
	heckleDaemon.DaemonLog.DebugHttp(req)

	err := heckleDaemon.AuthN.HTTPAuthenticate(req, false)
	if err != nil {
		heckleDaemon.DaemonLog.LogError("Permission Denied", err)
		writer.WriteHeader(http.StatusUnauthorized)
	}
	heckleDaemon.UpdateActivity()
	resourcesLock.Lock()
	//This need to go away as well. Why are we writing out the response...?
	for key, value := range resources {
		if value.Allocated {
			response = response + "NODE: " + key + "\tALLOCATED: yes\tALLOCATION: " + strconv.FormatUint(value.AllocationNumber, 10) + "\tOWNER: " + value.Owner + "\tIMAGE: " + value.Image + "\tALLOCATION START: " + value.TimeAllocated.Format(time.UnixDate) + "\tALLOCATION END: " + value.AllocationEndTime.Format(time.UnixDate) + "\tCOMMENTS: " + value.Comments + "\n\n"

		}
	}
	resourcesLock.Unlock()

	_, error := writer.Write([]byte(response))
	heckleDaemon.DaemonLog.LogError("Unable to write node status response in heckle.", error)
}
开发者ID:raffenet,项目名称:heckle,代码行数:25,代码来源:heckle.go

示例9: copyRequest

func (f *Forwarder) copyRequest(req *http.Request, u *url.URL) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	outReq.URL = utils.CopyURL(req.URL)
	outReq.URL.Scheme = u.Scheme
	outReq.URL.Host = u.Host
	// workaround for https://github.com/golang/go/issues/10433
	outReq.URL.Opaque = mergeStartingSlashes(req.RequestURI)
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""
	// Do not pass client Host header unless optsetter PassHostHeader is set.
	if f.passHost != true {
		outReq.Host = u.Host
	}
	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1

	// Overwrite close flag so we can keep persistent connection for the backend servers
	outReq.Close = false

	outReq.Header = make(http.Header)
	utils.CopyHeaders(outReq.Header, req.Header)

	if f.rewriter != nil {
		f.rewriter.Rewrite(outReq)
	}
	return outReq
}
开发者ID:narma,项目名称:oxy,代码行数:30,代码来源:fwd.go

示例10: rewriteRequest

// This function alters the original request - adds/removes headers, removes hop headers,
// changes the request path.
func rewriteRequest(req *http.Request, cmd *command.Forward, upstream *command.Upstream) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	outReq.URL.Scheme = upstream.Scheme
	outReq.URL.Host = fmt.Sprintf("%s:%d", upstream.Host, upstream.Port)
	if len(cmd.RewritePath) != 0 {
		outReq.URL.Path = cmd.RewritePath
	}

	outReq.URL.RawQuery = req.URL.RawQuery

	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1
	outReq.Close = false

	glog.Infof("Proxying request to: %v", outReq)

	outReq.Header = make(http.Header)
	netutils.CopyHeaders(outReq.Header, req.Header)

	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
		// TODO(pquerna): configure this?  Not all backends properly parse the header..
		if TRUST_FORWARD_HEADER {
			if prior, ok := outReq.Header["X-Forwarded-For"]; ok {
				clientIP = strings.Join(prior, ", ") + ", " + clientIP
			}
		}
		outReq.Header.Set("X-Forwarded-For", clientIP)
	}

	if req.TLS != nil {
		outReq.Header.Set("X-Forwarded-Proto", "https")
	} else {
		outReq.Header.Set("X-Forwarded-Proto", "http")
	}

	if req.Host != "" {
		outReq.Header.Set("X-Forwarded-Host", req.Host)
	}

	outReq.Header.Set("X-Forwarded-Server", vulcanHostname)

	if len(cmd.RemoveHeaders) != 0 {
		netutils.RemoveHeaders(cmd.RemoveHeaders, outReq.Header)
	}

	// Add generic instructions headers to the request
	if len(cmd.AddHeaders) != 0 {
		glog.Info("Proxying instructions headers:", cmd.AddHeaders)
		netutils.CopyHeaders(outReq.Header, cmd.AddHeaders)
	}

	// Remove hop-by-hop headers to the backend.  Especially
	// important is "Connection" because we want a persistent
	// connection, regardless of what the client sent to us.
	netutils.RemoveHeaders(hopHeaders, outReq.Header)
	return outReq
}
开发者ID:johntdyer,项目名称:golang-devops-stuff,代码行数:62,代码来源:proxy.go

示例11: freeAllocation

func freeAllocation(writer http.ResponseWriter, req *http.Request) {
	//This function allows a user, if it owns the allocation, to free an allocation
	//number and all associated nodes.  It resets the resource map and current
	//requests map.
	heckleDaemon.DaemonLog.DebugHttp(req)
	req.ProtoMinor = 0

	err := heckleDaemon.AuthN.HTTPAuthenticate(req, false)
	if err != nil {
		heckleDaemon.DaemonLog.LogError("Permission Denied", err)
		writer.WriteHeader(http.StatusUnauthorized)
	}
	heckleDaemon.UpdateActivity()
	username, _, admin := heckleDaemon.AuthN.GetHTTPAuthenticateInfo(req)

	jsonType := heckleDaemon.ProcessJson(req, new(uint64))
	allocationNumber := jsonType.(*uint64)

	if *allocationNumber <= 0 {
		heckleDaemon.DaemonLog.LogError(fmt.Sprintf("Allocation #%d does not exsist", *allocationNumber), errors.New("0 used"))
		writer.WriteHeader(http.StatusBadRequest)
		return
	}
	powerDown := []string{}

	currentRequestsLock.Lock()
	resourcesLock.Lock()
	found := false
	for key, value := range resources {
		if *allocationNumber == value.AllocationNumber {
			if username == value.Owner || admin {
				value.Reset()
				powerDown = append(powerDown, key)
				delete(currentRequests, key)
				found = true
			} else {
				heckleDaemon.DaemonLog.LogError("Cannot free allocations that do not belong to you.", errors.New("Access Denied"))
				currentRequestsLock.Unlock()
				resourcesLock.Unlock()
				return
			}
		}
	}
	currentRequestsLock.Unlock()
	resourcesLock.Unlock()

	if !found {
		heckleDaemon.DaemonLog.LogError(fmt.Sprintf("Allocation #%d does not exist.", allocationNumber), errors.New("Wrong Number"))
		writer.WriteHeader(http.StatusBadRequest)
		return
	}

	pollingCancelChan <- powerDown //Needed because polling will continue to poll if allocation is freed during allocation.

	_, err = ps.PostServer("/command/off", powerDown)
	heckleDaemon.DaemonLog.LogError("Failed to post for reboot of nodes in free allocation number.", err)
	heckleDaemon.DaemonLog.Log(fmt.Sprintf("Allocation #%d nodes %s have been freed.", *allocationNumber, powerDown))
	updateDatabase(false)
}
开发者ID:raffenet,项目名称:heckle,代码行数:59,代码来源:heckle.go

示例12: ServeHTTP

func (p *ReverseProxy) ServeHTTP(req *http.Request) (*http.Response, error) {

	transport := p.Transport
	if transport == nil {
		transport = http.DefaultTransport
	}

	outreq := new(http.Request)
	*outreq = *req // includes shallow copies of maps, but okay

	p.Director(outreq)
	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

	// Remove hop-by-hop headers to the backend.  Especially
	// important is "Connection" because we want a persistent
	// connection, regardless of what the client sent to us.  This
	// is modifying the same underlying map from req (shallow
	// copied above) so we only copy it if necessary.
	copiedHeaders := false
	for _, h := range hopHeaders {
		if outreq.Header.Get(h) != "" {
			if !copiedHeaders {
				outreq.Header = make(http.Header)
				copyHeader(outreq.Header, req.Header)
				copiedHeaders = true
			}
			outreq.Header.Del(h)
		}
	}

	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
		// If we aren't the first proxy retain prior
		// X-Forwarded-For information as a comma+space
		// separated list and fold multiple headers into one.
		if prior, ok := outreq.Header["X-Forwarded-For"]; ok {
			clientIP = strings.Join(prior, ", ") + ", " + clientIP
		}
		outreq.Header.Set("X-Forwarded-For", clientIP)
	}

	res, err := transport.RoundTrip(outreq)
	if err != nil {
		return res, err
	}

	for _, p := range *p.Plugins {
		p.Outbound(res)
	}

	for _, h := range hopHeaders {
		res.Header.Del(h)
	}

	return res, nil

}
开发者ID:SHMEDIALIMITED,项目名称:server,代码行数:59,代码来源:reverse_proxy.go

示例13: ServeHTTP

func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request, respUpdateFn respUpdateFn) error {
	transport := p.Transport
	if transport == nil {
		transport = http.DefaultTransport
	}

	p.Director(outreq)
	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

	res, err := transport.RoundTrip(outreq)
	if err != nil {
		return err
	} else if respUpdateFn != nil {
		respUpdateFn(res)
	}

	if res.StatusCode == http.StatusSwitchingProtocols && strings.ToLower(res.Header.Get("Upgrade")) == "websocket" {
		res.Body.Close()
		hj, ok := rw.(http.Hijacker)
		if !ok {
			return nil
		}

		conn, _, err := hj.Hijack()
		if err != nil {
			return err
		}
		defer conn.Close()

		backendConn, err := net.Dial("tcp", outreq.URL.Host)
		if err != nil {
			return err
		}
		defer backendConn.Close()

		outreq.Write(backendConn)

		go func() {
			io.Copy(backendConn, conn) // write tcp stream to backend.
		}()
		io.Copy(conn, backendConn) // read tcp stream from backend.
	} else {
		defer res.Body.Close()
		for _, h := range hopHeaders {
			res.Header.Del(h)
		}
		copyHeader(rw.Header(), res.Header)
		rw.WriteHeader(res.StatusCode)
		p.copyResponse(rw, res.Body)
	}

	return nil
}
开发者ID:RobbieMcKinstry,项目名称:caddy,代码行数:56,代码来源:reverseproxy.go

示例14: prepareRequest

func prepareRequest(req *http.Request) *http.Request {
	outreq := new(http.Request)
	*outreq = *req // includes shallow copies of maps, but okay

	// Pass the Request-URI verbatim without any modifications.
	//
	// NOTE: An exception must be made if the Request-URI is a path
	// beginning with "//" (e.g. "//foo/bar") because then
	// req.URL.RequestURI() would interpret req.URL.Opaque as being a URI
	// with the scheme stripped and so generate a URI like scheme:opaque
	// (e.g. "http://foo/bar") which would be incorrect, see:
	// https://github.com/golang/go/blob/f75aafd/src/net/url/url.go#L913-L931
	//
	// It is ok to make this exception because the fallback to
	// req.URL.EscapedPath will generate the correct Request-URI.
	if !strings.HasPrefix(req.RequestURI, "//") {
		outreq.URL.Opaque = strings.Split(strings.TrimPrefix(req.RequestURI, req.URL.Scheme+":"), "?")[0]
	}

	outreq.URL.Scheme = "http"
	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

	// Remove hop-by-hop headers to the backend.
	outreq.Header = make(http.Header)
	copyHeader(outreq.Header, req.Header)
	for _, h := range hopHeaders {
		outreq.Header.Del(h)
	}

	// remove the Upgrade header and headers referenced in the Connection
	// header if HTTP < 1.1 or if Connection header didn't contain "upgrade":
	// https://tools.ietf.org/html/rfc7230#section-6.7
	if !req.ProtoAtLeast(1, 1) || !isConnectionUpgrade(req.Header) {
		outreq.Header.Del("Upgrade")

		// Especially important is "Connection" because we want a persistent
		// connection, regardless of what the client sent to us.
		outreq.Header.Del("Connection")

		// A proxy or gateway MUST parse a received Connection header field before a
		// message is forwarded and, for each connection-option in this field, remove
		// any header field(s) from the message with the same name as the
		// connection-option, and then remove the Connection header field itself (or
		// replace it with the intermediary's own connection options for the
		// forwarded message): https://tools.ietf.org/html/rfc7230#section-6.1
		tokens := strings.Split(req.Header.Get("Connection"), ",")
		for _, hdr := range tokens {
			outreq.Header.Del(hdr)
		}
	}

	return outreq
}
开发者ID:imjorge,项目名称:flynn,代码行数:56,代码来源:reverseproxy.go

示例15: wrapControl

func (cms ControllerMuxServer) wrapControl(w http.ResponseWriter, req *http.Request) {
	powerDaemon.DaemonLog.DebugHttp(req)
	req.ProtoMinor = 0

	err := powerDaemon.AuthN.HTTPAuthenticate(req, true)
	if err != nil {
		powerDaemon.DaemonLog.LogError("Access not permitted.", err)
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	cmd := strings.Split(req.RequestURI, "/")[2]

	switch cmd {
	case "on", "off", "reboot":
		break
	default:
		powerDaemon.DaemonLog.LogError(fmt.Sprintf("%s command not supported", cmd),
			errors.New("dummy"))
		w.WriteHeader(http.StatusNotFound)
		return
		break
	}

	body, err := ioutil.ReadAll(req.Body)
	err = req.Body.Close()
	if err != nil {
		fmt.Println(err.Error())
	}

	var nodes []string

	err = json.Unmarshal(body, &nodes)
	if err != nil {
		fmt.Println(err.Error())
	}

	powerDaemon.DaemonLog.Log(fmt.Sprintf("%s: %s", cmd, nodes))

	switch cmd {
	case "on":
		err = cms.cm.On(nodes)
	case "off":
		err = cms.cm.Off(nodes)
	case "reboot":
		err = cms.cm.Reboot(nodes)
	}

	if err != nil {
		powerDaemon.DaemonLog.LogError(err.Error(), err)
		w.WriteHeader(http.StatusInternalServerError)
	}

	return
}
开发者ID:narayandesai,项目名称:heckle,代码行数:55,代码来源:server.go


注:本文中的net/http.Request.ProtoMinor方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。