OLD | NEW |
1 package main | 1 package main |
2 | 2 |
3 /* | 3 /* |
4 Runs the frontend portion of the fuzzer. This primarily is the webserver (see D
ESIGN.md) | 4 Runs the frontend portion of the fuzzer. This primarily is the webserver (see D
ESIGN.md) |
5 */ | 5 */ |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "encoding/base64" | 9 "encoding/base64" |
10 "encoding/json" | 10 "encoding/json" |
(...skipping 29 matching lines...) Expand all Loading... |
40 ) | 40 ) |
41 | 41 |
42 const ( | 42 const ( |
43 // OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow. | 43 // OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow. |
44 OAUTH2_CALLBACK_PATH = "/oauth2callback/" | 44 OAUTH2_CALLBACK_PATH = "/oauth2callback/" |
45 ) | 45 ) |
46 | 46 |
47 var ( | 47 var ( |
48 // indexTemplate is the main index.html page we serve. | 48 // indexTemplate is the main index.html page we serve. |
49 indexTemplate *template.Template = nil | 49 indexTemplate *template.Template = nil |
50 » // detailsTemplate is used for /category/foo, which displays the number
of | 50 » // detailsTemplate is used for /category, which displays the count of fu
zzes in various files |
51 » // fuzzes by file/function/line | 51 » // as well as the stacktraces. |
52 » overviewTemplate *template.Template = nil | |
53 » // detailsTemplate is used for /details, which displays the information
from | |
54 » // overview as well as the stacktraces and fuzzes. | |
55 detailsTemplate *template.Template = nil | 52 detailsTemplate *template.Template = nil |
56 | 53 |
57 storageClient *storage.Client = nil | 54 storageClient *storage.Client = nil |
58 | 55 |
59 versionWatcher *fcommon.VersionWatcher = nil | 56 versionWatcher *fcommon.VersionWatcher = nil |
60 | 57 |
61 fuzzSyncer *syncer.FuzzSyncer = nil | 58 fuzzSyncer *syncer.FuzzSyncer = nil |
62 ) | 59 ) |
63 | 60 |
64 var ( | 61 var ( |
(...skipping 26 matching lines...) Expand all Loading... |
91 | 88 |
92 func Init() { | 89 func Init() { |
93 reloadTemplates() | 90 reloadTemplates() |
94 } | 91 } |
95 | 92 |
96 func reloadTemplates() { | 93 func reloadTemplates() { |
97 indexTemplate = template.Must(template.ParseFiles( | 94 indexTemplate = template.Must(template.ParseFiles( |
98 filepath.Join(*resourcesDir, "templates/index.html"), | 95 filepath.Join(*resourcesDir, "templates/index.html"), |
99 filepath.Join(*resourcesDir, "templates/header.html"), | 96 filepath.Join(*resourcesDir, "templates/header.html"), |
100 )) | 97 )) |
101 overviewTemplate = template.Must(template.ParseFiles( | |
102 filepath.Join(*resourcesDir, "templates/overview.html"), | |
103 filepath.Join(*resourcesDir, "templates/header.html"), | |
104 )) | |
105 detailsTemplate = template.New("details.html") | 98 detailsTemplate = template.New("details.html") |
106 // Allows this template to have Polymer binding in it and go template ma
rkup. The go templates | 99 // Allows this template to have Polymer binding in it and go template ma
rkup. The go templates |
107 // have been changed to be {%.Thing%} instead of {{.Thing}} | 100 // have been changed to be {%.Thing%} instead of {{.Thing}} |
108 detailsTemplate.Delims("{%", "%}") | 101 detailsTemplate.Delims("{%", "%}") |
109 detailsTemplate = template.Must(detailsTemplate.ParseFiles( | 102 detailsTemplate = template.Must(detailsTemplate.ParseFiles( |
110 filepath.Join(*resourcesDir, "templates/details.html"), | 103 filepath.Join(*resourcesDir, "templates/details.html"), |
111 filepath.Join(*resourcesDir, "templates/header.html"), | 104 filepath.Join(*resourcesDir, "templates/header.html"), |
112 )) | 105 )) |
113 } | 106 } |
114 | 107 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 r.HandleFunc("/category/{category:[a-z_]+}/file/{file}/func/{function}",
detailsPageHandler) | 213 r.HandleFunc("/category/{category:[a-z_]+}/file/{file}/func/{function}",
detailsPageHandler) |
221 r.HandleFunc(`/category/{category:[a-z_]+}/file/{file}/func/{function}/l
ine/{line}`, detailsPageHandler) | 214 r.HandleFunc(`/category/{category:[a-z_]+}/file/{file}/func/{function}/l
ine/{line}`, detailsPageHandler) |
222 r.HandleFunc("/loginstatus/", login.StatusHandler) | 215 r.HandleFunc("/loginstatus/", login.StatusHandler) |
223 r.HandleFunc("/logout/", login.LogoutHandler) | 216 r.HandleFunc("/logout/", login.LogoutHandler) |
224 r.HandleFunc("/json/version", skiaversion.JsonHandler) | 217 r.HandleFunc("/json/version", skiaversion.JsonHandler) |
225 r.HandleFunc("/json/fuzz-summary", summaryJSONHandler) | 218 r.HandleFunc("/json/fuzz-summary", summaryJSONHandler) |
226 r.HandleFunc("/json/details", detailsJSONHandler) | 219 r.HandleFunc("/json/details", detailsJSONHandler) |
227 r.HandleFunc("/json/status", statusJSONHandler) | 220 r.HandleFunc("/json/status", statusJSONHandler) |
228 r.HandleFunc(`/fuzz/{category:[a-z_]+}/{name:[0-9a-f]+}`, fuzzHandler) | 221 r.HandleFunc(`/fuzz/{category:[a-z_]+}/{name:[0-9a-f]+}`, fuzzHandler) |
229 r.HandleFunc(`/metadata/{category:[a-z_]+}/{name:[0-9a-f]+_(debug|releas
e)\.(err|dump|asan)}`, metadataHandler) | 222 r.HandleFunc(`/metadata/{category:[a-z_]+}/{name:[0-9a-f]+_(debug|releas
e)\.(err|dump|asan)}`, metadataHandler) |
230 r.HandleFunc("/fuzz_count", fuzzCountHandler) | |
231 r.HandleFunc("/newBug", newBugHandler) | 223 r.HandleFunc("/newBug", newBugHandler) |
232 | 224 |
233 rootHandler := login.ForceAuth(util.LoggingGzipRequestResponse(r), OAUTH
2_CALLBACK_PATH) | 225 rootHandler := login.ForceAuth(util.LoggingGzipRequestResponse(r), OAUTH
2_CALLBACK_PATH) |
234 | 226 |
235 http.Handle("/", rootHandler) | 227 http.Handle("/", rootHandler) |
236 glog.Infof("Ready to serve on %s", serverURL) | 228 glog.Infof("Ready to serve on %s", serverURL) |
237 glog.Fatal(http.ListenAndServe(*port, nil)) | 229 glog.Fatal(http.ListenAndServe(*port, nil)) |
238 } | 230 } |
239 | 231 |
240 func indexHandler(w http.ResponseWriter, r *http.Request) { | 232 func indexHandler(w http.ResponseWriter, r *http.Request) { |
(...skipping 17 matching lines...) Expand all Loading... |
258 Category string | 250 Category string |
259 }{ | 251 }{ |
260 Category: mux.Vars(r)["category"], | 252 Category: mux.Vars(r)["category"], |
261 } | 253 } |
262 | 254 |
263 if err := detailsTemplate.Execute(w, cat); err != nil { | 255 if err := detailsTemplate.Execute(w, cat); err != nil { |
264 glog.Errorf("Failed to expand template: %v", err) | 256 glog.Errorf("Failed to expand template: %v", err) |
265 } | 257 } |
266 } | 258 } |
267 | 259 |
268 func summaryPageHandler(w http.ResponseWriter, r *http.Request) { | |
269 if *local { | |
270 reloadTemplates() | |
271 } | |
272 w.Header().Set("Content-Type", "text/html") | |
273 | |
274 var cat = struct { | |
275 Category string | |
276 }{ | |
277 Category: mux.Vars(r)["category"], | |
278 } | |
279 | |
280 if err := overviewTemplate.Execute(w, cat); err != nil { | |
281 glog.Errorf("Failed to expand template: %v", err) | |
282 } | |
283 } | |
284 | |
285 type countSummary struct { | 260 type countSummary struct { |
286 Category string `json:"category"` | 261 Category string `json:"category"` |
287 CategoryDisplay string `json:"categoryDisplay"` | 262 CategoryDisplay string `json:"categoryDisplay"` |
288 TotalBad int `json:"totalBadCount"` | 263 TotalBad int `json:"totalBadCount"` |
289 TotalGrey int `json:"totalGreyCount"` | 264 TotalGrey int `json:"totalGreyCount"` |
290 // "This" means "newly introduced/fixed in this revision" | 265 // "This" means "newly introduced/fixed in this revision" |
291 ThisBad int `json:"thisBadCount"` | 266 ThisBad int `json:"thisBadCount"` |
292 ThisGrey int `json:"thisGreyCount"` | 267 ThisGrey int `json:"thisGreyCount"` |
293 } | 268 } |
294 | 269 |
295 func summaryJSONHandler(w http.ResponseWriter, r *http.Request) { | 270 func summaryJSONHandler(w http.ResponseWriter, r *http.Request) { |
296 » var overview interface{} | 271 » summary := getSummary() |
297 » if cat := r.FormValue("category"); cat != "" { | |
298 » » overview = data.CategoryOverview(cat) | |
299 » } else { | |
300 » » overview = getOverview() | |
301 » } | |
302 | 272 |
303 » if err := json.NewEncoder(w).Encode(overview); err != nil { | 273 » if err := json.NewEncoder(w).Encode(summary); err != nil { |
304 glog.Errorf("Failed to write or encode output: %v", err) | 274 glog.Errorf("Failed to write or encode output: %v", err) |
305 return | 275 return |
306 } | 276 } |
307 } | 277 } |
308 | 278 |
309 func getOverview() []countSummary { | 279 func getSummary() []countSummary { |
310 » overviews := make([]countSummary, 0, len(fcommon.FUZZ_CATEGORIES)) | 280 » counts := make([]countSummary, 0, len(fcommon.FUZZ_CATEGORIES)) |
311 for _, cat := range fcommon.FUZZ_CATEGORIES { | 281 for _, cat := range fcommon.FUZZ_CATEGORIES { |
312 o := countSummary{ | 282 o := countSummary{ |
313 CategoryDisplay: fcommon.PrettifyCategory(cat), | 283 CategoryDisplay: fcommon.PrettifyCategory(cat), |
314 Category: cat, | 284 Category: cat, |
315 } | 285 } |
316 c := syncer.FuzzCount{ | 286 c := syncer.FuzzCount{ |
317 TotalBad: -1, | 287 TotalBad: -1, |
318 TotalGrey: -1, | 288 TotalGrey: -1, |
319 ThisBad: -1, | 289 ThisBad: -1, |
320 ThisGrey: -1, | 290 ThisGrey: -1, |
321 } | 291 } |
322 if fuzzSyncer != nil { | 292 if fuzzSyncer != nil { |
323 c = fuzzSyncer.LastCount(cat) | 293 c = fuzzSyncer.LastCount(cat) |
324 } | 294 } |
325 o.TotalBad = c.TotalBad | 295 o.TotalBad = c.TotalBad |
326 o.ThisBad = c.ThisBad | 296 o.ThisBad = c.ThisBad |
327 o.TotalGrey = c.TotalGrey | 297 o.TotalGrey = c.TotalGrey |
328 o.ThisGrey = c.ThisGrey | 298 o.ThisGrey = c.ThisGrey |
329 » » overviews = append(overviews, o) | 299 » » counts = append(counts, o) |
330 } | 300 } |
331 » return overviews | 301 » return counts |
332 } | 302 } |
333 | 303 |
334 func detailsJSONHandler(w http.ResponseWriter, r *http.Request) { | 304 func detailsJSONHandler(w http.ResponseWriter, r *http.Request) { |
335 w.Header().Set("Content-Type", "application/json") | 305 w.Header().Set("Content-Type", "application/json") |
336 | 306 |
337 category := r.FormValue("category") | 307 category := r.FormValue("category") |
338 name := r.FormValue("name") | 308 name := r.FormValue("name") |
339 // The file names have "/" in them and the functions can have "(*&" in t
hem. | 309 // The file names have "/" in them and the functions can have "(*&" in t
hem. |
340 // We base64 encode them to prevent problems. | 310 // We base64 encode them to prevent problems. |
341 file, err := decodeBase64(r.FormValue("file")) | 311 file, err := decodeBase64(r.FormValue("file")) |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 437 } |
468 } | 438 } |
469 } | 439 } |
470 | 440 |
471 if err := json.NewEncoder(w).Encode(s); err != nil { | 441 if err := json.NewEncoder(w).Encode(s); err != nil { |
472 glog.Errorf("Failed to write or encode output: %s", err) | 442 glog.Errorf("Failed to write or encode output: %s", err) |
473 return | 443 return |
474 } | 444 } |
475 } | 445 } |
476 | 446 |
477 func fuzzCountHandler(w http.ResponseWriter, r *http.Request) { | |
478 c := syncer.FuzzCount{ | |
479 TotalBad: -1, | |
480 TotalGrey: -1, | |
481 ThisBad: -1, | |
482 ThisGrey: -1, | |
483 } | |
484 if fuzzSyncer != nil { | |
485 c = fuzzSyncer.LastCount(r.FormValue("category")) | |
486 } | |
487 if err := json.NewEncoder(w).Encode(c); err != nil { | |
488 glog.Errorf("Failed to write or encode output: %s", err) | |
489 return | |
490 } | |
491 } | |
492 | |
493 type newBug struct { | 447 type newBug struct { |
494 Category string | 448 Category string |
495 PrettyCategory string | 449 PrettyCategory string |
496 Name string | 450 Name string |
497 Revision string | 451 Revision string |
498 } | 452 } |
499 | 453 |
500 var newBugTemplate = template.Must(template.New("new_bug").Parse(`# Your bug des
cription here about fuzz found in {{.PrettyCategory}} | 454 var newBugTemplate = template.Must(template.New("new_bug").Parse(`# Your bug des
cription here about fuzz found in {{.PrettyCategory}} |
501 | 455 |
502 # tracking metadata below: | 456 # tracking metadata below: |
(...skipping 19 matching lines...) Expand all Loading... |
522 } | 476 } |
523 var t bytes.Buffer | 477 var t bytes.Buffer |
524 if err := newBugTemplate.Execute(&t, b); err != nil { | 478 if err := newBugTemplate.Execute(&t, b); err != nil { |
525 util.ReportError(w, r, err, fmt.Sprintf("Could not create templa
te with %#v", b)) | 479 util.ReportError(w, r, err, fmt.Sprintf("Could not create templa
te with %#v", b)) |
526 return | 480 return |
527 } | 481 } |
528 q.Add("comment", t.String()) | 482 q.Add("comment", t.String()) |
529 // 303 means "make a GET request to this url" | 483 // 303 means "make a GET request to this url" |
530 http.Redirect(w, r, "https://bugs.chromium.org/p/skia/issues/entry?"+q.E
ncode(), 303) | 484 http.Redirect(w, r, "https://bugs.chromium.org/p/skia/issues/entry?"+q.E
ncode(), 303) |
531 } | 485 } |
OLD | NEW |