From 2bee026ca1f45c41015be6205efd60401edb84d0 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 9 Oct 2015 15:50:38 -0400 Subject: [PATCH 1/2] doc: Use relative links in generated index.html when possible BUG=crashpad:67 Review URL: https://codereview.chromium.org/1397173002 . --- doc/support/generate.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/support/generate.sh b/doc/support/generate.sh index f5785c64..f85e4d3c 100755 --- a/doc/support/generate.sh +++ b/doc/support/generate.sh @@ -43,7 +43,10 @@ done # Move doc/index.html to index.html, adjusting relative paths to other files in # doc. +base_url=https://crashpad-home.appspot.com/ ${sed_ext} -e 's%%%g' \ + -e 's%%%g' \ + -e 's% "${output_dir}/index.html" rm "${output_dir}/doc/index.html" From a2740b23a2b5a8aaa65a8323fe784b5cbf14377d Mon Sep 17 00:00:00 2001 From: Andrew Bonventre Date: Fri, 9 Oct 2015 15:59:32 -0400 Subject: [PATCH 2/2] Add app engine app to mirror html docs from chromium.googlesource.com BUG=crashpad:67 R=mark@chromium.org, rsesek@chromium.org Review URL: https://codereview.chromium.org/1393353002 . Patch from Andrew Bonventre . --- doc/appengine/app.yaml | 9 +++ doc/appengine/main.go | 122 ++++++++++++++++++++++++++++++++++++++++ doc/favicon.ico | Bin 0 -> 8348 bytes doc/support/generate.sh | 3 + 4 files changed, 134 insertions(+) create mode 100644 doc/appengine/app.yaml create mode 100644 doc/appengine/main.go create mode 100644 doc/favicon.ico diff --git a/doc/appengine/app.yaml b/doc/appengine/app.yaml new file mode 100644 index 00000000..bcf370c8 --- /dev/null +++ b/doc/appengine/app.yaml @@ -0,0 +1,9 @@ +application: crashpad-home +version: 1 +runtime: go +api_version: go1 + +handlers: +- url: /.* + script: _go_app + secure: always diff --git a/doc/appengine/main.go b/doc/appengine/main.go new file mode 100644 index 00000000..261440d4 --- /dev/null +++ b/doc/appengine/main.go @@ -0,0 +1,122 @@ +// Copyright 2015 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package crashpad mirrors crashpad documentation from Chromium’s git repo. +package crashpad + +import ( + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "path" + "strings" + "time" + + "google.golang.org/appengine" + "google.golang.org/appengine/memcache" + "google.golang.org/appengine/urlfetch" +) + +const baseURL = "https://chromium.googlesource.com/crashpad/crashpad/+/doc/doc/generated/?format=TEXT" + +func init() { + http.HandleFunc("/", handler) +} + +func handler(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + client := urlfetch.Client(ctx) + + // Don’t show dotfiles. + if strings.HasPrefix(path.Base(r.URL.Path), ".") { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + + u, err := url.Parse(baseURL) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + u.Path = path.Join(u.Path, r.URL.Path) + urlStr := u.String() + + item, err := memcache.Get(ctx, urlStr) + if err == memcache.ErrCacheMiss { + resp, err := client.Get(urlStr) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + w.WriteHeader(resp.StatusCode) + for k, v := range w.Header() { + w.Header()[k] = v + } + io.Copy(w, resp.Body) + return + } + + // Redirect directories to their index pages (/doc/ -> /doc/index.html). + if resp.Header.Get("X-Gitiles-Object-Type") == "tree" { + http.Redirect(w, r, path.Join(r.URL.Path, "/index.html"), http.StatusFound) + return + } + + decoder := base64.NewDecoder(base64.StdEncoding, resp.Body) + b, err := ioutil.ReadAll(decoder) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + item = &memcache.Item{ + Key: urlStr, + Value: b, + Expiration: 1 * time.Hour, + } + if err := memcache.Set(ctx, item); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } else if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", contentType(path.Base(u.Path))) + fmt.Fprintf(w, "%s", item.Value) +} + +// contentType returns the appropriate content type header for file. +func contentType(file string) string { + contentTypes := map[string]string{ + ".html": "text/html; charset=UTF-8", + ".css": "text/css; charset=UTF-8", + ".js": "text/javascript; charset=UTF-8", + ".png": "image/png", + ".ico": "image/x-icon", + } + for suffix, typ := range contentTypes { + if strings.HasSuffix(file, suffix) { + return typ + } + } + return "text/plain; charset=UTF-8" +} diff --git a/doc/favicon.ico b/doc/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..23c553a2966ca4cecf146093f33d8114b4f1e368 GIT binary patch literal 8348 zcmeI0du&tJ8Ng3Vwv|ewX4Hu@my&|vCD%DN@CLnxyptBT_%HjatoYr7%N3zGPed#@ckvA><;HWecDU4&2}*2(h%gm&WgCftWj zkQfW;&mXr@0S&(csd+cjaImbXSy=NC<10}z(efGwgi=;B$dt=HkKYCvp-#3KX+qIu zxx$>zcwk+N=c%1^J9)sO44lmS0##~wzU(43f>wW-p_YXwj>s>3{gHI*^oo1lmJ!X*bw{3UBAKRut zUh5Uy4_94IIkdxC^v{_g%FjuEI+f&;9KQ3i+nK7pU_RivFjP_DTl-&gP_qr$nD=M{ z@z;C3#y5Jsh77svGQ4u$ZX)t}=e52{#Xvk;4qIxNh86kR$OhCAie%&e`U{r{ACQZ@ z-)1#sItef{2L za&U;nm+_lo@lbR7vat&^EcECsH)uSnhlht@etsV4LE5B`j#GW*iur~}xpYlTtc;FC{nl|LK^miZ0y3WU>MIM zmc}94VzEFx9?#&?4l+h;ggzvOeCI$ob=`tBp*&EtirH2xU z4a#KB)IMa{_YdYrnxq>-DrrQ>rfpYe8@|Nc-oHnG*L(HR$}d4Eo2&X@o1~9l@%@W) zU{%rv$`tBAOHJH+?zcv7`!T~x;=<#7@4R5T^5$-%Pz-NAYt+5{d;>R+9W24y&`;ZkZqFGQ6_)<35Z_$5V#ga#=N9985-M0KR*fl@h4M0BxWvbYQr6t zULtYBAMJ%iU>x|?U8z_Zyv1jg_VcZ^kO)pd_)jk`_~2MHZmybbloW?l)lnMrb~TAX zV&%#e+VLvM4!%js+%B6}N!=udFlN5Jv;yQm0sdW({6ny+{{$_b`%pI&q3%#p3R?q( z%3@zpafPo4-GA}ErIfU@j?gpfdgeyI);;S-otz(GefQbXvG3J6hbwD_0*YOuqb1V8 zpQm{(oT|g$!tcw;Ck6l>=mo$z0J@0f0^U0{x?+mD8}QB{9yV7qQ;&$5^%*fb@qUB& zX(O<{D-aZ493K;1xH%!}9+}vt8Sshs4os9)d132glTa=lIJv}MJyU_Y!ZFl62j9@l zggg2y{y~c&Vm0cMa@}r@bbn?HR4Sa|66p;nlMl_6D%_%EjCNRq)NBvx!R!t`@zUoW zKV#O#EhZy4>~?VU+rfg@_W_4Kt~zS<|3JjVMcZ#exy;pDUypq|xjpD&0#H{BHgrvM zI=z9nnTN~NCX?mf@DOU;!82-#gXGsw5CSSf22lJ>u8duE&igGuZq4lVZf*LH2%QqOqkv@O{w`Y}q~yWm0EP zeSP~Hau49ZBU@&hWwH5YG0dnGVN1^iztQFh>rIvj5$iQ;q^nyuSuXo`U~{E8DpuIS zA{kR5oC9o=_>jhfRX@QTs1KRm{@F31 zFKP1!w?51@R^I~kA%H*B0W^sKnyVIsv`_2;=zbUGR9pOTqUhV{{^UH=RQ2@S?`uaQ zEy`)Gsd}1IEedW&4lAe0Sg5h`nQXqaZ}RyEzX{FT?hmF3>0_QQT1V~jI$wc&1@aZh ZS0G=3d706zJ{{SaIO|Jj| literal 0 HcmV?d00001 diff --git a/doc/support/generate.sh b/doc/support/generate.sh index f85e4d3c..f4410aee 100755 --- a/doc/support/generate.sh +++ b/doc/support/generate.sh @@ -50,6 +50,9 @@ ${sed_ext} -e 's%%%g' \ < "${output_dir}/doc/index.html" > "${output_dir}/index.html" rm "${output_dir}/doc/index.html" +# Ensure a favicon exists at the root since the browser will always request it. +cp doc/favicon.ico "${output_dir}/" + # Create man/index.html cd "${output_dir}/man" cat > index.html << __EOF__