Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(75)

Delta Between Two Patch Sets: state/apiserver/charms.go

Issue 67750045: Implement the get charm file API.
Left Patch Set: Implement the get charm file API. Created 11 years, 1 month ago
Right Patch Set: Implement the get charm file API. Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « state/apiserver/apiserver.go ('k') | state/apiserver/charms_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2013 Canonical Ltd. 1 // Copyright 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details. 2 // Licensed under the AGPLv3, see LICENCE file for details.
3 3
4 package apiserver 4 package apiserver
5 5
6 import ( 6 import (
7 "archive/zip" 7 "archive/zip"
8 "crypto/sha256" 8 "crypto/sha256"
9 "encoding/base64" 9 "encoding/base64"
10 "encoding/hex" 10 "encoding/hex"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 } 115 }
116 h.sendJSON(w, http.StatusOK, &params.CharmsResponse{Files: files}) 116 h.sendJSON(w, http.StatusOK, &params.CharmsResponse{Files: files})
117 } 117 }
118 118
119 // fileSender returns a zipContentsSenderFunc which is responsible of sending 119 // fileSender returns a zipContentsSenderFunc which is responsible of sending
120 // the contents of filePath included in the given zip. 120 // the contents of filePath included in the given zip.
121 // A 404 page not found is returned if path does not exist in the zip. 121 // A 404 page not found is returned if path does not exist in the zip.
122 // A 403 forbidden error is returned if path points to a directory. 122 // A 403 forbidden error is returned if path points to a directory.
123 func (h *charmsHandler) fileSender(filePath string) zipContentsSenderFunc { 123 func (h *charmsHandler) fileSender(filePath string) zipContentsSenderFunc {
124 return func(w http.ResponseWriter, r *http.Request, reader *zip.ReadClos er) { 124 return func(w http.ResponseWriter, r *http.Request, reader *zip.ReadClos er) {
125 for _, file := range reader.File { 125 for _, file := range reader.File {
dimitern 2014/02/25 17:40:03 gofmt again?
frankban 2014/02/26 09:34:28 Done, and it seems already ok.
126 if h.fixPath(file.Name) != filePath { 126 if h.fixPath(file.Name) != filePath {
127 continue 127 continue
128 } 128 }
129 fileInfo := file.FileInfo() 129 fileInfo := file.FileInfo()
130 if fileInfo.IsDir() { 130 if fileInfo.IsDir() {
131 http.Error(w, "directory listing not allowed", h ttp.StatusForbidden) 131 http.Error(w, "directory listing not allowed", h ttp.StatusForbidden)
132 return 132 return
133 } 133 }
134 if contents, err := file.Open(); err != nil { 134 if contents, err := file.Open(); err != nil {
135 http.Error( 135 http.Error(
136 w, fmt.Sprintf("unable to read file %q: %v", filePath, err), 136 w, fmt.Sprintf("unable to read file %q: %v", filePath, err),
137 http.StatusInternalServerError) 137 http.StatusInternalServerError)
138 return
138 } else { 139 } else {
dimitern 2014/02/25 17:40:03 Instead of else, you could just return in the if b
frankban 2014/02/26 09:34:28 We need contents in the scope, that's why I used e
dimitern 2014/02/26 10:01:03 Then you can just move the assignment out of the i
139 defer contents.Close() 140 defer contents.Close()
140 ctype := mime.TypeByExtension(filepath.Ext(fileP ath)) 141 ctype := mime.TypeByExtension(filepath.Ext(fileP ath))
141 if ctype != "" { 142 if ctype != "" {
142 w.Header().Set("Content-Type", ctype) 143 w.Header().Set("Content-Type", ctype)
143 } 144 }
144 w.Header().Set("Content-Length", strconv.FormatI nt(fileInfo.Size(), 10)) 145 w.Header().Set("Content-Length", strconv.FormatI nt(fileInfo.Size(), 10))
145 w.WriteHeader(http.StatusOK) 146 w.WriteHeader(http.StatusOK)
146 io.Copy(w, contents) 147 io.Copy(w, contents)
147 } 148 }
148 return 149 return
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 502 }
502 503
503 // And finally, update state. 504 // And finally, update state.
504 _, err = h.state.UpdateUploadedCharm(archive, curl, bundleURL, bundleSHA 256) 505 _, err = h.state.UpdateUploadedCharm(archive, curl, bundleURL, bundleSHA 256)
505 if err != nil { 506 if err != nil {
506 return errgo.Annotate(err, "cannot update uploaded charm in stat e") 507 return errgo.Annotate(err, "cannot update uploaded charm in stat e")
507 } 508 }
508 return nil 509 return nil
509 } 510 }
510 511
511 // processGet handles a charm file download GET request after authentication. 512 // processGet handles a charm file GET request after authentication.
dimitern 2014/02/25 17:40:03 s/download//
frankban 2014/02/26 09:34:28 Done.
512 // It returns the bundle path, the requested file path (if any) and an error. 513 // It returns the bundle path, the requested file path (if any) and an error.
513 func (h *charmsHandler) processGet(r *http.Request) (string, string, error) { 514 func (h *charmsHandler) processGet(r *http.Request) (string, string, error) {
514 query := r.URL.Query() 515 query := r.URL.Query()
515 516
516 // Retrieve and validate query parameters. 517 // Retrieve and validate query parameters.
517 curl := query.Get("url") 518 curl := query.Get("url")
518 if curl == "" { 519 if curl == "" {
519 return "", "", fmt.Errorf("expected url=CharmURL query argument" ) 520 return "", "", fmt.Errorf("expected url=CharmURL query argument" )
520 } 521 }
521 var filePath string 522 var filePath string
(...skipping 14 matching lines...) Expand all
536 if err = h.downloadCharm(name, charmArchivePath); err != nil { 537 if err = h.downloadCharm(name, charmArchivePath); err != nil {
537 return "", "", fmt.Errorf("unable to retrieve and save t he charm: %v", err) 538 return "", "", fmt.Errorf("unable to retrieve and save t he charm: %v", err)
538 } 539 }
539 } else if err != nil { 540 } else if err != nil {
540 return "", "", fmt.Errorf("cannot access the charms cache: %v", err) 541 return "", "", fmt.Errorf("cannot access the charms cache: %v", err)
541 } 542 }
542 return charmArchivePath, filePath, nil 543 return charmArchivePath, filePath, nil
543 } 544 }
544 545
545 // downloadCharm downloads the given charm name from the provider storage and 546 // downloadCharm downloads the given charm name from the provider storage and
546 // save the corresponding zip archive to the given charmArchivePath. 547 // saves the corresponding zip archive to the given charmArchivePath.
dimitern 2014/02/25 17:40:03 s/save/saves/
frankban 2014/02/26 09:34:28 Done.
547 func (h *charmsHandler) downloadCharm(name, charmArchivePath string) error { 548 func (h *charmsHandler) downloadCharm(name, charmArchivePath string) error {
548 // Get the provider storage. 549 // Get the provider storage.
549 storage, err := envtesting.GetEnvironStorage(h.state) 550 storage, err := envtesting.GetEnvironStorage(h.state)
550 if err != nil { 551 if err != nil {
551 return errgo.Annotate(err, "cannot access provider storage") 552 return errgo.Annotate(err, "cannot access provider storage")
552 } 553 }
553 554
554 // Use the storage to retrieve and save the charm archive. 555 // Use the storage to retrieve and save the charm archive.
555 reader, err := storage.Get(name) 556 reader, err := storage.Get(name)
556 if err != nil { 557 if err != nil {
(...skipping 13 matching lines...) Expand all
570 return errgo.Annotate(err, "cannot create the charms cache") 571 return errgo.Annotate(err, "cannot create the charms cache")
571 } 572 }
572 tempCharmArchive, err := ioutil.TempFile(cacheDir, "charm") 573 tempCharmArchive, err := ioutil.TempFile(cacheDir, "charm")
573 if err != nil { 574 if err != nil {
574 return errgo.Annotate(err, "cannot create charm archive temp fil e") 575 return errgo.Annotate(err, "cannot create charm archive temp fil e")
575 } 576 }
576 defer tempCharmArchive.Close() 577 defer tempCharmArchive.Close()
577 if err = ioutil.WriteFile(tempCharmArchive.Name(), data, 0644); err != n il { 578 if err = ioutil.WriteFile(tempCharmArchive.Name(), data, 0644); err != n il {
578 return errgo.Annotate(err, "error processing charm archive downl oad") 579 return errgo.Annotate(err, "error processing charm archive downl oad")
579 } 580 }
580 if err = os.Rename(tempCharmArchive.Name(), charmArchivePath); err != ni l { 581 if err = os.Rename(tempCharmArchive.Name(), charmArchivePath); err != ni l {
dimitern 2014/02/25 17:40:03 In this case I think you should defer os.Remove(te
frankban 2014/02/26 09:34:28 Good catch, fixed.
582 defer os.Remove(tempCharmArchive.Name())
581 return errgo.Annotate(err, "error renaming the charm archive") 583 return errgo.Annotate(err, "error renaming the charm archive")
582 } 584 }
583 return nil 585 return nil
584 } 586 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b