func PostConnection(w rest.ResponseWriter, r *rest.Request) { form := ConnectionSetting{} err := r.DecodeJsonPayload(&form) if err != nil { apiutils.WriteRestError(w, apierrors.NewBadRequest(err.Error())) return } err = clientconfig.Update(func(conf *clientconfig.Config) error { all := conf.Settings.Connections var connection shared.Connection // decoded connection var invalids fielderrors.ValidationErrorList // Verify that the encoded field is set { if form.Encoded == "" { invalids = append(invalids, fielderrors.NewFieldRequired("encoded")) } } // verify that the connection is decodeable { var err error connection, err = shared.DecodeConnection(form.Encoded) if err != nil { invalids = append(invalids, fielderrors.NewFieldInvalid("encoded", form.Encoded, "invalid formatting")) } } // validate that the id exists, if supplied foundIdx := 0 { if form.ID != "" { found := false for k, v := range all { if v.ID == form.ID { found = true foundIdx = k } } if !found { invalids = append(invalids, fielderrors.NewFieldNotFound("id", form.ID)) } } } // validate that the connection doesnt alreay exist { encoded, err := connection.Encode() if err != nil { apiutils.WriteRestError(w, err) return nil } found := false for _, v := range all { enc2, err := v.Encode() if err != nil { lg.Errorln(err) continue } if enc2 == encoded { found = true } } if found { invalids = append(invalids, fielderrors.NewFieldDuplicate("encoded", form.Encoded)) } } // end of field validations if len(invalids) > 0 { apiutils.WriteRestError(w, apierrors.NewInvalid("post-connection", "", invalids)) return nil } // add connection to settings and save if form.ID == "" { connection.EnsureID() conf.Settings.Connections = append(conf.Settings.Connections, connection) } else { conf.Settings.Connections[foundIdx] = connection } service.UpdateConnections(conf.Settings.Connections) return nil }) if err != nil { lg.Errorln(err) } clientconfig.Write() w.WriteJson(true) }
// CreateSuggestion . func CreateSuggestion(w rest.ResponseWriter, r *rest.Request) { form := shared.BrowserSuggestionTokenRequest{} err := r.DecodeJsonPayload(&form) if err != nil { // apiError(w, err.Error(), http.StatusInternalServerError) apiutils.WriteRestError(w, err) return } var invalids fielderrors.ValidationErrorList // parse and validate url. URL := strings.TrimSpace(form.URL) if URL == "" { invalids = append(invalids, fielderrors.NewFieldRequired("URL")) // apiError(w, "no or empty URL", http.StatusBadRequest) } u, err := url.Parse(URL) if err != nil { invalids = append(invalids, fielderrors.NewFieldInvalid("URL", URL, err.Error())) // apiError(w, fmt.Sprintf("%s is not a valid URL", URL), http.StatusBadRequest) } host := u.Host if strings.Contains(host, ":") { host, _, err = net.SplitHostPort(u.Host) if err != nil { invalids = append(invalids, fielderrors.NewFieldInvalid("URL", URL, err.Error())) } } if !shared.AcceptedURL(u) { invalids = append(invalids, fielderrors.NewFieldValueNotSupported("URL", URL, nil)) } if len(invalids) > 0 { apiutils.WriteRestError(w, apierrors.NewInvalid("create-suggestion", "URL", invalids)) return } s := client.NewSuggestion(u.String()) defer s.DoneAddingSamples() measurers, err := measure.DefaultMeasurements(form.URL) if err != nil { apiutils.WriteRestError(w, apierrors.NewInternalError(err)) return } for _, v := range measurers { m, err := v.Measure() if err != nil { lg.Errorf("could not measure: %s", err.Error()) } else { switch m.Type() { case sampletypes.DNSQuery, sampletypes.HTTPHeader: err = s.AddMeasurement(m) if err != nil { lg.Errorln(err.Error()) return } default: lg.Warningf("unsupported sample type: %s", m.Type().String()) } } } }
func TestNewInvalid(t *testing.T) { testCases := []struct { Err *fielderrors.ValidationError Details *api.StatusDetails }{ { fielderrors.NewFieldDuplicate("field[0].name", "bar"), &api.StatusDetails{ Kind: "kind", Name: "name", Causes: []api.StatusCause{{ Type: api.CauseTypeFieldValueDuplicate, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldInvalid("field[0].name", "bar", "detail"), &api.StatusDetails{ Kind: "kind", Name: "name", Causes: []api.StatusCause{{ Type: api.CauseTypeFieldValueInvalid, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldNotFound("field[0].name", "bar"), &api.StatusDetails{ Kind: "kind", Name: "name", Causes: []api.StatusCause{{ Type: api.CauseTypeFieldValueNotFound, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldValueNotSupported("field[0].name", "bar", nil), &api.StatusDetails{ Kind: "kind", Name: "name", Causes: []api.StatusCause{{ Type: api.CauseTypeFieldValueNotSupported, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldRequired("field[0].name"), &api.StatusDetails{ Kind: "kind", Name: "name", Causes: []api.StatusCause{{ Type: api.CauseTypeFieldValueRequired, Field: "field[0].name", }}, }, }, } for i, testCase := range testCases { vErr, expected := testCase.Err, testCase.Details expected.Causes[0].Message = vErr.Error() err := NewInvalid("kind", "name", fielderrors.ValidationErrorList{vErr}) status := err.(*StatusError).ErrStatus if status.Code != 422 || status.Reason != api.StatusReasonInvalid { t.Errorf("%d: unexpected status: %#v", i, status) } if !reflect.DeepEqual(expected, status.Details) { t.Errorf("%d: expected %#v, got %#v", i, expected, status.Details) } } }