Hacker DirectoryHacker Directory

WEB / WEB-07.05

Redirects, connections, and stateless HTTP

A redirect creates a new request; connection reuse uses an existing transport resource. Follow request context, application sessions, and resource state across their boundaries.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

POST → 303 → GET

  1. POST prepared

    Benign JSON is 16 UTF-8 bytes with supplied same-origin routing and a repeatable source.

    Browser / Duru
    POST /note-titles; 16 bytes; awaiting response
    Atlas routing and policy
    No request
    Resource / connection / session
    No note; actionCount=0
  2. Initial POST arrived

    The initial method and content reached the Application without applying the action.

    Browser / Duru
    POST /note-titles; 16 bytes; awaiting response
    Atlas routing and policy
    POST received; content 16 bytes
    Resource / connection / session
    No note; actionCount=0
  3. Server redirect decision

    Apply the title action once; select 303 for read-only result retrieval.

    Browser / Duru
    Awaiting response
    Atlas routing and policy
    303 ready; Location=/notes/atlas-1
    Resource / connection / session
    Note Çay; actionCount=1
  4. Redirect arrived at the Browser

    Status and relative Location arrived; the follow-up request has not been constructed.

    Browser / Duru
    303 received; Location known
    Atlas routing and policy
    303 ready; Location=/notes/atlas-1
    Resource / connection / session
    Note Çay; actionCount=1
  5. New request context

    Resolve Location on the same origin; use GET with null content and remove content headers.

    Browser / Duru
    GET /notes/atlas-1; no body; awaiting final response
    Atlas routing and policy
    303 ready; Location=/notes/atlas-1
    Resource / connection / session
    Note Çay; actionCount=1
  6. Follow-up request arrived

    The new request reaches the Application with its method/target context and the same reserved authority.

    Browser / Duru
    GET /notes/atlas-1; no body; awaiting final response
    Atlas routing and policy
    GET /notes/atlas-1 received
    Resource / connection / session
    Note Çay; actionCount=1
  7. Endpoint result

    GET selects the note representation without repeating submission.

    Browser / Duru
    Awaiting final response
    Atlas routing and policy
    200 ready; text/plain Çay
    Resource / connection / session
    Note Çay; actionCount=1
  8. Final response arrived

    200 text/plain Çay arrived; intermediate redirect and action state remain separate in the artifact.

    Browser / Duru
    200: Çay; chain complete
    Atlas routing and policy
    200 ready; text/plain Çay
    Resource / connection / session
    Note Çay; actionCount=1

POST → 307 → POST

  1. POST prepared

    Benign JSON is 16 UTF-8 bytes with supplied same-origin routing and a repeatable source.

    Browser / Duru
    POST /note-titles; 16 bytes; awaiting response
    Atlas routing and policy
    No request
    Resource / connection / session
    No note; actionCount=0
  2. Initial POST arrived

    The initial method and content reached the Application without applying the action.

    Browser / Duru
    POST /note-titles; 16 bytes; awaiting response
    Atlas routing and policy
    POST received; content 16 bytes
    Resource / connection / session
    No note; actionCount=0
  3. Server redirect decision

    Legacy route selects 307 before applying the action.

    Browser / Duru
    Awaiting response
    Atlas routing and policy
    307 ready; Location=/note-titles/new
    Resource / connection / session
    No note; actionCount=0
  4. Redirect arrived at the Browser

    Status and relative Location arrived; the follow-up request has not been constructed.

    Browser / Duru
    307 received; Location known
    Atlas routing and policy
    307 ready; Location=/note-titles/new
    Resource / connection / session
    No note; actionCount=0
  5. New request context

    Resolve Location on the same origin; preserve POST and 16-byte body.

    Browser / Duru
    POST /note-titles/new; 16 bytes; awaiting final response
    Atlas routing and policy
    307 ready; Location=/note-titles/new
    Resource / connection / session
    No note; actionCount=0
  6. Follow-up request arrived

    The new request reaches the Application with its method/target context and the same reserved authority.

    Browser / Duru
    POST /note-titles/new; 16 bytes; awaiting final response
    Atlas routing and policy
    POST /note-titles/new received
    Resource / connection / session
    No note; actionCount=0
  7. Endpoint result

    In this selected fixture the new endpoint applies the harmless action once; this count is not a general idempotency guarantee of 307.

    Browser / Duru
    Awaiting final response
    Atlas routing and policy
    200 ready; text/plain Çay
    Resource / connection / session
    Note Çay; actionCount=1
  8. Final response arrived

    200 text/plain Çay arrived; intermediate redirect and action state remain separate in the artifact.

    Browser / Duru
    200: Çay; chain complete
    Atlas routing and policy
    200 ready; text/plain Çay
    Resource / connection / session
    Note Çay; actionCount=1

Close ≠ logout

  1. conn-a and session context

    Connection open; eligibility has not yet been evaluated for this request.

    Browser / Duru
    GET ready; SESSION_REF_ALIAS; awaiting response
    Atlas routing and policy
    No request
    Resource / connection / session
    conn-a open; session active
  2. Request arrived on conn-a

    Alias context is carried without substituting connection identity.

    Browser / Duru
    GET ready; SESSION_REF_ALIAS; awaiting response
    Atlas routing and policy
    GET received; eligibility pending
    Resource / connection / session
    conn-a open; session active
  3. Request policy and response

    Supplied active-session/permission results allow this request; a complete response declares Connection: close.

    Browser / Duru
    Awaiting response
    Atlas routing and policy
    200 ready; Connection: close
    Resource / connection / session
    conn-a open; session active
  4. Complete 200 arrived

    Content arrived completely; the close option ends persistence.

    Browser / Duru
    200 received; close declared
    Atlas routing and policy
    200 ready; Connection: close
    Resource / connection / session
    conn-a open; session active
  5. Transport close event

    A supplied local close observation is neither logout nor expiry; the session record stays active.

    Browser / Duru
    conn-a closed; no logout
    Atlas routing and policy
    First request complete
    Resource / connection / session
    conn-a closed; session active
  6. New transport context

    The fixture supplies open conn-b without drawing a handshake. The same inert session reference is included in the next request.

    Browser / Duru
    New GET ready; conn-b; SESSION_REF_ALIAS; awaiting response
    Atlas routing and policy
    No new request
    Resource / connection / session
    conn-b open; session active
  7. New request arrived on conn-b

    The new GET and SESSION_REF_ALIAS arrived at the Application on conn-b. Eligibility and permission have not been evaluated; those are the next local decision.

    Browser / Duru
    New GET ready; conn-b; SESSION_REF_ALIAS; awaiting response
    Atlas routing and policy
    New GET received; eligibility pending
    Resource / connection / session
    conn-b open; session active
  8. Fresh request eligibility

    Supplied trusted results active=true and permission=true make this request eligible. The browser has not received a second response.

    Browser / Duru
    Awaiting new response
    Atlas routing and policy
    Eligibility rechecked; allowed
    Resource / connection / session
    conn-b open; session active

ACTORS · STATE · DATA FLOW

A redirect asks the client to select another resource

Duru submits the Atlas title form as POST /note-titles with {"title":"Çay"}. The normal branch applies the action and returns 303 See Other with Location: /notes/atlas-1. The browser resolves Location against the current URL and retrieves the result using GET. This second request does not repeat title submission; it retrieves the created note representation. The artifact separates both requests and the intervening redirect response.

307 Temporary Redirect illustrates a different case: the legacy form endpoint redirects to /note-titles/new before applying the action. Automatic following preserves the method and, for this repeatable fixture, its 16-byte JSON body. The new endpoint applies the action once. A redirect is neither an internal function call nor a networkless address-bar change.

General HTTP semantics historically permit a POST→GET change for 301 permanent and 302 temporary redirects without requiring every client to make that optional choice. Browser Fetch specifies GET with null body for POST after 301/302. For 303, Fetch changes methods other than GET/HEAD to GET, leaving HEAD as HEAD. 307/308 preserve methods, with 308 permanent. Repeatable content, redirect mode, and other policy gates still matter.

Fetch follow/error/manual modes expose different information. Error mode takes redirects down a network-error path; ordinary script using manual usually gets an opaque-redirect filtered response rather than an inspector record with readable intermediate Location. This scene explains supplied client behavior rather than providing a DevTools trace or browser Fetch runtime result.

Referer and User-Agent provide context rather than identity

Referer retains its historical single-r field spelling, while Referrer-Policy is a different field. Referer can partially describe the initiating page. Policy and navigation context can omit it, reduce it to an origin, or include path/query; fragments and user information are excluded. Its absence alone proves neither malice nor direct navigation.

User-Agent is software metadata expressed as a character string. Reduction can give many clients in a family similar or identical limited values. It does not prove a real person, account, device ownership, or verified capabilities. HackerDirectoryFixture/1.0 is an inert product token rather than a measured browser UA.

Redirect context is not an automatic copy-and-paste list. Target authority, resource-specific fields, and referrer policy are re-evaluated. Cross-origin credential behavior follows additional browser/API rules. Both redirects here stay on the same HTTPS origin with supplied no-referrer policy; there is no credential-forwarding experiment.

Host describes the intended authority

An origin server can serve several virtual hosts on the same address. HTTP/1.1 Host carries target host/port information to select relevant resources. HTTP/2–3 can use :authority for that control-data role. A connection address and TLS server-identity verification are different layers; URL, Host, and certificate are not one object.

Host: library.atlas.example proves neither Duru’s authentication nor permission to every Atlas resource. Trusted routing configuration determines accepted authorities, with resource permissions decided separately. All benign fixtures use one fixed canonicalAuthority without an alternative-host bypass.

A relative Location is resolved into a new URL. Host remains unchanged here because the new path stays on the same origin. A different origin would require origin-specific context to be re-evaluated rather than blindly using the old Host. WEB-06 URL rules complement these HTTP control-data concepts.

Connection persistence preserves transport resources between messages

HTTP/1.1 can use persistent connections by default. After a complete exchange, the same connection can carry another; Connection: close indicates that persistence ends after the current response. Reuse depends on understood message boundaries and consumed prior bodies. Connections can also close asynchronously, with API pools applying their own policies.

Persistence in HTTP/1.0 requires explicit negotiation, whereas HTTP/1.1 does not require Keep-Alive on every response for default persistence. Keep-Alive can supply timeout/max hints and relates to legacy Connection: keep-alive. A hint guarantees neither future availability nor an application-session idle lifetime. TCP keepalive probes are a separate transport mechanism.

Connection and Keep-Alive are prohibited connection-specific fields in HTTP/2–3 messages. Those versions can carry exchanges on multiple streams; adding HTTP/1.1 headers does not activate multiplexing. This scene uses HTTP/1.1 conn-a/conn-b aliases without running pools, TCP/TLS handshakes, or HTTP/2–3 streams.

Stateless request semantics and a stateful application

HTTP statelessness means each request’s semantics can be understood in its own context. It does not forbid resource databases, session stores, caches, or audits from retaining state. Resending a cookie/session reference and evaluating it against trusted server state/policy provide application continuity.

In the close branch, conn-a closes while the session record remains active because no logout or expiry action was supplied. A later request on conn-b carries the same inert SESSION_REF_ALIAS context again. The Application evaluates eligibility and permission for that request afresh rather than using connection reuse as an identity decision.

Two requests sharing a connection generally do not even guarantee the same user agent; the RFC qualifies secured connections specific to that agent. This fixture does not use connection-level authentication. An active session also does not grant every resource permission; WEB-13.03 and authorization lessons develop those decisions.

2. Red · Trust & Impact

Read every scenario without motion

Close/session

  1. Transport closure was observed in its own record

    The completed response on conn-a carries Connection: close, and that connection becomes closed. SESSION_REF_ALIAS remains active. Transport closure cannot replace a logout or expiry event that was not supplied.

    Request context
    conn-a closed / session active
    Application policy
    Trusted decision pending
    Session boundary
    No application outcome
  2. The old connection did not accept the next request

    The later request carries the session reference over conn-b. The application rechecks eligibility; success on the old connection is insufficient. Resource permission is a separate required decision from connection-reuse hints.

    Request context
    conn-a closed / session active
    Application policy
    Fresh eligibility and resource policy required
    Session boundary
    No application outcome
  3. The active-session scope remained explicit

    The ledger supplies sessionEligibleSupplied and resourcePermissionSupplied as true. Those trusted outcomes support acceptance in this case, not the conn-b label. The alias contains no secret bytes and does not imply creation of a new session.

    Request context
    conn-a closed / session active
    Application policy
    Fresh eligibility and resource policy required
    Session boundary
    Active / supplied eligibility=true / permission=true
  4. Closure was separated from lifecycle events

    logoutSupplied and expirySupplied are false. A closed connection does not establish session termination. Conversely, an open connection guarantees neither an active session nor resource permission.

    Request context
    Close observed / no supplied logout or expiry
    Application policy
    Fresh eligibility and resource policy required
    Session boundary
    Active / supplied eligibility=true / permission=true
  5. Authority stayed with the request’s own predicate

    HTTP stateless semantics do not prohibit an application session ledger. Each protected request still passes its own trusted-context acceptance gate. Treating the network connection as the authenticated subject creates the wrong boundary.

    Request context
    Close observed / no supplied logout or expiry
    Application policy
    Connection ≠ authenticated subject
    Session boundary
    Active / supplied eligibility=true / permission=true
  6. The outcome was stated separately from transport

    In this normal ledger the session stays active after connection closure and is later rechecked. No real session store, browser pool or TCP/TLS was measured. The result explains only the supplied lifecycle and policy predicates.

    Request context
    Close observed / no supplied logout or expiry
    Application policy
    Connection ≠ authenticated subject
    Session boundary
    Close ≠ logout / request policy rechecked

Metadata scope

  1. Client metadata supplied routing context

    Host is library.atlas.example and User-Agent is HackerDirectoryFixture/1.0. Referer is null under the selected no-referrer policy. These fields provide routing or diagnostic context, not a verified account identity.

    Request context
    Host/UA present / Referer null
    Application policy
    Trusted decision pending
    Session boundary
    No application outcome
  2. Routing and identity decisions were evaluated separately

    Host helps select the appropriate virtual host. That selection does not determine which subject may read a resource. An expected User-Agent string likewise cannot replace a trusted principal or resource permission.

    Request context
    Host/UA present / Referer null
    Application policy
    Routing context only / trusted subject separate
    Session boundary
    No application outcome
  3. A missing Referer remained an ordinary condition

    Referer null is an ordinary result of the selected policy in this case. Labeling it unauthenticated or malicious by itself would be incorrect attribution. Session and action authority require their own trusted evidence.

    Request context
    Host/UA present / Referer null
    Application policy
    Routing context only / trusted subject separate
    Session boundary
    Referer absent / authentication not inferred
  4. Relative Location supplied no action authority

    The 303 Location is /notes/atlas-1; the 307 Location is /note-titles/new. Both relative destinations resolve within the same reserved origin. A Location field does not remove the need to check destination contracts or action permission.

    Request context
    303 result route / 307 action route
    Application policy
    Routing context only / trusted subject separate
    Session boundary
    Referer absent / authentication not inferred
  5. Method was separated from the action’s execution time

    The 303 row has actionCountAtRedirect 1, and follow-up GET does not increment it. In the 307 row the count is initially 0 and becomes 1 after preserved POST. Redirect status alone does not establish whether the initial action ran.

    Request context
    303 result route / 307 action route
    Application policy
    303: 1→1 / 307: 0→1
    Session boundary
    Referer absent / authentication not inferred
  6. The review kept metadata distinct from permission

    The same final 200 can follow two different intermediate processing paths. Client metadata, redirects and connection context help explain them. None replaces trusted identity or a resource grant.

    Request context
    303 result route / 307 action route
    Application policy
    303: 1→1 / 307: 0→1
    Session boundary
    Context known / authority must be checked

ASSUMPTION · BOUNDARY · CONTROL

Control redirect destinations and action intent together

A normal 303 moves from a completed submission to a read-only result; 307 moves a pending POST to a new endpoint. Wrong method assumptions can duplicate actions or process an incorrect target. A redirect status alone does not say whether an action has applied; the fixture explicitly supplies the server decision state.

Defensive policy identifies allowed destination mappings, schemes/origins, and endpoint contracts rather than treating a supplied Location string as authorization. Select canonical trusted destinations appropriate to product needs and bound cycles/failures. Both examples use fixed benign same-origin routes without external targets or redirect-bypass workflows.

Do not substitute client metadata or a connection for identity

Referer, User-Agent, and Host supply context, not authenticated subjects. Accepting a protected request solely because its connection succeeded before places trust at the wrong boundary. Impact depends on the protected read/action given incorrect authority.

Keep canonical routing, request-context policy, and trusted session/resource authorization decisions distinct. Reused connections and missing Referer may be operational signals without independently deciding authentication. Transport hints must not replace session-lifecycle gates.

3. Blue · Secure development & defense

Read every scenario without motion

303 result GET

  1. The initial request retained its content

    The normal row describes POST /note-titles with a JSON body whose title is Çay. It occupies 16 UTF-8 bytes. Review identifies this initial method and content before the final response; copying the full body into telemetry is unnecessary.

    Exchange ledger
    POST /note-titles / body 16
    Chain comparison
    Correlation pending
    Evidence verdict
    No delivery verdict
  2. The action count was checked at the 303

    At redirect status 303 and Location /notes/atlas-1, actionCountAtRedirect is 1. The ledger states that the action has executed. That conclusion comes from the separate action-count field, not the status label alone.

    Exchange ledger
    POST /note-titles / body 16
    Chain comparison
    303 / actionCountAtRedirect=1
    Evidence verdict
    No delivery verdict
  3. The follow-up was read as a separate exchange

    The follow-up method is GET, followBody is null and followBodyOctets is 0. The initial POST body does not carry into this GET. Relative Location resolves within the reserved origin; this ledger is not a browser-redirect measurement.

    Exchange ledger
    GET /notes/atlas-1 / body 0
    Chain comparison
    303 / actionCountAtRedirect=1
    Evidence verdict
    No delivery verdict
  4. The read-only follow-up retained the action count

    actionCountAfterFollow remains 1 and finalStatus is 200. The final Çay body occupies 4 UTF-8 bytes. Here the follow-up GET is not another submission; reading method change with the action count makes that distinction visible.

    Exchange ledger
    GET /notes/atlas-1 / body 0
    Chain comparison
    Final 200 / action count remains 1
    Evidence verdict
    No delivery verdict
  5. Chain evidence was not reduced to final status

    Initial POST, 303, GET and count 1→1 are mutually consistent. Observing only the final 200 would leave intermediate method and action timing unknown. The complete authored ledger answers those questions; actual client delivery needs separate observation.

    Exchange ledger
    GET /notes/atlas-1 / body 0
    Chain comparison
    Final 200 / action count remains 1
    Evidence verdict
    303 chain consistent / real delivery unmeasured
  6. Regression preserved the ordinary method transition

    The regression target is POST submission followed by GET result with count remaining 1. For HEAD, 303 retains HEAD; the 301/302 POST rows specify Fetch behavior. That qualification is not generalized into a mandatory rewrite for every HTTP client.

    Exchange ledger
    GET /notes/atlas-1 / body 0
    Chain comparison
    Final 200 / action count remains 1
    Evidence verdict
    POST→GET verified in ledger / count 1→1

307 keeps POST

  1. The method-preserving chain selected its initial request

    The preserve307 row starts with the same POST /note-titles and 16-byte JSON content. At the redirect, actionCountAtRedirect is 0. Issuing the initial POST does not imply that the business action completed.

    Exchange ledger
    POST initial / action count 0
    Chain comparison
    Correlation pending
    Evidence verdict
    No delivery verdict
  2. The 307 predicate compared method and content

    Status 307 with Location /note-titles/new selects a method-preserving follow-up. The method remains POST, followBodyOctets 16 and Content-Type application/json. Repeatable content is explicitly supplied in this fixture.

    Exchange ledger
    POST initial / action count 0
    Chain comparison
    307 / follow POST / body 16
    Evidence verdict
    No delivery verdict
  3. The new endpoint’s action result was recorded separately

    After preserved POST, actionCountAfterFollow becomes 1 and finalStatus is 200. Although the final text is the same Çay as in the 303 case, the exchange where the action executes differs. Final body alone cannot reveal that distinction.

    Exchange ledger
    Follow completed / count 0→1 / final 200
    Chain comparison
    307 / follow POST / body 16
    Evidence verdict
    No delivery verdict
  4. The positive control selected a method mismatch

    The selector’s separate positive XML reports followMethod GET for status 307 with initialMethod POST. XPath selects it as an inconsistent observation. The normal ledger yields zero matches; the positive record is not a claim of a real browser defect.

    Exchange ledger
    Follow completed / count 0→1 / final 200
    Chain comparison
    Normal XPath 0 / positive control 1
    Evidence verdict
    No delivery verdict
  5. A missing intermediate record limited the verdict

    A complete 307 chain supports POST preservation and count 0→1. If the follow-up method or redirect observation is missing, zero matches cannot answer those questions. Final 200 cannot fill an unobserved intermediate stage.

    Exchange ledger
    Follow completed / count 0→1 / final 200
    Chain comparison
    Normal XPath 0 / positive control 1
    Evidence verdict
    Complete chain supports / missing chain UNKNOWN
  6. Diagnostic scope retained minimal context

    Client HTTP observations correlate the initial method, redirect status/Location and follow method/body metadata. Action count comes from the server’s operation record, a separate producer for the same action. Final 200 or absent Referer cannot replace either record.

    Exchange ledger
    Follow completed / count 0→1 / final 200
    Chain comparison
    Normal XPath 0 / positive control 1
    Evidence verdict
    Record method/status/count; exclude secrets

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Read a redirect chain with methods and content

Mark the initial request, redirect status/Location, and follow-up request separately. The normal branch applies one POST then follows with GET and null content; 307 initially applies no action, then preserved POST completion makes the count one. Equal final 200 statuses do not mean equal intermediate processing.

Artifact followMethod/followBodyOctets are an authored decision ledger. The XPath selects status=307 with initialMethod=POST but followMethod!=POST. Negative and positive fixtures yield 0 and 1; a missing event yielding 0 cannot verify a chain. Browser automatic redirects can hide intermediate responses from script, so actual tracing needs an explicit scope.

A handler should select redirect status from the intended next operation. After the note-title POST completes, this example uses 303 to read its result; the follow-up GET does not apply the change again. Continuing an unapplied POST at a new address with the same method and body is the 307 branch. Equal final 200 statuses do not make the implementations equivalent; verify actionCount before and after redirect alongside the follow-up body.

Separate connection events from session decisions

A conn-a closed observation describes transport state; SESSION_REF_ALIAS active describes logical session state. The close branch shows both can simultaneously differ and does not invent a logout request. Eligibility on the later request is a local supplied trusted-result assumption.

Actual telemetry distinguishes reuse, request correlation, selected authority, sanitized user-agent family, and session decision reasons. Avoid logging full referrer queries, credentials, or session secrets. Transient closes, logout, expiry, and denial reasons are normal failure classes rather than proof that every close or 3xx is malicious.

NOW APPLY IT TO THE CASE

Which decisions can redirects, connections and client metadata support?

On the Atlas route, 303 moves from an executed POST to a GET result; 307 carries POST to a new endpoint. Both return Çay. Closing conn-a can leave the session active; a later request passes its own eligibility and resource-policy checks.

Evaluate the case’s 200, media type and parse-error records separately. Use representation rules to identify the remaining condition for usable data.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas route chain and connection/session ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "canonicalAuthority": "library.atlas.example",
  "requestContext": {
    "Host": "library.atlas.example",
    "User-Agent": "HackerDirectoryFixture/1.0",
    "Referer": null,
    "referrerPolicy": "no-referrer",
    "scope": "Supplied benign same-origin client context; no credentials and no measured Browser UA"
  },
  "redirectRows": [
    {
      "case": "normal",
      "initialMethod": "POST",
      "initialUrl": "https://library.atlas.example/note-titles",
      "initialBody": "{\"title\":\"Çay\"}",
      "initialBodyOctets": 16,
      "redirectStatus": 303,
      "location": "/notes/atlas-1",
      "followUrl": "https://library.atlas.example/notes/atlas-1",
      "followMethod": "GET",
      "followBody": null,
      "followBodyOctets": 0,
      "followBodyHeaders": {},
      "actionCountAtRedirect": 1,
      "actionCountAfterFollow": 1,
      "finalStatus": 200,
      "finalBody": "Çay",
      "finalBodyOctets": 4
    },
    {
      "case": "preserve307",
      "initialMethod": "POST",
      "initialUrl": "https://library.atlas.example/note-titles",
      "initialBody": "{\"title\":\"Çay\"}",
      "initialBodyOctets": 16,
      "redirectStatus": 307,
      "location": "/note-titles/new",
      "followUrl": "https://library.atlas.example/note-titles/new",
      "followMethod": "POST",
      "followBody": "{\"title\":\"Çay\"}",
      "followBodyOctets": 16,
      "followBodyHeaders": {
        "Content-Type": "application/json"
      },
      "actionCountAtRedirect": 0,
      "actionCountAfterFollow": 1,
      "finalStatus": 200,
      "finalBody": "Çay",
      "finalBodyOctets": 4
    }
  ],
  "redirectMethodMatrix": [
    {
      "status": 301,
      "initialMethod": "POST",
      "fetchFollowMethod": "GET",
      "fetchBodyRemoved": true,
      "genericHttpQualification": "HTTP permits historical POST-to-GET change; this row specifies Fetch behavior"
    },
    {
      "status": 302,
      "initialMethod": "POST",
      "fetchFollowMethod": "GET",
      "fetchBodyRemoved": true,
      "genericHttpQualification": "HTTP permits historical POST-to-GET change; this row specifies Fetch behavior"
    },
    {
      "status": 303,
      "initialMethod": "POST",
      "fetchFollowMethod": "GET",
      "fetchBodyRemoved": true,
      "genericHttpQualification": "Fetch changes methods other than GET/HEAD to GET"
    },
    {
      "status": 303,
      "initialMethod": "HEAD",
      "fetchFollowMethod": "HEAD",
      "fetchBodyRemoved": false,
      "genericHttpQualification": "HEAD remains HEAD; no request body supplied"
    },
    {
      "status": 307,
      "initialMethod": "POST",
      "fetchFollowMethod": "POST",
      "fetchBodyRemoved": false,
      "genericHttpQualification": "Method-preserving, repeatable fixture content supplied"
    },
    {
      "status": 308,
      "initialMethod": "POST",
      "fetchFollowMethod": "POST",
      "fetchBodyRemoved": false,
      "genericHttpQualification": "Method-preserving permanent redirect, repeatable fixture content supplied"
    }
  ],
  "http11Illustration": {
    "initialRequest": "POST /note-titles HTTP/1.1\r\nHost: library.atlas.example\r\nUser-Agent: HackerDirectoryFixture/1.0\r\nContent-Type: application/json\r\nContent-Length: 16\r\n\r\n{\"title\":\"Çay\"}",
    "redirect303": "HTTP/1.1 303 See Other\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nLocation: /notes/atlas-1\r\nContent-Length: 0\r\n\r\n",
    "followGet": "GET /notes/atlas-1 HTTP/1.1\r\nHost: library.atlas.example\r\nUser-Agent: HackerDirectoryFixture/1.0\r\n\r\n",
    "dateIsSynthetic": true
  },
  "connectionSession": {
    "protocol": "HTTP/1.1",
    "initialConnection": "conn-a",
    "initialConnectionState": "open",
    "responseConnectionField": "close",
    "afterCompleteResponseConnectionState": "closed",
    "sessionRef": "SESSION_REF_ALIAS",
    "sessionStateBefore": "active",
    "sessionStateAfterClose": "active",
    "logoutSupplied": false,
    "expirySupplied": false,
    "laterConnection": "conn-b",
    "laterConnectionState": "open",
    "laterRequestCarriesSessionRef": true,
    "laterEligibilityRechecked": true,
    "sessionEligibleSupplied": true,
    "resourcePermissionSupplied": true,
    "ordinaryConnectionIsSessionIdentity": false
  },
  "selector": {
    "language": "XPath",
    "xml": "<observations><redirect status=\"303\" initialMethod=\"POST\" followMethod=\"GET\"/><redirect status=\"307\" initialMethod=\"POST\" followMethod=\"POST\"/></observations>",
    "xpath": "count(/observations/redirect[@status=\"307\" and @initialMethod=\"POST\" and @followMethod!=\"POST\"])",
    "expected": 0,
    "positiveFixtureXml": "<observations><redirect status=\"307\" initialMethod=\"POST\" followMethod=\"GET\"/></observations>",
    "positiveExpected": 1,
    "scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
    "missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
  }
}
redirectRows
Initial exchange, follow-up, and action counts kept separate; not a measured trace.
redirectMethodMatrix
Fetch behavior distinguished from general HTTP optional POST rewrite qualifications.
requestContext
Supplied Host/UA and no-referrer context do not establish identity.
connectionSession
Close changes transport state; an active session and fresh request policy remain distinct.

Same reserved HTTPS origin, benign repeatable content, and secret-free aliases. No native browser redirects/pools, TCP/TLS, or real session store runs. Trusted eligibility/permission results are supplied assumptions.

Two reality checks

Every redirect changes POST to GET.

This POST becomes GET after 303; 307/308 preserve its method. General HTTP permits historical optional behavior for 301/302, while Fetch specifies POST rewriting.

Keep-Alive keeps me logged in, and closing a connection ends my session.

Persistence concerns transport resources. Session expiry/logout are separate application-state decisions; the fixture retains an active session when conn-a closes.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

What method/body does the follow request use in the selected POST 307 redirect?

  1. It becomes GET and drops the body; every redirect behaves alike.
  2. POST and the same repeatable JSON body are preserved.
Read the explained answer

POST and the same repeatable JSON body are preserved. — The selected preserve307 row has followMethod=POST and sixteen body octets.

Is connection close evidence of session logout?

Selected lesson artifact fields; teaching example

connectionSession.afterCompleteResponseConnectionState
closed
connectionSession.sessionStateAfterClose
active
connectionSession.logoutSupplied
false
  1. No; the connection is closed while the selected session stays active.
  2. Yes; the TCP connection itself is the session identity.
Read the explained answer

No; the connection is closed while the selected session stays active. — Neither logout nor expiry is supplied. Later conn-b carries the session reference and rechecks eligibility/permission.

Referer is null and User-Agent is a fixture string. Can these serve as authenticated-user or intent evidence?

Read the explained answer

Referer may be null because of no-referrer policy; User-Agent is a client description. Neither establishes an authenticated principal or action permission. Host specifies selected authority-routing context and does not replace server identity/session/authorization validation.

□ I did not treat absent Referer as anomaly or identity evidence.

□ I did not substitute header metadata for permission.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope