// GetApiConfigs creates APIDescriptor for every registered RPCService and // responds with a config suitable for generating Discovery doc. // // Responds with a list of active APIs and their configuration files. func (s *BackendService) GetApiConfigs( r *http.Request, req *GetAPIConfigsRequest, resp *APIConfigsList) error { c := appengine.NewContext(r) if req.AppRevision != "" { revision := strings.Split(appengine.VersionID(c), ".")[1] if req.AppRevision != revision { err := fmt.Errorf( "API backend app revision %s not the same as expected %s", revision, req.AppRevision) log.Errorf(c, "%s", err) return err } } resp.Items = make([]string, 0) for _, service := range s.server.services.services { if service.internal { continue } d := &APIDescriptor{} if err := service.APIDescriptor(d, r.Host); err != nil { log.Errorf(c, "%s", err) return err } bytes, err := json.Marshal(d) if err != nil { log.Errorf(c, "%s", err) return err } resp.Items = append(resp.Items, string(bytes)) } return nil }
// handler is the main demo entry point that calls the GCS operations. func handler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } c := appengine.NewContext(r) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(c); err != nil { log.Errorf(c, "failed to get default GCS bucket name: %v", err) return } } hc := &http.Client{ Transport: &oauth2.Transport{ Source: google.AppEngineTokenSource(c, storage.ScopeFullControl), // Note that the App Engine urlfetch service has a limit of 10MB uploads and // 32MB downloads. // See https://cloud.google.com/appengine/docs/go/urlfetch/#Go_Quotas_and_limits // for more information. Base: &urlfetch.Transport{Context: c}, }, } ctx := cloud.NewContext(appengine.AppID(c), hc) w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(c)) fmt.Fprintf(w, "Using bucket name: %v\n\n", bucket) d := &demo{ c: c, w: w, ctx: ctx, } n := "demo-testfile-go" d.createFile(n) d.readFile(n) d.copyFile(n) d.statFile(n) d.createListFiles() d.listBucket() d.listBucketDirMode() d.defaultACL() d.putDefaultACLRule() d.deleteDefaultACLRule() d.bucketACL() d.putBucketACLRule() d.deleteBucketACLRule() d.acl(n) d.putACLRule(n) d.deleteACLRule(n) d.deleteFiles() if d.failed { io.WriteString(w, "\nDemo failed.\n") } else { io.WriteString(w, "\nDemo succeeded.\n") } }
// Run starts a query for log records, which contain request and application // level log information. func (params *Query) Run(c appengine.Context) *Result { req, err := makeRequest(params, c.FullyQualifiedAppID(), appengine.VersionID(c)) return &Result{ context: c, request: req, err: err, } }
func handler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } ctx := appengine.NewContext(r) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(ctx); err != nil { log.Errorf(ctx, "error", err) return } } client, err := storage.NewClient(ctx) if err != nil { log.Errorf(ctx, "error", err) return } defer client.Close() w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(ctx)) fmt.Fprintf(w, "Using bucket name: %v\n\n", bucket) d := &demo{ w: w, ctx: ctx, client: client, bucket: client.Bucket(bucket), } n := "demo-testfile-go" d.makeF(n) d.rFile(n) d.cFile(n) d.statFile(n) d.createListFiles() d.listBucket() d.listBucketDirMode() d.defaultACL() d.putDefaultACLRule() d.deleteDefaultACLRule() d.bucketACL() d.putBucketACLRule() d.deleteBucketACLRule() d.acl(n) d.putACLRule(n) d.deleteACLRule(n) d.deleteFiles() if d.failed { io.WriteString(w, "\nDemo failed.\n") } else { io.WriteString(w, "\nDemo succeeded.\n") } }
func connectToDB(ctx context.Context) { version := appengine.VersionID(ctx) versionID := strings.Split(version, ".") log.Infof(ctx, "Current serving app version: %s", versionID[0]) if versionID[0] == "live" { DB_STRING = os.Getenv("LIVE_DB") } else { DB_STRING = os.Getenv("TEST_DB") } log.Infof(ctx, "connecting to DB with string %s", DB_STRING) db = backend.SqlInit(DB_STRING) }
// handler is the main demo entry point that calls the GCS operations. func handler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } c := appengine.NewContext(r) bucketName, err := file.DefaultBucketName(c) if err != nil { c.Errorf("failed to get default GCS bucket name: %v", err) return } config := google.NewAppEngineConfig(c, storage.ScopeFullControl) ctx := cloud.NewContext(appengine.AppID(c), &http.Client{Transport: config.NewTransport()}) w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(c)) fmt.Fprintf(w, "Using bucket name: %v\n\n", bucketName) d := &demo{ c: c, w: w, ctx: ctx, bucket: bucketName, } n := "demo-testfile-go" d.createFile(n) d.readFile(n) d.copyFile(n) d.statFile(n) d.createListFiles() d.listBucket() d.listBucketDirMode() d.defaultACL() d.putDefaultACLRule() d.deleteDefaultACLRule() d.bucketACL() d.putBucketACLRule() d.deleteBucketACLRule() d.acl(n) d.putACLRule(n) d.deleteACLRule(n) d.deleteFiles() if d.failed { io.WriteString(w, "\nDemo failed.\n") } else { io.WriteString(w, "\nDemo succeeded.\n") } }
//Diagnostics shows a bunch of app engine's information for the app/project //useful for figuring out which version of an app is serving func Diagnostics(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) out := map[string]interface{}{ "App ID": appengine.AppID(c), "Instance ID": appengine.InstanceID(), "Default Version Hostname": appengine.DefaultVersionHostname(c), "Version ID": appengine.VersionID(c), "Datacenter": appengine.Datacenter(c), "Module Name": appengine.ModuleName(c), "Server Software": appengine.ServerSoftware(), } templates.Load(w, "diagnostics", out) return }
// Run starts a query for log records, which contain request and application // level log information. func (params *Query) Run(c appengine.Context) *Result { req := &pb.LogReadRequest{} appId := c.FullyQualifiedAppID() req.AppId = &appId if !params.StartTime.IsZero() { req.StartTime = proto.Int64(params.StartTime.UnixNano() / 1e3) } if !params.EndTime.IsZero() { req.EndTime = proto.Int64(params.EndTime.UnixNano() / 1e3) } if params.Offset != nil { var offset pb.LogOffset if err := proto.Unmarshal(params.Offset, &offset); err != nil { return &Result{context: c, err: fmt.Errorf("bad Offset: %v", err)} } req.Offset = &offset } if params.Incomplete { req.IncludeIncomplete = ¶ms.Incomplete } if params.AppLogs { req.IncludeAppLogs = ¶ms.AppLogs } if params.ApplyMinLevel { req.MinimumLogLevel = proto.Int32(int32(params.MinLevel)) } if params.Versions == nil { // If no versions were specified, default to the major version // used by this app. versionID := appengine.VersionID(c) if i := strings.Index(versionID, "."); i >= 0 { versionID = versionID[:i] } req.VersionId = []string{versionID} } else { req.VersionId = params.Versions } if params.RequestIDs != nil { ids := make([][]byte, len(params.RequestIDs)) for i, v := range params.RequestIDs { ids[i] = []byte(v) } req.RequestId = ids } return &Result{context: c, request: req} }
// handleListBucket lists the contents of the default bucket func handleListBucket(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(ctx); err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } } client, err := storage.NewClient(ctx) if err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } defer client.Close() w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(ctx)) fmt.Fprintf(w, "Using bucket name: %v\n\n", bucket) writer := client.Bucket(bucket).Object("foo").NewWriter(ctx) _, err = writer.Write([]byte("Yoho!")) if err != nil { log.Errorf(ctx, "Error while creating file") } log.Infof(ctx, "Created a new file. So yay!") reader, err := client.Bucket(bucket).Object("foo").NewReader(ctx) if err != nil { log.Errorf(ctx, "Error creating reader for object from Bucket. %s", err) } content, err := ioutil.ReadAll(reader) if err != nil { log.Errorf(ctx, "Error reading object") } fmt.Fprintf(w, "Got: %s", &content) }
func handler(res http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(res, req) return } //[START get_default_bucket] ctx := appengine.NewContext(res) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(ctx); err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } } //[END get_default_bucket] //Make Client client, err := storage.NewClient(ctx) if err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } defer client.Close() //Construct our object to interface with the cloud storage. res.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(res, "Demo GCS Application running from Version: %v\n", appengine.VersionID(ctx)) fmt.Fprintf(res, "Using bucket name: %v\n\n", bucket) d := &demo{ w: res, //The response writer so it knows what to write to later if retrieving. ctx: ctx, //Current Context client: client, //Current Client bucket: client.Bucket(bucket), //Relevant Bucket, bucket is a global string that contains the default bucket location. } //The name of the file we will be creating. n := "demo-testfile-go" //Create the File and store in google cloud. d.createFile(n) d.listBucket() }
func handler(res http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(res, req) return } ctx := appengine.NewContext(res) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(ctx); err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } } //[END get_default_bucket] //Make Client client, err := storage.NewClient(ctx) if err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } defer client.Close() res.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(res, "Demo GCS Application running from Version: %v\n", appengine.VersionID(ctx)) fmt.Fprintf(res, "Using bucket name: %v\n\n", bucket) d := &demo{ w: res, ctx: ctx, client: client, bucket: client.Bucket(bucket), } n := "demo-testfile-go" d.createFile(n) d.listBucket() }
func storeImage(rw http.ResponseWriter, req *http.Request) { // Appengine var c appengine.Context // Google Cloud Storage authentication var cc gcscontext.Context // Google Cloud Storage bucket name var bucketName string = "" // Google Cloud Storage client var client *storage.Client // Google Cloud Storage bucket var bucketHandle *storage.BucketHandle // User uploaded image file name var fileName string = uuid.New() // Transform user uploaded image to a thumbnail file name var fileNameThumbnail string = uuid.New() // User uploaded image file type var contentType string = "" // User uploaded image file raw data var b []byte // Google Cloud Storage file writer var wc *storage.Writer = nil // Error var err error = nil // Result, 0: success, 1: failed var r int = http.StatusCreated // Set response in the end defer func() { // Return status. WriteHeader() must be called before call to Write if r == http.StatusCreated { // Changing the header after a call to WriteHeader (or Write) has no effect. // rw.Header().Set("Location", req.URL.String()+"/"+cKey.Encode()) rw.Header().Set("Location", "http://"+bucketName+".storage.googleapis.com/"+fileName) rw.Header().Set("X-Thumbnail", "http://"+bucketName+".storage.googleapis.com/"+fileNameThumbnail) rw.WriteHeader(r) } else { http.Error(rw, http.StatusText(r), r) } }() // To log information in Google APP Engine console c = appengine.NewContext(req) // Get data from body b, err = ioutil.ReadAll(req.Body) if err != nil { c.Errorf("%s in reading body", err) r = http.StatusInternalServerError return } c.Infof("Body length %d bytes, read %d bytes", req.ContentLength, len(b)) // Determine filename extension from content type contentType = req.Header["Content-Type"][0] switch contentType { case "image/jpeg": fileName += ".jpg" fileNameThumbnail += ".jpg" default: c.Errorf("Unknown or unsupported content type '%s'. Valid: image/jpeg", contentType) r = http.StatusBadRequest return } c.Infof("Content type %s is received, %s is detected.", contentType, http.DetectContentType(b)) // Prepare Google Cloud Storage authentication cc = gcsappengine.NewContext(req) if client, err = storage.NewClient(cc); err != nil { c.Errorf("%s in initializing a GCS client", err) r = http.StatusInternalServerError return } defer client.Close() // Get default bucket if bucketName, err = gcsfile.DefaultBucketName(cc); err != nil { c.Errorf("%s in getting default GCS bucket name", err) r = http.StatusInternalServerError return } bucketHandle = client.Bucket(bucketName) c.Infof("APP Engine Version: %s", gcsappengine.VersionID(cc)) c.Infof("Using bucket name: %s", bucketName) // Change default object ACLs if err = bucketHandle.DefaultObjectACL().Set(cc, storage.AllUsers, storage.RoleReader); err != nil { c.Errorf("%v in saving default object ACL rule for bucket %q", err, bucketName) r = http.StatusInternalServerError return } // Store rotated image in Google Cloud Storage var in *bytes.Reader = bytes.NewReader(b) var x *exif.Exif = nil var orientation *tiff.Tag = nil var beforeImage image.Image var afterImage *image.NRGBA = nil // Read EXIF if _, err = in.Seek(0, 0); err != nil { c.Errorf("%s in moving the reader offset to the beginning in order to read EXIF", err) return } if x, err = exif.Decode(in); err != nil { c.Errorf("%s in decoding JPEG image", err) return } // Get Orientation if orientation, err = x.Get(exif.Orientation); err != nil { c.Warningf("%s in getting orientation from EXIF", err) return } c.Debugf("Orientation %s", orientation.String()) // Open image if _, err = in.Seek(0, 0); err != nil { c.Errorf("%s in moving the reader offset to the beginning in order to read EXIF", err) return } if beforeImage, err = imaging.Decode(in); err != nil { c.Errorf("%s in opening image %s", err) return } switch orientation.String() { case "1": afterImage = beforeImage.(*image.NRGBA) case "2": afterImage = imaging.FlipH(beforeImage) case "3": afterImage = imaging.Rotate180(beforeImage) case "4": afterImage = imaging.FlipV(beforeImage) case "5": afterImage = imaging.Transverse(beforeImage) case "6": afterImage = imaging.Rotate270(beforeImage) case "7": afterImage = imaging.Transpose(beforeImage) case "8": afterImage = imaging.Rotate90(beforeImage) } // Save rotated image wc = bucketHandle.Object(fileName).NewWriter(cc) wc.ContentType = contentType if err = imaging.Encode(wc, afterImage, imaging.JPEG); err != nil { c.Errorf("%s in saving rotated image", err) return } if err = wc.Close(); err != nil { c.Errorf("CreateFile: unable to close bucket %q, file %q: %v", bucketName, fileName, err) r = 1 return } wc = nil // Make thumbnail if afterImage.Rect.Dx() > afterImage.Rect.Dy() { afterImage = imaging.Resize(afterImage, 1920, 0, imaging.Lanczos) } else { afterImage = imaging.Resize(afterImage, 0, 1920, imaging.Lanczos) } // Save thumbnail wc = bucketHandle.Object(fileNameThumbnail).NewWriter(cc) wc.ContentType = contentType if imaging.Encode(wc, afterImage, imaging.JPEG); err != nil { c.Errorf("%s in saving image thumbnail", err) return } if err = wc.Close(); err != nil { c.Errorf("CreateFileThumbnail: unable to close bucket %q, file %q: %v", bucketName, fileNameThumbnail, err) r = 1 return } c.Infof("/%v/%v, /%v/%v created", bucketName, fileName, bucketName, fileNameThumbnail) }
func storeImage(rw http.ResponseWriter, req *http.Request) { // Appengine var c appengine.Context // Google Cloud Storage authentication var cc gcscontext.Context // Google Cloud Storage bucket name var bucket string = "" // User uploaded image file name var fileName string = uuid.New() // User uploaded image file type var contentType string = "" // User uploaded image file raw data var b []byte // Result, 0: success, 1: failed var r int = 0 // Set response in the end defer func() { // Return status. WriteHeader() must be called before call to Write if r == 0 { // Changing the header after a call to WriteHeader (or Write) has no effect. // rw.Header().Set("Location", req.URL.String()+"/"+cKey.Encode()) rw.Header().Set("Location", "http://"+bucket+".storage.googleapis.com/"+fileName) rw.WriteHeader(http.StatusCreated) } else { http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) } }() // To log information in Google APP Engine console c = appengine.NewContext(req) // Get data from body b, err := ioutil.ReadAll(req.Body) if err != nil { c.Errorf("%s in reading body", err) r = 1 return } c.Infof("Body length %d bytes, read %d bytes", req.ContentLength, len(b)) // Determine filename extension from content type contentType = req.Header["Content-Type"][0] switch contentType { case "image/jpeg": fileName += ".jpg" default: c.Errorf("Unknown or unsupported content type '%s'. Valid: image/jpeg", contentType) r = 1 return } c.Infof("Content type %s is received, %s is detected.", contentType, http.DetectContentType(b)) // Get default bucket name cc = gcsappengine.NewContext(req) if bucket, err = gcsfile.DefaultBucketName(cc); err != nil { c.Errorf("%s in getting default GCS bucket name", err) r = 1 return } c.Infof("APP Engine Version: %s", gcsappengine.VersionID(cc)) c.Infof("Using bucket name: %s", bucket) // Prepare Google Cloud Storage authentication hc := &http.Client{ Transport: &oauth2.Transport{ Source: google.AppEngineTokenSource(cc, storage.ScopeFullControl), // Note that the App Engine urlfetch service has a limit of 10MB uploads and // 32MB downloads. // See https://cloud.google.com/appengine/docs/go/urlfetch/#Go_Quotas_and_limits // for more information. Base: &gcsurlfetch.Transport{Context: cc}, }, } ctx := cloud.NewContext(gcsappengine.AppID(cc), hc) // Change default object ACLs err = storage.PutDefaultACLRule(ctx, bucket, "allUsers", storage.RoleReader) // err = storage.PutACLRule(ctx, bucket, fileName, "allUsers", storage.RoleReader) if err != nil { c.Errorf("%v in saving ACL rule for bucket %q", err, bucket) return } // Store file in Google Cloud Storage wc := storage.NewWriter(ctx, bucket, fileName) wc.ContentType = contentType // wc.Metadata = map[string]string{ // "x-goog-meta-foo": "foo", // "x-goog-meta-bar": "bar", // } if _, err := wc.Write(b); err != nil { c.Errorf("CreateFile: unable to write data to bucket %q, file %q: %v", bucket, fileName, err) r = 1 return } if err := wc.Close(); err != nil { c.Errorf("CreateFile: unable to close bucket %q, file %q: %v", bucket, fileName, err) r = 1 return } c.Infof("/%v/%v\n created", bucket, fileName) }
// Todo: When c==nil we are in a non-appengine environment. // We still want to return at least ii.PureHostname func GetByContext(c context.Context) *Instance { tstart := time.Now() if !ii.LastUpdated.IsZero() { age := tstart.Sub(ii.LastUpdated) if age < 200*time.Millisecond { aelog.Infof(c, "instance info update too recently: %v, skipping.\n", age) return ii } if age < 1*time.Hour { if len(ii.Hostname) > 2 { return ii } } aelog.Infof(c, "instance info update too old: %v, recomputing.\n", age) } ii.ModuleName = appengine.ModuleName(c) ii.InstanceID = appengine.InstanceID() ii.VersionFull = appengine.VersionID(c) majorMinor := strings.Split(ii.VersionFull, ".") if len(majorMinor) != 2 { panic("we need a version string of format X.Y") } ii.VersionMajor = majorMinor[0] ii.VersionMinor = majorMinor[1] var err = errors.New("dummy creation error message") ii.NumInstances, err = module.NumInstances(c, ii.ModuleName, ii.VersionFull) if err != nil { // this never works with version full // we do not log this - but try version major err = nil if !util_appengine.IsLocalEnviron() { ii.NumInstances, err = module.NumInstances(c, ii.ModuleName, ii.VersionMajor) if err != nil { eStr := err.Error() eCmp1, eCmp2, eCmp3 := "API error", "INVALID_VERSION)", "Could not find the given version" if strings.Contains(eStr, eCmp1) && strings.Contains(eStr, eCmp2) && strings.Contains(eStr, eCmp3) { aelog.Infof(c, "get num instances works only live and without autoscale; %v", err) } else { aelog.Errorf(c, "get num instances error; %v", err) } } } } // in auto scaling, google reports "zero" - which can not be true // we assume at least 1 if ii.NumInstances == 0 { ii.NumInstances = 1 } // http://[0-2].1.default.libertarian-islands.appspot.com/instance-info ii.Hostname, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "") if err != nil { aelog.Errorf(c, "ModuleHostname1: %v", err) } ii.PureHostname = appengine.DefaultVersionHostname(c) if !appengine.IsDevAppServer() { ii.HostnameInst0, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "0") if err != nil && (err.Error() == autoScalingErr1 || err.Error() == autoScalingErr2) { aelog.Infof(c, "inst 0: "+autoScalingErrMsg) err = nil } if err != nil { aelog.Errorf(c, "ModuleHostname2: %v", err) } ii.HostnameInst1, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "1") if err != nil && (err.Error() == autoScalingErr1 || err.Error() == autoScalingErr2) { aelog.Infof(c, "inst 1: "+autoScalingErrMsg) err = nil } if err != nil { aelog.Errorf(c, "ModuleHostname3: %v", err) } ii.HostnameMod02, err = appengine.ModuleHostname(c, "mod02", "", "") if err != nil { aelog.Infof(c, "ModuleHostname4: %v", err) } } ii.LastUpdated = time.Now() aelog.Infof(c, "collectInfo() completed, %v - %v - %v - %v - %v, took %v", stringspb.Ellipsoider(ii.InstanceID, 4), ii.VersionMajor, ii.ModuleName, ii.Hostname, ii.PureHostname, time.Now().Sub(tstart)) return ii }
// handler is the main demo entry point that calls the GCS operations. func handler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } //[START get_default_bucket] ctx := appengine.NewContext(r) if bucket == "" { var err error if bucket, err = file.DefaultBucketName(ctx); err != nil { log.Errorf(ctx, "failed to get default GCS bucket name: %v", err) return } } //[END get_default_bucket] client, err := storage.NewClient(ctx) if err != nil { log.Errorf(ctx, "failed to create client: %v", err) return } defer client.Close() w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(ctx)) fmt.Fprintf(w, "Using bucket name: %v\n\n", bucket) buf := &bytes.Buffer{} d := &demo{ w: buf, ctx: ctx, client: client, bucket: client.Bucket(bucket), } n := "demo-testfile-go" d.createFile(n) d.readFile(n) d.copyFile(n) d.statFile(n) d.createListFiles() d.listBucket() d.listBucketDirMode() d.defaultACL() d.putDefaultACLRule() d.deleteDefaultACLRule() d.bucketACL() d.putBucketACLRule() d.deleteBucketACLRule() d.acl(n) d.putACLRule(n) d.deleteACLRule(n) d.deleteFiles() if d.failed { w.WriteHeader(http.StatusInternalServerError) buf.WriteTo(w) fmt.Fprintf(w, "\nDemo failed.\n") } else { w.WriteHeader(http.StatusOK) buf.WriteTo(w) fmt.Fprintf(w, "\nDemo succeeded.\n") } }
func (g giImpl) VersionID() string { return appengine.VersionID(g.aeCtx) }