Documentationcurrent version
Help us improve the docs by fixing typos and proposing enhancements.


Action "network.http"

Perform an HTTP request. Internaly, the action requires the presence of the curl command.


  • data (string)
    The decoded data is type is provided or detected.
  • body (string)
    The HTTP response body.
  • headers ([string])
    The HTTP response headers.
  • http_version ([string])
    The HTTP response http_version, eg 'HTTP/1.1'.
  • status_code (string)
    The HTTP response status code.
  • status_message (string)
    The HTTP response status message.
  • type (string)
    The format type if provided or detected, possible values is only "json" for now.


The error.code reflects the native curl errors code. You can get a list of them with man 3 libcurl-errors. For example:

try {
    url: "http://2222:localhost"
} catch (err) {
  assert(err.code, 'CURLE_URL_MALFORMAT')
  assert(err.message, 'CURLE_URL_MALFORMAT: the curl command exited with code `3`.')

Schema definitions

definitions =
    type: 'object'
        type: 'array'
          type: 'string'
        description: '''
        Extra cookies to include in the request when sending HTTP to a server.
        type: ['array', 'boolean', 'null', 'number', 'object', 'string']
        description: '''
        The request HTTP body associated with "POST" and "PUT" requests. The
        `Accept: application/json` request header will be automatically
        inserted if not yet present and if `data` is not a string.
        type: 'boolean'
        description: '''
        Fail silently (no output at all) on HTTP errors.
        $ref: 'module://@nikitajs/core/lib/actions/fs/chown#/definitions/config/properties/gid'
        description: '''
        Group name or id who owns the target file; only apply if `target` is
        type: 'object'
        default: {}
        description: '''
        Extra header to include in the request when sending the HTTP request
        to a server.
        type: 'boolean'
        description: '''
        Allow insecure server connections when using SSL; disabled if `cacert`
        is provided.
        type: 'boolean'
        description: '''
        If the server reports that the requested page has moved to a different
        location (indicated with a Location: header and a 3XX response code),
        this option will make curl redo the request on the new place.
        type: 'string'
        default: 'GET'
        description: '''
        Specify request command (HTTP method) to use.
        $ref: 'module://@nikitajs/core/lib/actions/fs/chmod#/definitions/config/properties/mode'
        description: '''
        Permissions of the target. If specified, nikita will chmod after
        type: 'boolean'
        description: '''
        Use HTTP Negotiate (SPNEGO) authentication.
        type: 'string'
        description: '''
        Use the specified HTTP proxy. If the port number is not specified, it
        is assumed at port 1080. See curl(1) man page.
        type: 'string'
        description: '''
        Password associated with the Kerberos principal, required if
        `principal` is provided.
        type: 'string'
        description: '''
        Kerberos principal name if a ticket must be generated along the
        `negociate` option.
        type: 'string'
        description: '''
        An alias for connection.http_headers[\'Referer\']
        type: 'string'
        description: '''
        Write to file instead of stdout; mapped to the curl `output` argument.
        $ref: 'module://@nikitajs/core/lib/actions/fs/chown#/definitions/config/properties/uid'
        description: '''
        User name or id who owns the target file; only apply if `target` is
        type: 'string'
        description: '''
        HTTP URL endpoint, must be a valid URL.
    required: ['url']


handler = ({config}) ->
  throw Error "Required Option: `password` is required if principal is provided" if config.principal and not config.password
  throw Error "Required Option: `data` is required with POST and PUT requests" if config.method in ['POST', 'PUT'] and not
  if and typeof isnt 'string'
    config.http_headers['Accept'] ?= 'application/json'
    config.http_headers['Content-Type'] ?= 'application/json' = JSON.stringify
  url_info = url.parse config.url
  config.http_headers ?= []
  config.cookies ?= []
  err = null
  output =
    body: []
    data: undefined
    http_version: undefined
    headers: {}
    status_code: undefined
    status_message: undefined
    type: undefined
    {code, stdout} = await @execute
      command: """
      #{ unless config.principal then '' else [
        'echo', config.password, '|', 'kinit', config.principal, '>/dev/null'
      ].join ' '}
      command -v curl >/dev/null || exit 90
        '--include' # Include protocol headers in the output (H/F)
        '--silent' # Dont print progression to stderr
        '--fail' if
        '--insecure' if not config.cacert and url_info.protocol is 'https:'
        '--cacert #{config.cacert}' if config.cacert
        '--negotiate -u:' if config.negotiate
        '--location' if config.location
        ...("--header '#{header.replace '\'', '\\\''}:#{value.replace '\'', '\\\''}'" for header, value of config.http_headers)
        ...("--cookie '#{cookie.replace '\'', '\\\''}'" for cookie in config.cookies)
        "-o #{}" if
        "-x #{config.proxy}" if config.proxy
        "-X #{config.method}" if config.method isnt 'GET'
        "--data #{utils.string.escapeshellarg}" if
      ].join ' '}
      trap: true
    output.raw = stdout
    done_with_header = false
    for line, i in utils.string.lines stdout
      if output.body.length is 0 and /^HTTP\/[\d.]+ \d+/.test line
        done_with_header = false
        output.headers = {}
        [http_version, status_code, status_message...] = line.split ' '
        output.http_version = http_version.substr 5
        output.status_code = parseInt status_code, 10
        output.status_message = status_message.join ' '
        just_finished_header = false
      else if line is ''
        done_with_header = true
      unless done_with_header
        [name, value...] = line.split ':'
        output.headers[name.trim()] = value.join(':').trim()
        output.body.push line
  catch err
    if code = utils.curl.error(err.exit_code)
      throw utils.error code, [
        "the curl command exited with code `#{err.exit_code}`."
    else if err.exit_code is 90
      throw utils.error 'NIKITA_NETWORK_DOWNLOAD_CURL_REQUIRED', [
        'the `curl` command could not be found'
        'and is required to perform HTTP requests,'
        'make sure it is available in your `$PATH`.'
    else throw err
  await @fs.chmod
    $if: and config.mode
    mode: config.mode
  await @fs.chown
    $if: and config.uid? or config.gid?
    uid: config.uid
    gid: config.gid
  output.type = 'json' if /^application\/json(;|$)/.test output.headers['Content-Type']
  output.body = output.body.join ''
  switch output.type
    when 'json' then = JSON.parse output.body


module.exports =
  handler: handler
    definitions: definitions


url = require 'url'
utils = require '../utils'
Edit on GitHub

Nikita is an open source project hosted on GitHub and developed by Adaltas.