Skip to content

Instantly share code, notes, and snippets.

@jhass
Created July 22, 2016 12:05
Show Gist options
  • Save jhass/4613d601bfca63dead1ad6bfe7f74c91 to your computer and use it in GitHub Desktop.
Save jhass/4613d601bfca63dead1ad6bfe7f74c91 to your computer and use it in GitHub Desktop.

Revisions

  1. jhass created this gist Jul 22, 2016.
    68 changes: 68 additions & 0 deletions server.cr
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    require "option_parser"
    require "http/server"
    require "json"

    class Settings
    property port = 3000
    property host = "127.0.0.1"
    property? show_headers = false
    property? show_raw_json = false
    end

    settings = Settings.new


    OptionParser.parse! do |p|
    p.banner = "crystal server.cr -- [-p 3000] [-h 127.0.0.1] [--headers] [--rawjson]"

    p.on("-p PORT", "--port=PORT", "The port to bind on (default: 3000).") do |port|
    settings.port = port.to_i? || abort("Invalid port #{port}")
    end

    p.on("-h HOST", "--host=HOST", "The hostname to bind on (default: 127.0.0.1).") do |host|
    settings.host = host
    end

    p.on("--headers", "If set, request headers will be shown.") do
    settings.show_headers = true
    end

    p.on("--rawjson", "If set, JSON payload will not be formatted.") do
    settings.show_raw_json = true
    end

    p.on("--help", "Displays this message.") do
    puts p
    exit
    end
    end rescue abort "Invalid arguments, see --help."

    server = HTTP::Server.new(settings.host, settings.port) do |context|
    puts "-" * 80
    puts
    puts Time.now
    puts "#{context.request.method} #{context.request.path}"
    if settings.show_headers?
    puts
    puts "Headers:"
    puts context.request.headers.map {|k, v| " #{k}: #{v.join("; ")}" }.join("\n")
    end

    if body = context.request.body
    puts
    content_type = context.request.headers["Content-Type"]
    if content_type.includes?("json") && !settings.show_raw_json?
    puts JSON.parse(body).to_pretty_json
    elsif content_type.includes?("text") || content_type.includes?("json")
    puts body
    else
    puts "Got body of #{content_type} with #{context.request.headers["Content-Length"]} bytes."
    end
    end
    puts

    context.response.status_code = 204
    end

    puts "Listening on #{settings.host}:#{settings.port}"
    server.listen