// 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) } } }