github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/cf/commands/curl.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	. "github.com/cloudfoundry/cli/cf/i18n"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"github.com/cloudfoundry/cli/cf/api"
    14  	"github.com/cloudfoundry/cli/cf/command_metadata"
    15  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    16  	"github.com/cloudfoundry/cli/cf/flag_helpers"
    17  	"github.com/cloudfoundry/cli/cf/requirements"
    18  	"github.com/cloudfoundry/cli/cf/terminal"
    19  	"github.com/cloudfoundry/cli/cf/trace"
    20  	"github.com/codegangsta/cli"
    21  )
    22  
    23  type Curl struct {
    24  	ui       terminal.UI
    25  	config   core_config.Reader
    26  	curlRepo api.CurlRepository
    27  }
    28  
    29  func NewCurl(ui terminal.UI, config core_config.Reader, curlRepo api.CurlRepository) (cmd *Curl) {
    30  	cmd = new(Curl)
    31  	cmd.ui = ui
    32  	cmd.config = config
    33  	cmd.curlRepo = curlRepo
    34  	return
    35  }
    36  
    37  func (cmd *Curl) Metadata() command_metadata.CommandMetadata {
    38  	return command_metadata.CommandMetadata{
    39  		Name:        "curl",
    40  		Description: T("Executes a raw request, content-type set to application/json by default"),
    41  		Usage:       T("CF_NAME curl PATH [-iv] [-X METHOD] [-H HEADER] [-d DATA] [--output FILE]"),
    42  		Flags: []cli.Flag{
    43  			cli.BoolFlag{Name: "i", Usage: T("Include response headers in the output")},
    44  			cli.BoolFlag{Name: "v", Usage: T("Enable CF_TRACE output for all requests and responses")},
    45  			cli.StringFlag{Name: "X", Value: "GET", Usage: T("HTTP method (GET,POST,PUT,DELETE,etc)")},
    46  			flag_helpers.NewStringSliceFlag("H", T("Custom headers to include in the request, flag can be specified multiple times")),
    47  			flag_helpers.NewStringFlag("d", T("HTTP data to include in the request body")),
    48  			flag_helpers.NewStringFlag("output", T("Write curl body to FILE instead of stdout")),
    49  		},
    50  	}
    51  }
    52  
    53  func (cmd *Curl) GetRequirements(requirementsFactory requirements.Factory, c *cli.Context) (reqs []requirements.Requirement, err error) {
    54  	if len(c.Args()) != 1 {
    55  		err = errors.New(T("Incorrect number of arguments"))
    56  		cmd.ui.FailWithUsage(c)
    57  		return
    58  	}
    59  
    60  	reqs = []requirements.Requirement{
    61  		requirementsFactory.NewLoginRequirement(),
    62  	}
    63  	return
    64  }
    65  
    66  func (cmd *Curl) Run(c *cli.Context) {
    67  	path := c.Args()[0]
    68  	method := c.String("X")
    69  	headers := c.StringSlice("H")
    70  	body := c.String("d")
    71  	verbose := c.Bool("v")
    72  
    73  	reqHeader := strings.Join(headers, "\n")
    74  
    75  	if verbose {
    76  		trace.EnableTrace()
    77  	}
    78  
    79  	responseHeader, responseBody, apiErr := cmd.curlRepo.Request(method, path, reqHeader, body)
    80  	if apiErr != nil {
    81  		cmd.ui.Failed(T("Error creating request:\n{{.Err}}", map[string]interface{}{"Err": apiErr.Error()}))
    82  	}
    83  
    84  	if verbose {
    85  		return
    86  	}
    87  
    88  	if c.Bool("i") {
    89  		cmd.ui.Say(responseHeader)
    90  	}
    91  
    92  	if c.String("output") != "" {
    93  		err := cmd.writeToFile(responseBody, c.String("output"))
    94  		if err != nil {
    95  			cmd.ui.Failed(T("Error creating request:\n{{.Err}}", map[string]interface{}{"Err": err}))
    96  		}
    97  	} else {
    98  		if strings.Contains(responseHeader, "application/json") {
    99  			buffer := bytes.Buffer{}
   100  			err := json.Indent(&buffer, []byte(responseBody), "", "   ")
   101  			if err == nil {
   102  				responseBody = buffer.String()
   103  			}
   104  		}
   105  
   106  		cmd.ui.Say(responseBody)
   107  	}
   108  	return
   109  }
   110  
   111  func (cmd Curl) writeToFile(responseBody, filePath string) (err error) {
   112  	if _, err = os.Stat(filePath); os.IsNotExist(err) {
   113  		err = os.MkdirAll(filepath.Dir(filePath), 0755)
   114  	}
   115  
   116  	if err != nil {
   117  		return
   118  	}
   119  
   120  	return ioutil.WriteFile(filePath, []byte(responseBody), 0644)
   121  }