func warmupHandler(c *echo.Context) error { if appengine.IsDevAppServer() { photographers := []Photographer{ {1, "Mr Canon"}, {2, "Miss Nikon"}, {3, "Mrs Pentax"}, {4, "Ms Sony"}, } // create some dummy data for m := 1; m <= 12; m++ { for d := 1; d < 28; d++ { taken := time.Date(2015, time.Month(m), d, 12, 0, 0, 0, time.UTC) id := rand.Int31n(4) photographer := photographers[id] p := Photo{ Photographer: photographer, Uploaded: time.Now().UTC(), Width: 8000, Height: 6000, Taken: taken, } k := datastore.NewIncompleteKey(c, "photo", nil) nds.Put(c, k, &p) } } } return c.NoContent(http.StatusOK) }
func recaptchaCheck(ctx context.Context, response, ip string) (bool, error) { if appengine.IsDevAppServer() { return true, nil } form := url.Values{} form.Add("secret", os.Getenv("SECRET")) form.Add("response", response) form.Add("remoteip", ip) req, err := http.NewRequest("POST", recaptchaURL, strings.NewReader(form.Encode())) if err != nil { return false, err } cli := urlfetch.Client(ctx) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := cli.Do(req) if err != nil { return false, err } var recaptcha recaptchaResponse if err := json.NewDecoder(resp.Body).Decode(&recaptcha); err != nil { return false, err } if !recaptcha.Success { log.Warningf(ctx, "%+v", recaptcha) return false, nil } return true, nil }
func (s *shard) createOutputFile(c context.Context) (io.WriteCloser, error) { c, _ = context.WithTimeout(c, time.Duration(10)*time.Minute) // for development we can't use the appengine default credentials so // instead need to create our own oauth token source to access storage // TODO: maybe give job a chance to generate this - it could also // create the writer (?). The only reason we're doing it is to prevent // duplication and also handle the file rollup operations var client *cstorage.Client if appengine.IsDevAppServer() { jsonKey, err := ioutil.ReadFile("service-account.json") if err != nil { return nil, err } conf, err := google.JWTConfigFromJSON(jsonKey, cstorage.ScopeReadWrite) if err != nil { return nil, err } client, err = cstorage.NewClient(c, option.WithTokenSource(conf.TokenSource(c))) if err != nil { return nil, err } } else { var err error client, err = cstorage.NewClient(c) if err != nil { return nil, err } } o := client.Bucket(s.job.Bucket).Object(s.sliceFilename(s.Sequence)).NewWriter(c) // TODO: wrap writer to count bytes and continue slice if we get close to 10Mb limit (?) return o, nil }
func putCookie(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, error) { p, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } token := &model.Token{ Description: "Login from " + r.RemoteAddr, } value, err := p.IssueToken(ctx, token) if err != nil { return http.StatusInternalServerError, err } http.SetCookie(w, &http.Cookie{ Name: "token", Value: value, Secure: !appengine.IsDevAppServer(), HttpOnly: true, Expires: token.Expiry, }) w.Write([]byte("OK")) return http.StatusOK, nil }
func appstatsHandler(w http.ResponseWriter, r *http.Request) { ctx := storeContext(appengine.NewContext(r)) if appengine.IsDevAppServer() { // noop } else if u := user.Current(ctx); u == nil { if loginURL, err := user.LoginURL(ctx, r.URL.String()); err == nil { http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect) } else { serveError(w, err) } return } else if !u.Admin { http.Error(w, "Forbidden", http.StatusForbidden) return } if detailsURL == r.URL.Path { details(ctx, w, r) } else if fileURL == r.URL.Path { file(ctx, w, r) } else if strings.HasPrefix(r.URL.Path, staticURL) { name := r.URL.Path[strings.LastIndex(r.URL.Path, "/")+1:] content, ok := static[name] if !ok { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } http.ServeContent(w, r, name, initTime, content) } else { index(ctx, w, r) } }
func getTableProceed() string { if newappengine.IsDevAppServer() { return BIGQUERY_TABLE_PROCEED_DEV } else { return BIGQUERY_TABLE_PROCEED_PROD } }
// Rudimentary CORS checking. See // https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS func cors(h http.HandlerFunc) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { origin := r.Header.Get("Origin") if !appengine.IsDevAppServer() { if origin == "" { h(w, r) return } if !strings.HasPrefix(origin, "https://app.cod.uno") { http.Error(w, "Invalid CORS request", http.StatusUnauthorized) return } } w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE") w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Origin", origin) if r.Method == "OPTIONS" { w.Write([]byte("OK")) return } h(w, r) }) }
func initEnv() { if appengine.IsDevAppServer() { env = envDev } else { env = envProd } }
// this will generate some random data for the given day // 24 * 12 on appengine (288) // 24 only on development func generateRandom(c context.Context, day time.Time) error { var x int if appengine.IsDevAppServer() { x = 1 } else { x = 12 } keys := make([]*datastore.Key, 24*x) photos := make([]*Photo, 24*x) id := 0 for h := 0; h < 24; h++ { taken := day.Add(time.Duration(h) * time.Hour) for i := 0; i < x; i++ { photographer := photographers[rand.Int31n(4)] photos[id] = &Photo{ Photographer: photographer, Uploaded: time.Now().UTC(), Width: 8000, Height: 6000, Taken: taken, TakenDay: day, } keys[id] = datastore.NewIncompleteKey(c, "photo", nil) id++ } } nds.PutMulti(c, keys, photos) return nil }
// Rudimentary CORS checking. See // https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS func cors(w http.ResponseWriter, r *http.Request) bool { origin := r.Header.Get("Origin") // If the client has not provided it's origin, the // request will be answered in any case. if origin == "" { return true } // Only allow our own origin if not on development server. if !appengine.IsDevAppServer() && origin != "https://app.cod.uno" { http.Error(w, "Invalid Origin", http.StatusUnauthorized) return false } // We have a nice CORS established, so set appropriate headers. // TODO(flowlo): Figure out how to send correct methods. w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE") w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Origin", origin) // If this is an OPTIONS request, we answer it // immediately and do not bother higher level handlers. if r.Method == "OPTIONS" { w.Write([]byte("OK")) return false } return true }
func init() { if appengine.IsDevAppServer() { AuthenticatorFactory = tokeninfoAuthenticatorFactory } else { AuthenticatorFactory = cachingAuthenticatorFactory } }
func allowShare(r *http.Request) bool { if appengine.IsDevAppServer() { return true } switch r.Header.Get("X-AppEngine-Country") { case "", "ZZ", "CN": return false } return true }
func gaeUrl() string { if appengine.IsDevAppServer() { return "http://localhost:8080" } else { // Include your URL on App Engine here. // I found no way to get AppID without appengine.Context and this always // based on a http.Request. return "http://federatedservices.appspot.com" } }
func init() { if appengine.IsDevAppServer() { upgrader.CheckOrigin = func(r *http.Request) bool { log.Printf("Allowing origin %s", r.Header["Origin"]) return true } upgrader.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { log.Printf("WebSocket HTTP %d because of %s", status, reason) http.Error(w, reason.Error(), status) } } }
func init() { var err error if appengine.IsDevAppServer() { dc, err = docker.NewClientFromEnv() } else { // FIXME(flowlo) dc, err = docker.NewClient("tcp://10.240.10.141:2375") } if err != nil { panic(err) } }
func getGaeURL() string { if appengine.IsDevAppServer() { return "http://localhost:8080" } else { /** * Include your URL on App Engine here. * I found no way to get AppID without appengine.Context and this always * based on a http.Request. */ return "http://<your_app_id>.appspot.com" } }
func init() { enforceHosts = !appengine.IsDevAppServer() playEnabled = true log.Println("initializing godoc ...") log.Printf(".zip file = %s", zipFilename) log.Printf(".zip GOROOT = %s", zipGoroot) log.Printf("index files = %s", indexFilenames) goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/' // read .zip file and set up file systems const zipfile = zipFilename rc, err := zip.OpenReader(zipfile) if err != nil { log.Fatalf("%s: %s\n", zipfile, err) } // rc is never closed (app running forever) fs.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace) fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace) corpus := godoc.NewCorpus(fs) corpus.Verbose = false corpus.MaxResults = 10000 // matches flag default in main.go corpus.IndexEnabled = true corpus.IndexFiles = indexFilenames if err := corpus.Init(); err != nil { log.Fatal(err) } corpus.IndexDirectory = indexDirectoryDefault go corpus.RunIndexer() pres = godoc.NewPresentation(corpus) pres.TabWidth = 8 pres.ShowPlayground = true pres.ShowExamples = true pres.DeclLinks = true pres.NotesRx = regexp.MustCompile("BUG") readTemplates(pres, true) mux := registerHandlers(pres) dl.RegisterHandlers(mux) short.RegisterHandlers(mux) // Register /compile and /share handlers against the default serve mux // so that other app modules can make plain HTTP requests to those // hosts. (For reasons, HTTPS communication between modules is broken.) proxy.RegisterHandlers(http.DefaultServeMux) log.Println("godoc initialization complete") }
// IsLocalEnviron tells us, if we are on the // local development server, or on the google app engine cloud maschine func IsLocalEnviron() bool { return appengine.IsDevAppServer() s := os.TempDir() s = strings.ToLower(s) if s[0:2] == "c:" || s[0:2] == "d:" { // we are on windoofs - we are NOT on GAE return true } return false }
func hsts(w http.ResponseWriter) { if !appengine.IsDevAppServer() { // Protect against HTTP downgrade attacks by explicitly telling // clients to use HTTPS. // max-age is computed to match the expiration date of our TLS // certificate. // https://developer.mozilla.org/docs/Web/Security/HTTP_strict_transport_security // This is only set on production. invalidity := time.Date(2017, time.July, 15, 8, 30, 21, 0, time.UTC) maxAge := invalidity.Sub(time.Now()).Seconds() w.Header().Set("Strict-Transport-Security", fmt.Sprintf("max-age=%d", int(maxAge))) } }
// compileCSS gets the CSS name from the URL, determines if there is a pre-built version // and compiles the CSS if need be before serving it to the client func compileCSS(w http.ResponseWriter, r *http.Request) { file := r.URL.Path[len("/css/"):] if file == "" { errorHandler(w, r, http.StatusInternalServerError, "did not get a name of a CSS file") return } if !appengine.IsDevAppServer() { _, err := os.Stat("static/css/" + file) if err == nil { http.ServeFile(w, r, "static/css/"+file) return } } // check if a generated version of the file exists _, err := os.Stat("static/css/" + file) if err == nil { http.ServeFile(w, r, "static/css/"+file) return } // convert the .css extension to .gcss and build out path to the file f := gcss.Path(file) f = fmt.Sprintf("static/css/%s", f) // read the GCSS file css, err := os.Open(f) if err != nil { errorHandler(w, r, http.StatusInternalServerError, err.Error()) return } // close out the file resource once done defer func() { if err := css.Close(); err != nil { errorHandler(w, r, http.StatusInternalServerError, err.Error()) return } }() // set the content type header so browsers will know how to handle it w.Header().Set("Content-Type", "text/css") // build out the CSS and serve it to the browser _, err = gcss.Compile(w, css) if err != nil { errorHandler(w, r, http.StatusInternalServerError, err.Error()) return } }
func init() { renderer := render.New(render.Options{}) token := os.Getenv("SLACK_TOKEN") http.HandleFunc("/v1/cmd", func(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) req, err := goslash.ParseFormSlashCommandRequest(r) if err != nil { renderer.JSON(w, http.StatusInternalServerError, err.Error()) return } if req.Token != token { log.Errorf(ctx, "received invalid token:%v from %v", req.Token, r.RemoteAddr) renderer.JSON(w, http.StatusForbidden, "invalid token") return } slashPlugins := map[string]plugins.Plugin{ "echo": echo.New(), "time": time.New(), "突然": suddendeath.New(), "LGTM": lgtm.New(urlfetch.Client(ctx)), "akari": akari.New(), } slashCmd := plugins.New(urlfetch.Client(ctx), slashPlugins) if appengine.IsDevAppServer() { // development cmd, _ := req.CmdArgs() p, ok := slashPlugins[cmd] if !ok { renderer.JSON(w, http.StatusNotFound, "cmd not found") return } msg := p.Do(req) var jsonData bytes.Buffer if err := json.NewEncoder(&jsonData).Encode(&msg); err != nil { renderer.JSON(w, http.StatusInternalServerError, err.Error()) return } renderer.JSON(w, http.StatusOK, jsonData.String()) } else { // production renderer.Text(w, http.StatusOK, slashCmd.Execute(req)) } }) }
func (h urlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c := h.getContext(r) ds := appwrap.NewAppengineDatastore(c) monitorTimeout := time.Minute * 30 if appengine.IsDevAppServer() { monitorTimeout = time.Second * 10 } if strings.HasSuffix(r.URL.Path, "/map-monitor") || strings.HasSuffix(r.URL.Path, "/reduce-monitor") { if jobKeyStr := r.FormValue("jobKey"); jobKeyStr == "" { http.Error(w, "jobKey parameter required", http.StatusBadRequest) } else if jobKey, err := datastore.DecodeKey(jobKeyStr); err != nil { http.Error(w, fmt.Sprintf("invalid jobKey: %s", err.Error()), http.StatusBadRequest) } else if strings.HasSuffix(r.URL.Path, "/map-monitor") { w.WriteHeader(mapMonitorTask(c, ds, h.pipeline, jobKey, r, monitorTimeout)) } else { w.WriteHeader(reduceMonitorTask(c, ds, h.pipeline, jobKey, r, monitorTimeout)) } return } var taskKey *datastore.Key var err error if taskKeyStr := r.FormValue("taskKey"); taskKeyStr == "" { http.Error(w, "taskKey parameter required", http.StatusBadRequest) return } else if taskKey, err = datastore.DecodeKey(taskKeyStr); err != nil { http.Error(w, fmt.Sprintf("invalid taskKey: %s", err.Error()), http.StatusBadRequest) return } if strings.HasSuffix(r.URL.Path, "/reduce") { reduceTask(c, ds, h.baseUrl, h.pipeline, taskKey, w, r) } else if strings.HasSuffix(r.URL.Path, "/map") { mapTask(c, ds, h.baseUrl, h.pipeline, taskKey, w, r) } else if strings.HasSuffix(r.URL.Path, "/mapstatus") || strings.HasSuffix(r.URL.Path, "/reducestatus") { updateTask(ds, taskKey, "", 0, r.FormValue("msg"), nil) } else { http.Error(w, "unknown request url", http.StatusNotFound) return } }
// ClientErrorMiddleware rejects the request with a 500 status code when an error occurs. func ClientErrorMiddleware(ctx context.Context, w http.ResponseWriter, r *http.Request, next NextMiddlewareFn) error { err := next(ctx) if err != nil { w.(*AppResponseWriter).Reset() w.Header().Set("Content-Type", "text/plain; charset=utf-8") if appengine.IsDevAppServer() { http.Error(w, errors.ErrorStack(err), http.StatusInternalServerError) } else { http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } return err }
func init() { if appengine.IsDevAppServer() { upgrader.CheckOrigin = func(r *http.Request) bool { return true } return } upgrader.CheckOrigin = func(r *http.Request) bool { origin, ok := r.Header["Origin"] if !ok { return false } // TODO(flowlo): Remove magic constant. return origin[0] == "https://app.cod.uno" } }
func main() { http.HandleFunc("/_ah/mail/", controllers.ReceiveMail) http.HandleFunc("/cert", hsts(guard(controllers.Certificate))) http.HandleFunc("/status", hsts(controllers.Status)) r := mux.NewRouter() r.HandleFunc("/subscriptions", hsts(controllers.Subscriptions)) r.HandleFunc("/code/download", hsts(guard(controllers.Template))) r.HandleFunc("/invitations", setup(controllers.Invitation)) r.HandleFunc("/accessTokens", setup(controllers.AccessTokens)) r.HandleFunc("/challenges", setup(controllers.CreateChallenge)) r.HandleFunc("/challenges/{key}", setup(controllers.ChallengeByKey)) r.HandleFunc("/challenges/{key}/results", setup(controllers.GetResultsByChallenge)) r.HandleFunc("/companies", setup(controllers.PostCompany)) r.HandleFunc("/companies/{key}/challenges", setup(controllers.GetChallengesForCompany)) r.HandleFunc("/companies/{key}/users", setup(controllers.GetUsersByCompany)) r.HandleFunc("/profiles/{key}", setup(controllers.GetProfileByKey)) r.HandleFunc("/profiles/{key}", setup(controllers.DeleteProfile)) r.HandleFunc("/results", setup(controllers.CreateResult)) r.HandleFunc("/results/{resultKey}/tasks/{taskKey}/submissions", setup(controllers.PostSubmission)) r.HandleFunc("/results/{resultKey}/finalSubmissions/{index}", setup(controllers.FinalSubmission)) r.HandleFunc("/results/{resultKey}", setup(controllers.GetResult)) r.HandleFunc("/user/company", setup(controllers.GetCompanyByUser)) r.HandleFunc("/user", setup(controllers.WhoAmI)) r.HandleFunc("/users", setup(controllers.User)) r.HandleFunc("/tasks/{key}", setup(controllers.TaskByKey)) r.HandleFunc("/tasks", setup(controllers.Tasks)) r.HandleFunc("/whoami", setup(controllers.WhoAmI)) r.HandleFunc("/mock/coduno", controllers.MockCoduno) if appengine.IsDevAppServer() { r.HandleFunc("/mock/all", controllers.Mock) r.HandleFunc("/mock/challenge", controllers.MockChallenge) } http.Handle("/", r) appengine.Main() }
// linkToPrimary sends HttpRPC to the primary to register myself as a replica. func linkToPrimary(c context.Context, ticket ServiceLinkTicket, initiatedBy string) error { headers := make(map[string]string) headers["Content-Type"] = "application/octet-stream" protocol := "https" if appengine.IsDevAppServer() { headers["X-Appengine-Inbound-Appid"] = appengine.AppID(c) protocol = "http" } linkReq := &ServiceLinkRequest{ Ticket: ticket.GetTicket(), ReplicaUrl: proto.String(fmt.Sprintf("%s://%s", protocol, appengine.DefaultVersionHostname(c))), InitiatedBy: proto.String(initiatedBy), } buf, err := proto.Marshal(linkReq) if err != nil { return err } req, err := http.NewRequest("POST", fmt.Sprintf("%s/auth_service/api/v1/internal/link_replica", ticket.GetPrimaryUrl()), bytes.NewReader(buf)) if err != nil { return err } for key, value := range headers { req.Header.Add(key, value) } client := urlfetch.Client(c) resp, err := client.Do(req) if err != nil { return err } if resp.StatusCode != 200 { return fmt.Errorf("got status code %v; want 200", resp.StatusCode) } respBody := new(bytes.Buffer) respBody.ReadFrom(resp.Body) linkResp := &ServiceLinkResponse{} if err = proto.Unmarshal(respBody.Bytes(), linkResp); err != nil { return err } if linkResp.GetStatus() != ServiceLinkResponse_SUCCESS { return fmt.Errorf("Request to the primary failed with status %d", linkResp.GetStatus()) } return nil }
func checkReferer(c context.Context) error { if appengine.IsDevAppServer() { return nil } r := endpoints.HTTPRequest(c).Referer() u, err := url.Parse(r) if err != nil { return endpoints.NewUnauthorizedError("couldn't extract domain from referer") } if u.Host != appengine.AppID(c)+".appspot.com" { return endpoints.NewUnauthorizedError("referer unauthorized") } return nil }
func runOnce(c appengine.Context, f func(appengine.Context) error, opts *TransactionOptions) error { // Begin the transaction. t := &transaction{Context: c} req := &pb.BeginTransactionRequest{ App: proto.String(c.FullyQualifiedAppID()), } if opts != nil && opts.XG { req.AllowMultipleEg = proto.Bool(true) } if err := t.Context.Call("datastore_v3", "BeginTransaction", req, &t.transaction, nil); err != nil { return err } // Call f, rolling back the transaction if f returns a non-nil error, or panics. // The panic is not recovered. defer func() { if t.finished { return } t.finished = true // Ignore the error return value, since we are already returning a non-nil // error (or we're panicking). c.Call("datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{}, nil) }() if err := f(t); err != nil { return err } t.finished = true // Commit the transaction. res := &pb.CommitResponse{} err := c.Call("datastore_v3", "Commit", &t.transaction, res, nil) if ae, ok := err.(*internal.APIError); ok { if appengine.IsDevAppServer() { // The Python Dev AppServer raises an ApplicationError with error code 2 (which is // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.". if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." { return ErrConcurrentTransaction } } if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) { return ErrConcurrentTransaction } } return err }
func init() { http.Handle("/", handlerFunc(serveRoot)) http.Handle("/compile", handlerFunc(serveCompile)) http.Handle("/bot.html", handlerFunc(serveBot)) present.PlayEnabled = true if s := os.Getenv("CONTACT_EMAIL"); s != "" { contactEmail = s } if appengine.IsDevAppServer() { return } github := httputil.NewAuthTransportFromEnvironment(nil) if github.Token == "" || github.ClientID == "" || github.ClientSecret == "" { panic("missing GitHub metadata, follow the instructions on README.md") } }
func NewConfig(context context.Context) Config { appID := appengine.AppID(context) log.Infof(context, "AppID: %v", appID) if appengine.IsDevAppServer() { return DevConfig() } if appID == ProductionAppID { return ProductionConfig() } if appID == StagingAppID { return StagingConfig() } panic("Could not resolve environment configuration") }