Skip to content

Instantly share code, notes, and snippets.

@ppanyukov
Created March 30, 2016 13:11
Show Gist options
  • Save ppanyukov/35ebd99f457c000f667269d3c0c2acd5 to your computer and use it in GitHub Desktop.
Save ppanyukov/35ebd99f457c000f667269d3c0c2acd5 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"log"
"net/http"
"os"
"strings"
"time"
"github.com/ppanyukov/azure-sdk-for-go/storage"
)
// BlobStorageHandler implements http.Handler interface to
// list contents of Azure blob storage as folders and files.
type BlobStorageHandler struct {
accountName string
accountKey string
accountContainer string
client storage.BlobStorageClient
}
// NewBlobStorageHandler creates new instance of the blob storage HTTP handler.
func NewBlobStorageHandler(accountName, accountKey, accountContainer string) (*BlobStorageHandler, error) {
client, err := storage.NewBasicClient(accountName, accountKey)
if err != nil {
return nil, err
}
return &BlobStorageHandler{
accountName: accountName,
accountKey: accountKey,
accountContainer: accountContainer,
client: client.GetBlobService(),
}, nil
}
// ServeHTTP implements the HTTP handler to list contents of the blob store.
func (server *BlobStorageHandler) ServeHTTP(w http.ResponseWriter, request *http.Request) {
const delimiter = "/"
// Add leading and trailing slash if it's not present already.
url := request.URL.String()
parentFolder := url
if !strings.HasSuffix(parentFolder, delimiter) {
parentFolder = parentFolder + delimiter
}
if !strings.HasPrefix(parentFolder, delimiter) {
parentFolder = delimiter + parentFolder
}
blobParams := storage.ListBlobsParameters{
Delimiter: delimiter,
Prefix: parentFolder,
}
listBlobResponse, err := server.client.ListBlobs(server.accountContainer, blobParams)
if err != nil {
w.WriteHeader(500)
w.Header().Add("Content-Type", "text/plain")
fmt.Fprintf(w, "ERROR: %v\n", err)
return
}
w.Header().Add("Content-Type", "text/plain")
fmt.Fprintf(w, "%s:\n", url)
fmt.Fprint(w, "----------------\n")
for _, folder := range listBlobResponse.BlobPrefixes {
folderWithoutParent := strings.TrimPrefix(folder, parentFolder)
fmt.Fprintf(w, "d %s\n", folderWithoutParent)
}
for _, blob := range listBlobResponse.Blobs {
blobWithoutParent := strings.TrimPrefix(blob.Name, parentFolder)
fmt.Fprintf(w, "- %s\n", blobWithoutParent)
}
}
func main() {
const port = ":8080"
const usage = "Need these environmental variables: ACCOUNT_NAME, ACCOUNT_KEY, ACCOUNT_CONTAINER."
accountName := os.Getenv("ACCOUNT_NAME")
accountKey := os.Getenv("ACCOUNT_KEY")
accountContainer := os.Getenv("ACCOUNT_CONTAINER")
if accountName == "" || accountKey == "" || accountContainer == "" {
fmt.Println(usage)
os.Exit(1)
}
blobStorageHandler, err := NewBlobStorageHandler(accountName, accountKey, accountContainer)
if err != nil {
fmt.Println("ERROR:", err)
os.Exit(1)
}
fmt.Println("Will listen on port", port)
s := &http.Server{
Addr: port,
Handler: blobStorageHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServeTLS("/Users/philip/vso/philip-hacky-hacks/docker/artifactory-nginx-proxy/certs/domain.crt", "/Users/philip/vso/philip-hacky-hacks/docker/artifactory-nginx-proxy/certs/domain.key"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment