Auflösungen

PHP

HTTPocalypse

1)

In test.php wird ein Accept-Header mit dem Wert application/json gesetzt (vgl. enstprechenden Guzzle-Dokumentationsabschnitt).

<?php
require __DIR__ . '/../vendor/autoload.php';

$client = new \GuzzleHttp\Client();
$response = $client->request(
    'GET',
    'host.docker.internal:1010',
    [
        'headers' => [
            'Accept' => 'application/json', // Request a JSON response.
            'User-Agent' => 'HTTP-Client-Container'
        ]
    ]
);

echo "Status Code: " . $response->getStatusCode() . "\n";
echo "Content-Type Header: " . $response->getHeaderLine('content-type') . "\n";
echo "Response Body: " . $response->getBody() . "\n";

In der __invoke-Funktion in HttpController.php wird über das request-Objekt der Accept-Header abgefragt und dann in die entsprechenden Response-Details in einer Weiche abhängig vom Header-Inhalt gesetzt.

<?php
namespace App;

use Psr\Http\Message\{
    ResponseInterface,
    ServerRequestInterface
};

class HttpController {
    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        array $args
    ) {
        // If the Accept header of the request is application/json,
        // return a JSON response.
        if ($request->getHeaderLine('Accept') === 'application/json') {
            $responseData = ['message' => 'Hello World'];
            $contentBody = json_encode($responseData);
            $response = $response->withHeader('Content-Type', 'application/json');
            $response->getBody()->write($contentBody);
            return $response;
        }

        // The default response is a plain text response.
        $response = $response->withHeader('Content-Type', 'text/plain');
        $response->getBody()->write('Hello World');
        return $response;
    }
}

2)

Im Client-Skript wird der Inhalt des Accept-Headers auf den MIME-Type text/xml umgestellt.

<?php
require __DIR__ . '/../vendor/autoload.php';

$client = new \GuzzleHttp\Client();
$response = $client->request(
    'GET',
    'host.docker.internal:1010',
    [
        'headers' => [
            'Accept' => 'application/xml', // Request an XML response.
            'User-Agent' => 'HTTP-Client-Container'
        ],
        'http_errors' => false // Guzzle will by default throw exceptions for
                               // 4xx and 5xx status codes. We don't want that.
                               // See https://docs.guzzlephp.org/en/stable/request-options.html#http-errors
    ]
);

echo "Status Code: " . $response->getStatusCode() . "\n";
echo "Content-Type Header: " . $response->getHeaderLine('content-type') . "\n";
echo "Response Body: " . $response->getBody() . "\n";

Der Controller wird um eine weitere Weiche erweitert, die den Inhalt des Accept-Headers auf application/xml bzw. text/xml prüft und dann eine Fehler-Response zurückgibt.

<?php
namespace App;

use Psr\Http\Message\{
    ResponseInterface,
    ServerRequestInterface
};

class HttpController {
    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        array $args
    ) {
        // If the Accept header of the request is an XML type,
        // return a 415 status code
        if (strpos($request->getHeaderLine('Accept'), '/xml') !== false) {
            $response = $response->withStatus(415);
            return $response;
        }

        // If the Accept header of the request is application/json,
        // return a JSON response.
        if ($request->getHeaderLine('Accept') === 'application/json') {
            $responseData = ['message' => 'Hello World'];
            $contentBody = json_encode($responseData);
            $response = $response->withHeader('Content-Type', 'application/json');
            $response->getBody()->write($contentBody);
            return $response;
        }

        // The default response is a plain text response.
        $response = $response->withHeader('Content-Type', 'text/plain');
        $response->getBody()->write('Hello World');
        return $response;
    }
}

3)

Für den Request wird nun über Guzzle noch ein Authorization-Header gesetzt. Dieser wird nicht wie bisher in das bestehende header-Array eingefügt sondern mit dem zusätzlichen Sub-Parameter auth, damit Guzzle die übergebenen Zugangsdaten gleich automatisch entsprechend codiert (vgl. enstprechenden Guzzle-Dokumentationsabschnitt).

<?php
require __DIR__ . '/../vendor/autoload.php';

$client = new \GuzzleHttp\Client();
$response = $client->request(
    'GET',
    'host.docker.internal:1010',
    [
        'auth' => ['foo', 'bar'], // Basic Auth.
        'headers' => [
            'Accept' => 'application/json', // Request a JSON response.
            'User-Agent' => 'HTTP-Client-Container'
        ],
        'http_errors' => false // Guzzle will by default throw exceptions for
                               // 4xx and 5xx status codes. We don't want that.
                               // See https://docs.guzzlephp.org/en/stable/request-options.html#http-errors
    ]
);

echo "Status Code: " . $response->getStatusCode() . "\n";
echo "Content-Type Header: " . $response->getHeaderLine('content-type') . "\n";
echo "Response Body: " . $response->getBody() . "\n";

Im Contoller wird eine weitere Prüfung auf einen Authorization-Header vom richtigen Typ und mit dem richtigen Inhalt eingefügt und ggf. eine Response mit dem Statuscode 401 zurückgegeben.

<?php
namespace App;

use Psr\Http\Message\{
    ResponseInterface,
    ServerRequestInterface
};

class HttpController {
    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        array $args
    ) {
        // If the Authorization type of the request is not Basic or the
        // credentials are not correct, return a 401 status code.
        //
        // Note that we use base64_encode('foo:bar') here to generate the same
        // token that we expect in the Authorization header.
        //
        // Guzzle in the client script uses the same method under the bonnet to
        // generate the token content of the Authorization header of the
        // request.
        if (
            $request->getHeaderLine('Authorization') !== 'Basic ' . base64_encode('foo:bar')
        ) {
            $response = $response->withStatus(401);
            return $response;
        }

        // If the Accept header of the request is an XML type,
        // return a 415 status code
        if (strpos($request->getHeaderLine('Accept'), '/xml') !== false) {
            $response = $response->withStatus(415);
            return $response;
        }

        // If the Accept header of the request is application/json,
        // return a JSON response.
        if ($request->getHeaderLine('Accept') === 'application/json') {
            $responseData = ['message' => 'Hello World'];
            $contentBody = json_encode($responseData);
            $response = $response->withHeader('Content-Type', 'application/json');
            $response->getBody()->write($contentBody);
            return $response;
        }

        // The default response is a plain text response.
        $response = $response->withHeader('Content-Type', 'text/plain');
        $response->getBody()->write('Hello World');
        return $response;
    }
}

JavaScript

1)

alert('Hello World!')

2)

let name = 'Kermit'
alert('Hello ' + name + '!')

oder

let name = 'Kermit'
alert(`Hello ${name}!`)

3)

const birthday = '01.01.2001'
alert(birthday)

4)

let number = 1.2
let string = 'Hello'
let boolean = true
let notDefined
let nothing = null

alert(typeof(number))
alert(typeof(string))
alert(typeof(boolean))
alert(typeof(notDefined))
alert(typeof(nothing))

5)

let concatenation = 'New York' + ' , ' + 'New York'
alert(concatenation)

let substraction = 5 - 3
alert(substraction)

let numeric = '5'
alert(numeric)

let number = +numeric
alert(number)

let six = number++
alert(six)

let four = number--
alert(four)

let number += 5
alert(number)

6)

let reply = prompt('In welchem Jahr wurde die erste HTTP-Spezifikation veröffnetlich?', '')

if (reply == 1991) {
    alert('Gratulation, die Antwort ist richtig!')
} else {
    alert('Leider falsch, das richtige Jahr ist 1991!')
}

7)

let my = {
    givenName: 'Kermit',
    lastName: 'der Frosch'
};

alert(`${my.givenName} ${my.lastName}`)

8)

let input = prompt('Was ist Ihre Lieblingsprogrammiersprache?', '')
const baseUrl = 'https://de.wikipedia.org/wiki/'

switch (input) {
    case 'PHP':
        alert(`${baseUrl}PHP`)
    break
    case 'Python':
        alert(`${baseUrl}Python_(Programmiersprache)`)
    break
    case 'JavaScript':
        alert(`${baseUrl}JavaScript`)
    break
    case 'Ruby':
        alert(`${baseUrl}Ruby_(Programmiersprache)`)
    break
    default:
        alert(`${baseUrl}Liste_von_Programmiersprachen`)
    break
}

9)

let count = 5

while (count <= 10) {
    alert(count)
    count++
}

10)

let count = 4

do {
    count++
    if (count == 6) {
        continue
    } else {
        alert(count)
    }
} while (count < 10)

11)

let count = 1
let base = 7

for (count; count <= 10; count++) {
    alert(count * base)
}

12)

const http = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE', 'CONNECT']

for (method in http) {
    alert(http[method])
}

13)

const lamp = 'LAMP'

for (let component of lamp) {
    switch (component) {
        case 'L':
            alert('Linux')
        break
        case 'A':
            alert('Apache')
        break
        case 'M':
            alert('MySQL')
        break
        case 'P':
            alert('PHP')
        break
    }
}

14)

// function declaration
function sum1(a, b) {
  let result = a + b
  return result
}

// function expression
let sum2 = function(a, b) {
  let result = a + b
  return result
}

// arrow function
let sum3 = (a, b) => a + b

alert(sum1(2,2))
alert(sum2(3,5))
alert(sum3(1,9))

15)

function callMe(later) {
    alert('Call Me ' + later())
}

callMe(() => 'Later Alligator!')

16)

let date = new Date(Date.parse('1914-12-19'))
alert(Date)

17)

let my = {
    givenName: 'Kermit',
    lastName: 'der Frosch',
    words: function(utterance) {
        return `${this.givenName} ${this.lastName} sagt: ${utterance}`
    }
}

alert(my.words('Applaus, Applaus, Applaus!'))

18)

function randomProduct(num) {
    return {
        num,
        multiply: Math.random(),
        result: function() {
            return num + ' * ' + this.multiply + ' = ' + (num * this.multiply)
        }
    }
}

alert(randomProduct(42).result())

19)

// array iteration
let numbers = [1,2,3,4,5]
for (number of numbers) {
    alert(number)
}

// string
let string = 'To be or not to be...'
alert(string.toUpperCase())

// number
let number = 1.5
alert(Math.ceil(number))

// RegExp
let string = 'Lieber Walden'
let regexp = /Walden/
alert(string.search(regexp))

20)

console.log(window)

21)

console.log(document)
for (let css of document.styleSheets) {
    alert(css.href)
}

22)

for (let li of document.body.firstElementChild.firstElementChild.lastElementChild.firstElementChild.children) {
  alert(li.firstChild.textContent)
}

23)

for (let node of document.querySelectorAll('.teaserheader')) {
  alert(node.textContent)
}

24)

let newElement = document.createElement('li')
newElement.innerHTML = '<a href="#">Fälschungen</a>'
document.querySelector('.navigation > ul').appendChild(newElement)

25)

document.querySelector('.branding > a').addEventListener('click', () => {alert('Nach Hause telefonieren')})