Sending data to web servers

Info 253: Web Architecture
Kay Ashaolu

Sending Data with HTTP

  • GET: Query arguments in URL
  • POST: Data in request body
  • PUT: Data in request body

Query Arguments

  • ?name=Kay&title=i253
  • Typically used in GET requests
  • Key-Value pairs delimited by =, separated by &

Key-Value pairs in Programming

  • JavaScript object contains data sent from client
  • GET: request.args.get("[key]")
  • POST: request.form.get("[key")

GET Review

  • What does GET do?
  • Should GET modify a resource?
  • How is data passed to GET?

Get Request

From end of Lecture 12 example
curl -v "http://localhost:3000/?day_of_week=sunday"

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /?day_of_week=sunday HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
					

Get Response

< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 856
< ETag: W/"358-OO441lqfknOF3OaKpKfZqQ"
< Date: Fri, 07 Oct 2016 01:06:25 GMT
< Connection: keep-alive
< 
<html>
	<head>
		<title>Homepage</title>
    	<link rel='stylesheet' href='/static/css/style.css' />
    </head>
    <body>
    	<h1>This is the home page!</h1>

    	<p>The quote for sunday is: Life is about making an impact, 
    	not making an income.   –Kevin Kruse</p>
					

Content-Type Header

  • Describes what format the data is in
  • MIME: Multipurpose Internet Mail Extensions
  • Internet Media Type, Content-Type

Format

  • MIME format: [type] / [subtype] ; [parameters]
    • type: the general category of data
    • subtype: formats, encodings
    • parameters: extra information that applies to that subtype

Extensible

  • Common MIME types are registered
    • text/plain
    • image/png
    • audio/mpeg
  • Make up your own with vnd., prs.

Pranks

POST and PUT Data

  • Requests have metadata (Headers)
  • Requests can have data, too
  • Data is formatted similarly to query arguments

POST Data example

    Building on end of Lecture 12 example

  • Package requirements
    • pip install requests
      • Enables us to send an HTTP request from the server

POST Data example

Building on end of Lecture 12 example

webserver.py (1/3)

import requests
import os

from flask import Flask, request, render_template
app = Flask(__name__, static_url_path="/static")

@app.route('/email', methods=['GET'])
def show_email_page():
  return render_template("email.html", notifications=[])
					

POST Data example

webserver (2/3)

@app.route('/email', methods=['POST'])
def send_email():
    message = request.form.get("message")
    notifications = []

    data = {
        'from': os.environ["INFO253_MAILGUN_FROM_EMAIL"],
        'to': os.environ["INFO253_MAILGUN_TO_EMAIL"],
        'subject': "You just was sent a message",
        'text': message,
    }
  					

POST Data example

webserver (3/3)

   auth = (os.environ["INFO253_MAILGUN_USER"], os.environ["INFO253_MAILGUN_PASSWORD"])

    r = requests.post(
        'https://api.mailgun.net/v3/{}/messages'.format(os.environ["INFO253_MAILGUN_DOMAIN"]),
        auth=auth,
        data=data)

	if r.status_code == requests.codes.ok:
        notifications.append("Your email was sent")
    else:
        notifications.append("You email was not sent. Please try again later")

    return render_template("email.html", notifications=notifications)
					

POST Data example

templates/email.html

<html>
<head>
    <title>Email</title>
    <link rel='stylesheet' href='/static/style.css' />
</head>
<body>

<ul>
    {% for notification in notifications %}
    <li>{{ notification }}</li>
    {% endfor %}
</ul>

<h1>Email me!</h1>

<form action="/email" method="POST">
    <textarea name="message"></textarea>
    <input type="submit" value="Send me an email!" />
</form>
</body>
</html>
		

POST Data example

curl -v --data message=this%20is%20cool localhost:3000/email

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /email HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 24
> Content-Type: application/x-www-form-urlencoded

message=this%20is%20cool
					

POST Data example

* upload completely sent off: 24 out of 24 bytes
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 346
< ETag: W/"15a-/UO9Judtk8xIMgUMpeBmQg"
< Date: Fri, 07 Oct 2016 05:53:06 GMT
< Connection: keep-alive
< 
<html>
	<head>
		<title>Email</title>
    	<link rel='stylesheet' href='/static/style.css' />
    </head>
    <body>
		...
					

POST in practice

  • Most browsers only support GET, POST
  • HTML5 (currently) only supports GET, POST
  • So resource accessed by browsers, use POST for all modifying interactions

Query Arguments

  • Delimited by =, separated by &
  • What happens if you want to send a ?
  • What happens if you want to send a &?

Encoding

  • Map one representation of data to another
  • Map normal text to a format accepted by HTTP query params
  • Map special characters to the hexadecimal representation

URL Encoding

  • = - %3D
  • & - %26
  • space - %20

HTML Encoding

  • < - &lt;
  • & - &amp;
  • > - &gt;
  • ☃ - &#9731;

Questions