RexxHTTP examples

Click the links to see the servlet in action, and the arrows to inspect the source code.

  1. The simplest "Hello, world!" servlet
    Say "Hello, world!"
    
  2. "Hello, world!" & Unicode
    Say "नमस्ते",  "P ≝ 𝔐",  "🦞🍐"
    
  3. A simple HTML servlet
    .response~content_type = 'text/html; charset=utf-8'
    
    Say .resources~HTML
    
    ::Resource HTML
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>A 'Hello world!' HTML servlet</title>
      </head>
      <body>
        <p>
           Hello, world!
        </p>
        <p>
          <small><a href="../">⬅️ Back to the examples.</a></small>
        </p>
      </body>
    </html>
    ::END
    
  4. Servlet showing HTML and Unicode
    .response~content_type = 'text/html; charset=utf-8'
    
    Say .resources~HTML
    
    ::Resource HTML
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>A 'Hello world!' HTML and Unicode servlet</title>
      </head>
      <body>
        <p>
           Hello, world!
           <br>नमस्ते
           <br>P ≝ 𝔐
           <br>🦞🍐
        </p>
        <p>
          <small><a href="../">⬅️ Back to the examples.</a></small>
        </p>
      </body>
    </html>
    ::END
    
  5. Reading a GET form with arg
    .response~content_type = 'text/html; charset=utf-8'
    
    Say '<!DOCTYPE html>'
    Say '<html lang="en">'
    Say '  <head>'
    Say "    <title>A simple GET-form servlet</title>"
    Say '  </head>'
    Say '  <body>'
    
    If .request~arg("name", "Exists") Then Do
      name = .request~arg("name")
      If name = "" Then Say '    <p>The name can not be empty.</p>'
      Else Call Greet
    End
    
    Call PrintForm
    
    Say '    <p>'
    Say '      <small><a href="../">⬅️ Back to the examples.</a></small>'
    Say '    </p>'
    Say '  </body>'
    Say '</html>'
    Exit
    
    Greet:
      Say '    <p>Hello, '.response~encodeHTML(name)'!</p>'
    Return
    
    PrintForm:
      Say '    <form method="get">'
      Say '      <label>Please enter your name: <input type="text" name="name"></label>'
      Say '      <button type="submit">Say hello</button>'
      Say '    </form>'
    Return
    
  6. Setting and reading a cookie
    .response~content_type = 'text/html; charset=utf-8'
    
    remembered = .request~cookie("name")
    
    If .request~arg("forget", "Exists") Then Do
      gone = .HTTP.Cookie~new("name", "")
      gone~path    = "/"
      gone~max_age = 0
      .response~addcookie(gone)
      remembered = ""
    End
    Else If remembered = "", .request~arg("name", "Exists") Then Do
      name = .request~arg("name")
      If name \= "" Then Do
        c = .HTTP.Cookie~new("name", .response~encodeURIComponent(name))
        c~path = "/"
        .response~addcookie(c)
        remembered = name
      End
    End
    
    Say '<!DOCTYPE html>'
    Say '<html lang="en">'
    Say '  <head>'
    Say "    <title>A simple cookie servlet</title>"
    Say '  </head>'
    Say '  <body>'
    
    If remembered \= "" Then Call Welcome
    Else Call PrintForm
    
    Say '    <p>'
    Say '      <small><a href="../">⬅️ Back to the examples.</a></small>'
    Say '    </p>'
    Say '  </body>'
    Say '</html>'
    Exit
    
    Welcome:
      Say '    <p>Welcome back, '.response~encodeHTML(remembered)'!</p>'
      Say '    <p><small><a href="?forget=1">Forget me</a></small></p>'
    Return
    
    PrintForm:
      Say '    <form method="get">'
      Say '      <label>Please enter your name: <input type="text" name="name"></label>'
      Say '      <button type="submit">Remember me</button>'
      Say '    </form>'
    Return
    
  7. Fetching and merging JSON from the web
    .response~content_type = 'text/html; charset=utf-8'
    
    Say '<!DOCTYPE html>'
    Say '<html lang="en">'
    Say '  <head>'
    Say "    <title>A simple aggregating servlet</title>"
    Say '  </head>'
    Say '  <body>'
    Say '    <h1>Two posts, fetched and merged</h1>'
    Say '    <p>This servlet fetches two sample posts from the public'
    Say '       <a href="https://jsonplaceholder.typicode.com/">JSONPlaceholder</a>'
    Say '       API, parses their JSON, and shows them below. The placeholder text'
    Say '       is theirs &mdash; what this example demonstrates is a servlet reaching'
    Say '       out to the network and composing the results.</p>'
    
    Base = "https://jsonplaceholder.typicode.com/posts/"
    
    Do id = 1 To 2
      post = FetchJSON(Base || id)
      If post == .nil Then
        Say '    <p>Could not load post 'id'.</p>'
      Else Do
        Say '    <article>'
        Say '      <h2>#'.response~encodeHTML(post["id"])' &mdash; '.response~encodeHTML(post["title"])'</h2>'
        Say '      <p>'.response~encodeHTML(post["body"])'</p>'
        Say '    </article>'
      End
    End
    
    Say '    <p>'
    Say '      <small><a href="../">⬅️ Back to the examples.</a></small>'
    Say '    </p>'
    Say '  </body>'
    Say '</html>'
    Exit
    
    -- Fetch a URL and parse the JSON body into a Rexx object.
    -- Returns .nil if the download fails or the body is not valid JSON.
    -- Note: this blocks the CGI process until wget returns, so we keep it
    -- on a short leash -- --timeout caps DNS/connect/read at 5s each, and
    -- --tries=1 stops wget's default 20 silent retries from hanging the
    -- request when the remote host is down.
    FetchJSON: Procedure
      Use Strict Arg url
    
      Address Command "wget -qO- --timeout=5 --tries=1" url With Output Stem lines.
      If RC \= 0 Then Return .nil
    
      text = ""
      Do i = 1 To lines.0
        If i > 1 Then text = text || "0a"x
        text = text || lines.i
      End
    
      Signal On Syntax Name BadJSON
      Return .json~fromJson(text)
    
    BadJSON:
      Return .nil
    
    ::Requires "json.cls"