### ASP.NET Core Razor Pages (port 9401)
== Chapter 14 check against http://127.0.0.1:9401
GET /                       200, counter: no outlet chosen
POST /outlet O09            422 (refused)
POST /outlet O01            302 -> /
  Set-Cookie                outlet [httponly, max-age, samesite]; .Laundry.Session [httponly, samesite]
  flash                     This counter now works for O01 Profitina Laundry Rungkut.
  counter                   Profitina Laundry Rungkut
POST /customers/new (bad)   422, 7 messages:
    - Enter the customer's name.
    - Choose female or male.
    - Enter a date of birth in the past, at most 120 years ago.
    - Enter an Indonesian mobile number such as 0812-3456-7890 or +62 812 3456 7890.
    - Enter a valid e-mail address, for example rina@example.com.
    - An online password needs 8 to 64 characters.
    - The two passwords do not match.
  place kept                Surabaya
  password sent back        no
POST /customers/new (good)  302 -> /bills/draft?customer=C0257
  flash                     Customer C0257 Rina Wijaya registered.
  heading                   C0257 Rina Wijaya
add S0001 x5 B09            302 -> /bills/draft?customer=C0257
add S0008 x1 b10            302 -> /bills/draft?customer=C0257
add S0003 x2 A20            302 -> /bills/draft?customer=C0257
  draft total               Rp 87.000
add 0 units, rack D01       422: Enter a whole number from 1 to 999; round kilograms up. | A rack is a letter A to C and a number 01 to 20, for example B07.
add 2.5 units               422: Enter a whole number from 1 to 999; round kilograms up.
add service S0099           422: Choose a service from the price list.
add rack B08                422: Rack B08 is already taken at O01; choose another.
add rack B09 again          422: Rack B09 is already in this draft.
remove line 3               total now Rp 75.000
tampered hidden customer    -> /: This draft has expired. Please open it again.
browser B, same draft URL   total Rp 0, counter: no outlet chosen
confirm                     302 -> /
  flash                     Created B2954, B2955 for C0257 Rina Wijaya: Rp 75.000.
  reload                    flash gone
A: GET /lab                 app=1 session=1 cookie=1 hidden=0 query=0
A: GET /lab again           app=2 session=2 cookie=2 hidden=0 query=0
A: POST the form            app=3 session=3 cookie=3 hidden=1 query=0
A: POST the form            app=4 session=4 cookie=4 hidden=2 query=0
A: follow the link          app=5 session=5 cookie=5 hidden=0 query=1
A: follow it again          app=6 session=6 cookie=6 hidden=0 query=2
B: GET /lab                 app=7 session=1 cookie=1 hidden=0 query=0
RESULT: all checks passed
### PHP (port 9402)
== Chapter 14 check against http://127.0.0.1:9402
GET /                       200, counter: no outlet chosen
POST /outlet O09            422 (refused)
POST /outlet O01            302 -> /
  Set-Cookie                outlet [httponly, max-age, samesite]
  flash                     This counter now works for O01 Profitina Laundry Rungkut.
  counter                   Profitina Laundry Rungkut
POST /customers/new (bad)   422, 7 messages:
    - Enter the customer's name.
    - Choose female or male.
    - Enter a date of birth in the past, at most 120 years ago.
    - Enter an Indonesian mobile number such as 0812-3456-7890 or +62 812 3456 7890.
    - Enter a valid e-mail address, for example rina@example.com.
    - An online password needs 8 to 64 characters.
    - The two passwords do not match.
  place kept                Surabaya
  password sent back        no
POST /customers/new (good)  302 -> /bills/draft?customer=C0257
  flash                     Customer C0257 Rina Wijaya registered.
  heading                   C0257 Rina Wijaya
add S0001 x5 B09            302 -> /bills/draft?customer=C0257
add S0008 x1 b10            302 -> /bills/draft?customer=C0257
add S0003 x2 A20            302 -> /bills/draft?customer=C0257
  draft total               Rp 87.000
add 0 units, rack D01       422: Enter a whole number from 1 to 999; round kilograms up. | A rack is a letter A to C and a number 01 to 20, for example B07.
add 2.5 units               422: Enter a whole number from 1 to 999; round kilograms up.
add service S0099           422: Choose a service from the price list.
add rack B08                422: Rack B08 is already taken at O01; choose another.
add rack B09 again          422: Rack B09 is already in this draft.
remove line 3               total now Rp 75.000
tampered hidden customer    -> /: This draft has expired. Please open it again.
browser B, same draft URL   total Rp 0, counter: no outlet chosen
confirm                     302 -> /
  flash                     Created B2954, B2955 for C0257 Rina Wijaya: Rp 75.000.
  reload                    flash gone
A: GET /lab                 app=1 session=1 cookie=1 hidden=0 query=0
A: GET /lab again           app=2 session=2 cookie=2 hidden=0 query=0
A: POST the form            app=3 session=3 cookie=3 hidden=1 query=0
A: POST the form            app=4 session=4 cookie=4 hidden=2 query=0
A: follow the link          app=5 session=5 cookie=5 hidden=0 query=1
A: follow it again          app=6 session=6 cookie=6 hidden=0 query=2
B: GET /lab                 app=7 session=1 cookie=1 hidden=0 query=0
RESULT: all checks passed
### Java, JDK HttpServer (port 9403)
Picked up JAVA_TOOL_OPTIONS: -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts -Djavax.net.ssl.trustStoreType=JKS -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=33323 -Dhttp.nonProxyHosts=localhost|127.0.0.1|::1|127.*|0.*|::|169.254.*|api.anthropic.com|api-staging.anthropic.com|api-pr-preview.anthropic.com|mcp-proxy.anthropic.com|mcp-proxy-staging.anthropic.com|registry.npmjs.org|jsr.io|npm.jsr.io|pypi.org|files.pythonhosted.org|index.crates.io|proxy.golang.org|host.docker.internal|10.*|172.16.*|172.17.*|172.18.*|172.19.*|172.20.*|172.21.*|172.22.*|172.23.*|172.24.*|172.25.*|172.26.*|172.27.*|172.28.*|172.29.*|172.30.*|172.31.*|192.168.*|100.64.0.0/10|*.svc.cluster.local|*.svc.cluster.local -Djdk.http.auth.tunneling.disabledSchemes= -Djdk.http.auth.proxying.disabledSchemes=
== Chapter 14 check against http://127.0.0.1:9403
GET /                       200, counter: no outlet chosen
POST /outlet O09            422 (refused)
POST /outlet O01            302 -> /
  Set-Cookie                outlet [httponly, max-age, samesite]
  flash                     This counter now works for O01 Profitina Laundry Rungkut.
  counter                   Profitina Laundry Rungkut
POST /customers/new (bad)   422, 7 messages:
    - Enter the customer's name.
    - Choose female or male.
    - Enter a date of birth in the past, at most 120 years ago.
    - Enter an Indonesian mobile number such as 0812-3456-7890 or +62 812 3456 7890.
    - Enter a valid e-mail address, for example rina@example.com.
    - An online password needs 8 to 64 characters.
    - The two passwords do not match.
  place kept                Surabaya
  password sent back        no
POST /customers/new (good)  302 -> /bills/draft?customer=C0257
  flash                     Customer C0257 Rina Wijaya registered.
  heading                   C0257 Rina Wijaya
add S0001 x5 B09            302 -> /bills/draft?customer=C0257
add S0008 x1 b10            302 -> /bills/draft?customer=C0257
add S0003 x2 A20            302 -> /bills/draft?customer=C0257
  draft total               Rp 87.000
add 0 units, rack D01       422: Enter a whole number from 1 to 999; round kilograms up. | A rack is a letter A to C and a number 01 to 20, for example B07.
add 2.5 units               422: Enter a whole number from 1 to 999; round kilograms up.
add service S0099           422: Choose a service from the price list.
add rack B08                422: Rack B08 is already taken at O01; choose another.
add rack B09 again          422: Rack B09 is already in this draft.
remove line 3               total now Rp 75.000
tampered hidden customer    -> /: This draft has expired. Please open it again.
browser B, same draft URL   total Rp 0, counter: no outlet chosen
confirm                     302 -> /
  flash                     Created B2954, B2955 for C0257 Rina Wijaya: Rp 75.000.
  reload                    flash gone
A: GET /lab                 app=1 session=1 cookie=1 hidden=0 query=0
A: GET /lab again           app=2 session=2 cookie=2 hidden=0 query=0
A: POST the form            app=3 session=3 cookie=3 hidden=1 query=0
A: POST the form            app=4 session=4 cookie=4 hidden=2 query=0
A: follow the link          app=5 session=5 cookie=5 hidden=0 query=1
A: follow it again          app=6 session=6 cookie=6 hidden=0 query=2
B: GET /lab                 app=7 session=1 cookie=1 hidden=0 query=0
RESULT: all checks passed
### Python, Flask (port 9404)
== Chapter 14 check against http://127.0.0.1:9404
GET /                       200, counter: no outlet chosen
POST /outlet O09            422 (refused)
POST /outlet O01            302 -> /
  Set-Cookie                outlet [httponly, max-age, samesite]; laundry_session [httponly, samesite]
  flash                     This counter now works for O01 Profitina Laundry Rungkut.
  counter                   Profitina Laundry Rungkut
POST /customers/new (bad)   422, 7 messages:
    - Enter the customer's name.
    - Choose female or male.
    - Enter a date of birth in the past, at most 120 years ago.
    - Enter an Indonesian mobile number such as 0812-3456-7890 or +62 812 3456 7890.
    - Enter a valid e-mail address, for example rina@example.com.
    - An online password needs 8 to 64 characters.
    - The two passwords do not match.
  place kept                Surabaya
  password sent back        no
POST /customers/new (good)  302 -> /bills/draft?customer=C0257
  flash                     Customer C0257 Rina Wijaya registered.
  heading                   C0257 Rina Wijaya
add S0001 x5 B09            302 -> /bills/draft?customer=C0257
add S0008 x1 b10            302 -> /bills/draft?customer=C0257
add S0003 x2 A20            302 -> /bills/draft?customer=C0257
  draft total               Rp 87.000
add 0 units, rack D01       422: Enter a whole number from 1 to 999; round kilograms up. | A rack is a letter A to C and a number 01 to 20, for example B07.
add 2.5 units               422: Enter a whole number from 1 to 999; round kilograms up.
add service S0099           422: Choose a service from the price list.
add rack B08                422: Rack B08 is already taken at O01; choose another.
add rack B09 again          422: Rack B09 is already in this draft.
remove line 3               total now Rp 75.000
tampered hidden customer    -> /: This draft has expired. Please open it again.
browser B, same draft URL   total Rp 0, counter: no outlet chosen
confirm                     302 -> /
  flash                     Created B2954, B2955 for C0257 Rina Wijaya: Rp 75.000.
  reload                    flash gone
A: GET /lab                 app=1 session=1 cookie=1 hidden=0 query=0
A: GET /lab again           app=2 session=2 cookie=2 hidden=0 query=0
A: POST the form            app=3 session=3 cookie=3 hidden=1 query=0
A: POST the form            app=4 session=4 cookie=4 hidden=2 query=0
A: follow the link          app=5 session=5 cookie=5 hidden=0 query=1
A: follow it again          app=6 session=6 cookie=6 hidden=0 query=2
B: GET /lab                 app=7 session=1 cookie=1 hidden=0 query=0
RESULT: all checks passed
### What the three database tracks wrote
php   ('C0257', 'Rina Wijaya', '0812-3456-7890', 'pbkdf2_sha256$600000$')  [('B2954', 'B09', 5, 40000, 'O01', 'E0004'), ('B2955', 'B10', 1, 35000, 'O01', 'E0004')]  status log rows: 2  checks: ok
java  ('C0257', 'Rina Wijaya', '0812-3456-7890', 'pbkdf2_sha256$600000$')  [('B2954', 'B09', 5, 40000, 'O01', 'E0004'), ('B2955', 'B10', 1, 35000, 'O01', 'E0004')]  status log rows: 2  checks: ok
flask ('C0257', 'Rina Wijaya', '0812-3456-7890', 'pbkdf2_sha256$600000$')  [('B2954', 'B09', 5, 40000, 'O01', 'E0004'), ('B2955', 'B10', 1, 35000, 'O01', 'E0004')]  status log rows: 2  checks: ok
