• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang httpd.HttpError函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中github.com/influxdata/kapacitor/services/httpd.HttpError函数的典型用法代码示例。如果您正苦于以下问题:Golang HttpError函数的具体用法?Golang HttpError怎么用?Golang HttpError使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



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

示例1: handleTest

func (s *Service) handleTest(w http.ResponseWriter, r *http.Request) {
	name := s.nameFromPath(r.URL.Path)
	if name == "" {
		httpd.HttpError(w, "must provide service name", true, http.StatusBadRequest)
		return
	}

	test, ok := s.testers[name]
	if !ok {
		httpd.HttpError(w, fmt.Sprintf("service %q not found", name), true, http.StatusNotFound)
		return
	}

	options := test.TestOptions()
	if options != nil {
		if err := json.NewDecoder(r.Body).Decode(options); err != nil {
			httpd.HttpError(w, fmt.Sprint("failed to decode JSON body:", err), true, http.StatusBadRequest)
			return
		}
	}

	result := ServiceTestResult{}
	err := test.Test(options)
	if err != nil {
		result.Message = err.Error()
	} else {
		result.Success = true
	}
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:31,代码来源:service.go


示例2: handleTemplate

func (ts *Service) handleTemplate(w http.ResponseWriter, r *http.Request) {
	id, err := ts.templateIDFromPath(r.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}

	raw, err := ts.templates.Get(id)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}

	scriptFormat := r.URL.Query().Get("script-format")
	switch scriptFormat {
	case "":
		scriptFormat = "formatted"
	case "formatted", "raw":
	default:
		httpd.HttpError(w, fmt.Sprintf("invalid script-format parameter %q", scriptFormat), true, http.StatusBadRequest)
		return
	}

	t, err := ts.convertTemplate(raw, scriptFormat)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
	w.Write(httpd.MarshalJSON(t, true))
}
开发者ID:wutaizeng,项目名称:kapacitor,代码行数:31,代码来源:service.go


示例3: handleDeleteRecording

func (s *Service) handleDeleteRecording(w http.ResponseWriter, r *http.Request) {
	rid, err := s.recordingIDFromPath(r.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	recording, err := s.recordings.Get(rid)
	if err == ErrNoRecordingExists {
		w.WriteHeader(http.StatusNoContent)
		return
	}
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}
	err = s.recordings.Delete(rid)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}
	ds, err := parseDataSourceURL(recording.DataURL)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}

	err = ds.Remove()
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:34,代码来源:service.go


示例4: handleRecordBatch

func (s *Service) handleRecordBatch(w http.ResponseWriter, req *http.Request) {
	var opt kclient.RecordBatchOptions
	dec := json.NewDecoder(req.Body)
	err := dec.Decode(&opt)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	if opt.ID == "" {
		opt.ID = uuid.NewV4().String()
	}
	if !validID.MatchString(opt.ID) {
		httpd.HttpError(w, fmt.Sprintf("recording ID must contain only letters, numbers, '-', '.' and '_'. %q", opt.ID), true, http.StatusBadRequest)
		return
	}

	if opt.Start.IsZero() {
		httpd.HttpError(w, "must provide start time", true, http.StatusBadRequest)
		return
	}
	if opt.Stop.IsZero() {
		opt.Stop = time.Now()
	}

	t, err := s.TaskStore.Load(opt.Task)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}
	dataUrl := s.dataURLFromID(opt.ID, batchEXT)

	recording := Recording{
		ID:      opt.ID,
		DataURL: dataUrl.String(),
		Type:    BatchRecording,
		Date:    time.Now(),
		Status:  Running,
	}
	err = s.recordings.Create(recording)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}

	go func(recording Recording) {
		ds, _ := parseDataSourceURL(dataUrl.String())
		err := s.doRecordBatch(ds, t, opt.Start, opt.Stop)
		s.updateRecordingResult(recording, ds, err)
	}(recording)

	w.WriteHeader(http.StatusCreated)
	w.Write(httpd.MarshalJSON(convertRecording(recording), true))
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:53,代码来源:service.go


示例5: handleRecordQuery

func (s *Service) handleRecordQuery(w http.ResponseWriter, req *http.Request) {
	var opt kclient.RecordQueryOptions
	dec := json.NewDecoder(req.Body)
	err := dec.Decode(&opt)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	if opt.ID == "" {
		opt.ID = uuid.NewV4().String()
	}
	if !validID.MatchString(opt.ID) {
		httpd.HttpError(w, fmt.Sprintf("recording ID must contain only letters, numbers, '-', '.' and '_'. %q", opt.ID), true, http.StatusBadRequest)
		return
	}
	if opt.Query == "" {
		httpd.HttpError(w, "must provide query", true, http.StatusBadRequest)
		return
	}
	var dataUrl url.URL
	var typ RecordingType
	switch opt.Type {
	case kclient.StreamTask:
		dataUrl = s.dataURLFromID(opt.ID, streamEXT)
		typ = StreamRecording
	case kclient.BatchTask:
		dataUrl = s.dataURLFromID(opt.ID, batchEXT)
		typ = BatchRecording
	}

	recording := Recording{
		ID:      opt.ID,
		DataURL: dataUrl.String(),
		Type:    typ,
		Date:    time.Now(),
		Status:  Running,
	}
	err = s.recordings.Create(recording)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}

	go func(recording Recording) {
		ds, _ := parseDataSourceURL(dataUrl.String())
		err := s.doRecordQuery(ds, opt.Query, typ, opt.Cluster)
		s.updateRecordingResult(recording, ds, err)
	}(recording)

	w.WriteHeader(http.StatusCreated)
	w.Write(httpd.MarshalJSON(convertRecording(recording), true))
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:52,代码来源:service.go


示例6: handleDeleteTemplate

func (ts *Service) handleDeleteTemplate(w http.ResponseWriter, r *http.Request) {
	id, err := ts.templateIDFromPath(r.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	err = ts.templates.Delete(id)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}
开发者ID:wutaizeng,项目名称:kapacitor,代码行数:13,代码来源:service.go


示例7: handleTask

func (ts *Service) handleTask(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	if name == "" {
		httpd.HttpError(w, "must pass task name", true, http.StatusBadRequest)
		return
	}
	labels := false
	labelsStr := r.URL.Query().Get("labels")
	if labelsStr != "" {
		var err error
		labels, err = strconv.ParseBool(labelsStr)
		if err != nil {
			httpd.HttpError(w, "invalid labels value:", true, http.StatusBadRequest)
			return
		}

	}

	raw, err := ts.LoadRaw(name)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}

	executing := ts.TaskMaster.IsExecuting(name)
	errMsg := raw.Error
	dot := ""
	task, err := ts.Load(name)
	if err == nil {
		if executing {
			dot = ts.TaskMaster.ExecutingDot(name, labels)
		} else {
			dot = string(task.Dot())
		}
	} else {
		errMsg = err.Error()
	}

	info := TaskInfo{
		Name:       name,
		Type:       raw.Type,
		DBRPs:      raw.DBRPs,
		TICKscript: raw.TICKscript,
		Dot:        dot,
		Enabled:    ts.IsEnabled(name),
		Executing:  executing,
		Error:      errMsg,
	}

	w.Write(httpd.MarshalJSON(info, true))
}
开发者ID:yuanwr,项目名称:kapacitor,代码行数:51,代码来源:service.go


示例8: handleGetConfig

func (s *Service) handleGetConfig(w http.ResponseWriter, r *http.Request) {
	if !s.enabled {
		httpd.HttpError(w, "config override service is not enabled", true, http.StatusForbidden)
		return
	}
	section, element, hasSection, hasElement := sectionAndElementFromPath(r.URL.Path, configBasePath)
	config, err := s.getConfig(section)
	if err != nil {
		httpd.HttpError(w, fmt.Sprint("failed to resolve current config:", err), true, http.StatusInternalServerError)
		return
	}
	if hasSection && section == "" {
		httpd.HttpError(w, "section not specified, do you have an extra trailing '/'?", true, http.StatusBadRequest)
		return
	}
	if !hasSection {
		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(config)
	} else if section != "" {
		sec, ok := config.Sections[section]
		if !ok {
			httpd.HttpError(w, fmt.Sprint("unknown section: ", section), true, http.StatusNotFound)
			return
		}
		if hasElement {
			var elementEntry client.ConfigElement
			// Find specified element
			elementKey := s.elementKeys[section]
			found := false
			for _, e := range sec.Elements {
				if (element == "" && elementKey == "") || e.Options[elementKey] == element {
					elementEntry = e
					found = true
					break
				}
			}
			if found {
				w.WriteHeader(http.StatusOK)
				json.NewEncoder(w).Encode(elementEntry)
			} else {
				httpd.HttpError(w, fmt.Sprintf("unknown section/element: %s/%s", section, element), true, http.StatusNotFound)
				return
			}
		} else {
			w.WriteHeader(http.StatusOK)
			json.NewEncoder(w).Encode(sec)
		}
	}
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:49,代码来源:service.go


示例9: handleListTests

func (s *Service) handleListTests(w http.ResponseWriter, r *http.Request) {
	tests := ServiceTests{
		Link: serviceTestsLink,
	}
	pattern := r.URL.Query().Get("pattern")
	if pattern == "" {
		pattern = "*"
	}
	for name, test := range s.testers {
		if ok, err := filepath.Match(pattern, name); err != nil {
			httpd.HttpError(w, fmt.Sprintf("bad pattern: %v", err), true, http.StatusBadRequest)
			return
		} else if ok {
			options := test.TestOptions()
			tests.Services = append(tests.Services, ServiceTest{
				Link:    s.serviceTestLink(name),
				Name:    name,
				Options: options,
			})
		}
	}
	sort.Sort(tests.Services)

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(tests)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:26,代码来源:service.go


示例10: handleSubscriptions

// Refresh the subscriptions linking for all clusters.
func (s *Service) handleSubscriptions(w http.ResponseWriter, r *http.Request) {
	err := s.LinkSubscriptions()
	if err != nil {
		httpd.HttpError(w, fmt.Sprintf("failed to link subscriptions: %s", err.Error()), true, http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:9,代码来源:service.go


示例11: handleDisable

func (ts *Service) handleDisable(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	err := ts.Disable(name)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}
}
开发者ID:sstarcher,项目名称:kapacitor,代码行数:8,代码来源:service.go


示例12: handleRecordStream

func (s *Service) handleRecordStream(w http.ResponseWriter, r *http.Request) {
	var opt kclient.RecordStreamOptions
	dec := json.NewDecoder(r.Body)
	err := dec.Decode(&opt)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	if opt.ID == "" {
		opt.ID = uuid.NewV4().String()
	}
	if !validID.MatchString(opt.ID) {
		httpd.HttpError(w, fmt.Sprintf("recording ID must contain only letters, numbers, '-', '.' and '_'. %q", opt.ID), true, http.StatusBadRequest)
		return
	}
	t, err := s.TaskStore.Load(opt.Task)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}
	dataUrl := s.dataURLFromID(opt.ID, streamEXT)

	recording := Recording{
		ID:      opt.ID,
		DataURL: dataUrl.String(),
		Type:    StreamRecording,
		Date:    time.Now(),
		Status:  Running,
	}
	err = s.recordings.Create(recording)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusInternalServerError)
		return
	}

	// Spawn routine to perform actual recording.
	go func(recording Recording) {
		ds, _ := parseDataSourceURL(dataUrl.String())
		err := s.doRecordStream(opt.ID, ds, opt.Stop, t.DBRPs, t.Measurements())
		s.updateRecordingResult(recording, ds, err)
	}(recording)

	w.WriteHeader(http.StatusCreated)
	w.Write(httpd.MarshalJSON(convertRecording(recording), true))
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:45,代码来源:service.go


示例13: runOut

func (h *HTTPOutNode) runOut([]byte) error {

	hndl := func(w http.ResponseWriter, req *http.Request) {
		h.mu.RLock()
		defer h.mu.RUnlock()

		if b, err := json.Marshal(h.result); err != nil {
			httpd.HttpError(
				w,
				err.Error(),
				true,
				http.StatusInternalServerError,
			)
		} else {
			w.Write(b)
		}
	}

	p := path.Join("/task", h.et.Task.Name, h.c.Endpoint)

	r := []httpd.Route{{
		Name:        h.Name(),
		Method:      "GET",
		Pattern:     p,
		HandlerFunc: hndl,
	}}

	h.endpoint = h.et.tm.HTTPDService.URL() + p
	func() {
		h.mu.Lock()
		defer h.mu.Unlock()
		h.routes = r
	}()

	err := h.et.tm.HTTPDService.AddRoutes(r)
	if err != nil {
		return err
	}

	switch h.Wants() {
	case pipeline.StreamEdge:
		for p, ok := h.ins[0].NextPoint(); ok; p, ok = h.ins[0].NextPoint() {
			h.timer.Start()
			row := models.PointToRow(p)
			h.updateResultWithRow(p.Group, row)
			h.timer.Stop()
		}
	case pipeline.BatchEdge:
		for b, ok := h.ins[0].NextBatch(); ok; b, ok = h.ins[0].NextBatch() {
			h.timer.Start()
			row := models.BatchToRow(b)
			h.updateResultWithRow(b.Group, row)
			h.timer.Stop()
		}
	}
	return nil
}
开发者ID:yuanwr,项目名称:kapacitor,代码行数:57,代码来源:http_out.go


示例14: handleReplay

func (s *Service) handleReplay(w http.ResponseWriter, req *http.Request) {
	id, err := s.replayIDFromPath(req.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	replay, err := s.replays.Get(id)
	if err != nil {
		httpd.HttpError(w, "could not find replay: "+err.Error(), true, http.StatusNotFound)
		return
	}
	if replay.Status == Running {
		w.WriteHeader(http.StatusAccepted)
	} else {
		w.WriteHeader(http.StatusOK)
	}
	w.Write(httpd.MarshalJSON(convertReplay(replay), true))
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:18,代码来源:service.go


示例15: handleDeleteReplay

func (s *Service) handleDeleteReplay(w http.ResponseWriter, req *http.Request) {
	id, err := s.replayIDFromPath(req.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}
	//TODO: Cancel running replays
	s.replays.Delete(id)
	w.WriteHeader(http.StatusNoContent)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:10,代码来源:service.go


示例16: handleRecording

func (s *Service) handleRecording(w http.ResponseWriter, r *http.Request) {
	rid, err := s.recordingIDFromPath(r.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}

	recording, err := s.recordings.Get(rid)
	if err != nil {
		httpd.HttpError(w, "error finding recording: "+err.Error(), true, http.StatusInternalServerError)
		return
	}
	if recording.Status == Running {
		w.WriteHeader(http.StatusAccepted)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	w.Write(httpd.MarshalJSON(convertRecording(recording), true))
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:20,代码来源:service.go


示例17: handleTask

func (ts *Service) handleTask(w http.ResponseWriter, r *http.Request) {
	id, err := ts.taskIDFromPath(r.URL.Path)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusBadRequest)
		return
	}

	raw, err := ts.tasks.Get(id)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}

	scriptFormat := r.URL.Query().Get("script-format")
	switch scriptFormat {
	case "", "formatted":
		scriptFormat = "formatted"
	case "raw":
	default:
		httpd.HttpError(w, fmt.Sprintf("invalid script-format parameter %q", scriptFormat), true, http.StatusBadRequest)
		return
	}

	dotView := r.URL.Query().Get("dot-view")
	switch dotView {
	case "":
		dotView = "attributes"
	case "attributes":
	case "labels":
	default:
		httpd.HttpError(w, fmt.Sprintf("invalid dot-view parameter %q", dotView), true, http.StatusBadRequest)
		return
	}
	tmID := r.URL.Query().Get("replay-id")
	if tmID == "" {
		tmID = kapacitor.MainTaskMaster
	}
	tm := ts.TaskMasterLookup.Get(tmID)
	if tm == nil {
		httpd.HttpError(w, fmt.Sprintf("no running replay with ID: %s", tmID), true, http.StatusBadRequest)
		return
	}
	if tmID != kapacitor.MainTaskMaster && !tm.IsExecuting(raw.ID) {
		httpd.HttpError(w, fmt.Sprintf("replay %s is not for task: %s", tmID, raw.ID), true, http.StatusBadRequest)
		return
	}

	t, err := ts.convertTask(raw, scriptFormat, dotView, tm)
	if err != nil {
		httpd.HttpError(w, fmt.Sprintf("invalid task stored in db: %s", err.Error()), true, http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
	w.Write(httpd.MarshalJSON(t, true))
}
开发者ID:wutaizeng,项目名称:kapacitor,代码行数:55,代码来源:service.go


示例18: handleTestOptions

func (s *Service) handleTestOptions(w http.ResponseWriter, r *http.Request) {
	name := s.nameFromPath(r.URL.Path)
	if name == "" {
		httpd.HttpError(w, "must provide service name", true, http.StatusBadRequest)
		return
	}

	test, ok := s.testers[name]
	if !ok {
		httpd.HttpError(w, fmt.Sprintf("service %q not found", name), true, http.StatusNotFound)
		return
	}

	options := test.TestOptions()
	serviceTest := ServiceTest{
		Link:    s.serviceTestLink(name),
		Name:    name,
		Options: options,
	}
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(serviceTest)
}
开发者ID:influxdata,项目名称:kapacitor,代码行数:22,代码来源:service.go


示例19: handleGetRecording

func (r *Service) handleGetRecording(w http.ResponseWriter, req *http.Request) {
	rid := req.URL.Query().Get("id")

	// First check if its still running
	var errC <-chan error
	var running bool
	func() {
		r.recordingsMu.RLock()
		defer r.recordingsMu.RUnlock()
		errC, running = r.runningRecordings[rid]
	}()

	if running {
		// It is still running wait for it to finish
		err := <-errC
		if err != nil {
			info := RecordingInfo{
				ID:    rid,
				Error: err.Error(),
			}
			w.Write(httpd.MarshalJSON(info, true))
			return
		}
	}

	// It already finished, return its info
	info, err := r.GetRecordings([]string{rid})
	if err != nil {
		httpd.HttpError(w, "error finding recording: "+err.Error(), true, http.StatusInternalServerError)
		return
	}
	if len(info) != 1 {
		httpd.HttpError(w, "recording not found", true, http.StatusNotFound)
		return
	}

	w.Write(httpd.MarshalJSON(info[0], true))
}
开发者ID:karlitxo,项目名称:kapacitor,代码行数:38,代码来源:service.go


示例20: handleTasks

func (ts *Service) handleTasks(w http.ResponseWriter, r *http.Request) {
	tasksStr := r.URL.Query().Get("tasks")
	var tasks []string
	if tasksStr != "" {
		tasks = strings.Split(tasksStr, ",")
	}

	infos, err := ts.GetTaskInfo(tasks)
	if err != nil {
		httpd.HttpError(w, err.Error(), true, http.StatusNotFound)
		return
	}

	type response struct {
		Tasks []taskInfo `json:"Tasks"`
	}

	w.Write(httpd.MarshalJSON(response{infos}, true))
}
开发者ID:sstarcher,项目名称:kapacitor,代码行数:19,代码来源:service.go



注:本文中的github.com/influxdata/kapacitor/services/httpd.HttpError函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang httpd.MarshalJSON函数代码示例发布时间:2022-05-28
下一篇:
Golang pipeline.AlertNode类代码示例发布时间:2022-05-28
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap