Skip to content

Instantly share code, notes, and snippets.

@godfat
Last active May 19, 2019 18:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save godfat/30612a8dabb416076e73512c5aea46b6 to your computer and use it in GitHub Desktop.
Save godfat/30612a8dabb416076e73512c5aea46b6 to your computer and use it in GitHub Desktop.

HTTP

Connection

telnet www.example.com 80
curl -v www.example.com

Request

GET / HTTP/1.1
Host: www.example.com

Response

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Sun, 19 May 2019 07:58:33 GMT
Etag: "1541025663"
Expires: Sun, 26 May 2019 07:58:33 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (sjc/4E8B)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1270

Echo server with TCP socket

require 'socket'

server = TCPServer.new(8080)
client = server.accept
data = client.readline("\r\n\r\n") # CRLF
client.puts(data)
client.close
server.close
curl -v localhost:8080

Rack

gem install rack

Ruby file

require 'rack'

app = Rack::Builder.app do
  use Rack::ContentLength
  run lambda { |env| [200, {}, [env.inspect]] }
end

Rack::Handler.default.run(app, Port: 8080)
curl -v localhost:8080

config.ru

run lambda { |env| [200, {}, [env.inspect]] }
rackup -o 0.0.0.0 -p 8080

Jellyfish config.ru

gem install jellyfish
require 'jellyfish'

class Web
  include Jellyfish
  get '/' do
    env.inspect
  end
end

run Web.new
curl -v localhost:8080
curl -v localhost:8080/test # 404
require 'jellyfish'

class Web
  include Jellyfish
  get // do
    env.inspect
  end
end

run Web.new
curl -v localhost:8080      # PATH_INFO: /
curl -v localhost:8080/test # PATH_INFO: /test

HTML

require 'jellyfish'

class Web
  include Jellyfish
  get '/' do
    <<~HTML
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8"/>
          <title>🐱</title>
        </head>
        <body>🐈</body>
      </html>
    HTML
  end
end

run Web.new

GET /favicon.ico? 404?

require 'jellyfish'

class Web
  include Jellyfish
  get '/' do
    <<~HTML
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <link rel="icon" type="image/gif" href="favicon.gif">
          <title>🐱</title>
        </head>
        <body>🐈</body>
      </html>
    HTML
  end

  get '/favicon.gif' do
    "GIF89a\x01\x00\x01\x00\x80\x01\x00" \
      "\xff\x00\x00" + # RGB
      "\x00\x00\x00," \
      "\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00"
  end
end

run Web.new

JavaScript

require 'jellyfish'

class Web
  include Jellyfish
  get '/' do
    <<~HTML
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>🐱</title>
        </head>
        <body>
          <p onclick="this.innerHTML += this.innerHTML">🐈</p>
        </body>
      </html>
    HTML
  end
end

run Web.new

Form

require 'jellyfish'

class Web
  include Jellyfish
  get '/' do
    <<~HTML
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>🐱</title>
        </head>
        <body>
          <form action="/submit">
            <input type="submit">
          </form>
        </body>
      </html>
    HTML
  end

  get '/submit' do
    '🐈'
  end
end

run Web.new

Layout

require 'jellyfish'

class Web
  include Jellyfish

  controller_include Module.new {
    def layout
      <<~HTML
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <title>🐱</title>
          </head>
          <body>
            #{yield}
          </body>
        </html>
      HTML
    end
  }

  get '/' do
    layout do
      <<~HTML
        <form action="/submit">
          <input type="submit">
        </form>
      HTML
    end
  end

  get '/submit' do
    layout { '🐈' }
  end
end

run Web.new

Query

require 'jellyfish'

class Web
  include Jellyfish

  controller_include Module.new {
    def layout
      <<~HTML
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <title>🐱</title>
          </head>
          <body>
            #{yield}
          </body>
        </html>
      HTML
    end
  }

  get '/' do
    layout do
      <<~HTML
        <form action="/submit">
          <input type="text" name="cat">
          <input type="submit">
        </form>
      HTML
    end
  end

  get '/submit' do
    layout { "🐈 #{request['cat']}" }
  end
end

run Web.new

POST

require 'jellyfish'

class Web
  include Jellyfish

  controller_include Module.new {
    def layout
      <<~HTML
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <title>🐱</title>
          </head>
          <body>
            #{yield}
          </body>
        </html>
      HTML
    end
  }

  get '/' do
    layout do
      <<~HTML
        <form action="/submit" method="post">
          <input type="text" name="cat">
          <input type="submit">
        </form>
      HTML
    end
  end

  post '/submit' do
    layout { "🐈 #{request['cat']}" }
  end
end

run Web.new

Set cookies via JavaScript

require 'jellyfish'

class Web
  include Jellyfish

  controller_include Module.new {
    def layout
      <<~HTML
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <title>🐱</title>
          </head>
          <body>
            #{yield}
          </body>
        </html>
      HTML
    end
  }

  get '/' do
    layout do
      form = <<~HTML
        <form onsubmit="document.cookie = 'cat=' + this.elements['cat'].value">
          <input type="text" name="cat">
          <input type="submit">
        </form>

        <form onsubmit="document.cookie = 'cat=; expires=' + (new Date(0)).toUTCString()">
          <input type="submit" value="Clear">
        </form>
      HTML

      if cat = request.cookies['cat']
        "<p>Hi #{cat}!</p>\n<p>#{form}</p>"
      else
        "<p>#{form}</p>"
      end
    end
  end
end

run Web.new

Request when cookies set

GET / HTTP/1.1
Host: localhost:8080
Cookie: cat=QQ

Set cookies via server

require 'jellyfish'

class Web
  include Jellyfish

  controller_include Module.new {
    def layout
      <<~HTML
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <title>🐱</title>
          </head>
          <body>
            #{yield}
          </body>
        </html>
      HTML
    end
  }

  get '/' do
    layout do
      form = <<~HTML
        <form action="/submit" method="post">
          <input type="text" name="cat">
          <input type="submit">
        </form>

        <form action="/clear" method="post">
          <input type="submit" value="Clear">
        </form>
      HTML

      if cat = request.cookies['cat']
        "<p>Hi #{cat}!</p>\n<p>#{form}</p>"
      else
        "<p>#{form}</p>"
      end
    end
  end

  post '/submit' do
    response = Rack::Response.new
    response.set_cookie('cat', request['cat'])
    response.redirect('/')
    halt response.finish
  end

  post '/clear' do
    response = Rack::Response.new
    response.delete_cookie('cat')
    response.redirect('/')
    halt response.finish
  end
end

run Web.new

Response setting cookies

HTTP/1.1 302 Found
Set-Cookie: cat=QQ
Location: /

Response deleting cookies

HTTP/1.1 302 Found
Set-Cookie: cat=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000
Location: /
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment