class Kontena::LocalhostWebServer

Constants

DEFAULT_ERROR_MESSAGE
SUCCESS_URL

Attributes

error_response[RW]

Serves one request to

Serves one request to

Serves one request to

Serves one request to

Public Class Methods

new(success_response: nil, error_response: nil, port: nil) click to toggle source

Get new server instance

@param [String] success_response Returned for successful callback @param [String] error_response Returned for unsuccessful callback

# File lib/kontena/cli/localhost_web_server.rb, line 26
def initialize(success_response: nil, error_response: nil, port: nil)
  @success_response = success_response
  @error_response   = error_response   || DEFAULT_ERROR_MESSAGE
  @server = TCPServer.new('localhost', port || 0)
  @port = @server.addr[1]
end

Public Instance Methods

serve_one() click to toggle source

Serve one request and return query params.

@return [Hash] query_params

# File lib/kontena/cli/localhost_web_server.rb, line 41
def serve_one
  Kontena.logger.debug("LHWS") { "Waiting for connection on port #{port}.." }
  socket = server.accept

  content = socket.recvfrom(2048).first.split(/(?:\r)?\n/)

  request = content.shift

  headers = {}
  while line = content.shift
    break if line.nil?
    break if line == ''
    header, value = line.chomp.split(/:\s{0,}/, 2)
    headers[header] = value
  end

  body = content.join("\n")

  Kontena.logger.debug("LHWS") { "Got request: \"#{request.inspect}\n  Headers: #{headers.inspect}\n  Body: #{body}\"" }

  get_request = request[/GET (\/cb.+?) HTTP/, 1]
  if get_request
    if success_response
      socket.print [
        'HTTP/1.1 200 OK',
        'Content-Type: text/html',
        "Content-Length: #{success_response.bytesize}",
        "Connection: close",
        '',
        success_response
      ].join("\r\n")
    else
      socket.print [
        'HTTP/1.1 302 Found',
        "Location: #{SUCCESS_URL}",
        "Referrer-Policy: no-referrer",
        "Connection: close",
        ''
      ].join("\r\n")
    end

    socket.close
    server.close
    uri = URI.parse("http://localhost#{get_request}")
    Kontena.logger.debug("LHWS") { "  * Parsing params: \"#{uri.query}\"" }
    params = {}
    URI.decode_www_form(uri.query).each do |key, value|
      if value.to_s == ''
        next
      elsif value.to_s =~ /\A\d+\z/
        params[key] = value.to_i
      else
        params[key] = value
      end
    end
    params
  else
    # Unless it's a query to /cb, send an error message and keep listening,
    # it might have been something funny like fetching favicon.ico
    socket.print [
      'HTTP/1.1 400 Bad request',
      'Content-Type: text/plain',
      "Content-Length: #{error_response.bytesize}",
      'Connection: close',
      '',
      error_response
    ].join("\r\n")
    socket.close
    serve_one # serve more, this one was not proper.
  end
end
url() click to toggle source

The url to this service, send this as redirect_uri to auth provider.

# File lib/kontena/cli/localhost_web_server.rb, line 34
def url
  "http://localhost:#{port}/cb"
end