Skip to content

Documented js_access directive and r.readRequest* methods in njs.#272

Open
xeioex wants to merge 2 commits intonginx:mainfrom
xeioex:js_access
Open

Documented js_access directive and r.readRequest* methods in njs.#272
xeioex wants to merge 2 commits intonginx:mainfrom
xeioex:js_access

Conversation

@xeioex
Copy link
Copy Markdown
Collaborator

@xeioex xeioex commented May 6, 2026

No description provided.

@xeioex xeioex requested a review from y82 May 6, 2026 00:15
@xeioex xeioex requested a review from VadimZhestikov May 6, 2026 00:18
@VadimZhestikov
Copy link
Copy Markdown
Contributor

Issues Found

In the js_access example (ngx_http_js_module.xml):

  async function auth(r) {
      let reply = await ngx.fetch('http://authsvc/check', {
          headers: {Authorization: r.headersIn.Authorization}
      });

      if (reply.status != 200) {
          r.return(401);
      }
  }

After r.return(401), execution falls through to normal function completion, which grants access according to the documented semantics ("on normal completion the handler grants access"). This
means a failed auth check would send a 401 response body but still pass the access phase.

Alphabetical Ordering in the Index Table (moderate)

In reference.xml, the four new readRequest* entries are inserted after r.remoteAddress:

  <tr><td>r.remoteAddress</td></tr>   ← rem
  <tr><td>r.readRequestArrayBuffer()</td></tr>  ← rea  ← should be BEFORE

  rea < rem alphabetically, so all four r.readRequest* entries should be placed before r.remoteAddress, not after it.

"and friends" — Informal Language (minor)

In the updates to r.requestBody and r.requestText:

  see <link ...>r.readRequestText()</link>
  and friends.

"And friends" is too informal for reference documentation. Prefer: "and the related r.readRequest* methods" or list them explicitly.

maxKeys Option — Incomplete Description (minor)

The maxKeys option for r.readRequestForm() only says "caps the number of fields parsed from the form" with no mention of:

  • Default value (or that there is no limit by default)
  • Behavior when the cap is reached (silent truncation vs. error)

r.return() Amendment — Missing Wrapper (minor)

The new sentence appended to the r.return() :

  +May be called from the
  +<link .../js_content/> or, since 0.9.9, <link .../js_access/> handler.
   <para>
   It is possible to specify a redirect URL..

This text is appended directly to the <tag-desc> body without a <para> wrapper, while the rest of the entry uses <para>. Wrapping it in <para> would be consistent with the surrounding content.

js_access Syntax — Intentional Restriction Undocumented (minor)

js_content accepts both function and module.function, but js_access only accepts module.function. If this restriction is intentional it should be noted explicitly, e.g. "Unlike js_content, only
the module.function form is accepted."


Missing Russian Translation for reference.xml (minor)

The diff updates xml/ru/docs/http/ngx_http_js_module.xml but not xml/ru/docs/njs/reference.xml. If a Russian version of the reference exists, it should cover r.decline() and the readRequest*
methods too.


What's Done Well

  • Cross-references between readRequest* methods are clean: ArrayBuffer, JSON, and Form all defer to readRequestText() for availability/caching/concurrency semantics — avoids duplicating prose.
  • The security note on readRequestForm() ("The filename is client-supplied and is not sanitized.") is important and correctly placed.
  • Caching and concurrency semantics (body cached after first read, concurrent reads throw) are clearly documented.
  • The r.decline() / satisfy any interaction is well explained with proper cross-links.
  • Russian translation is structurally identical to the English, including the example.

Summary

In the code example — as written, it implies that calling r.return(401) is sufficient to deny access, which contradicts the
documented "normal completion grants access", it is not clear if "normal completion" is about function completion, or something else. The alphabetical ordering of the index table is also worth fixing before merge. The remaining items are style/completeness nits.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

async function auth(r) {
let reply = await ngx.fetch('http://authsvc/check', {
headers: {Authorization: r.headersIn.Authorization}
});

  if (reply.status != 200) {
      r.return(401);
  }

}

After r.return(401), execution falls through to normal function completion, which grants access according to the documented semantics ("on normal completion the handler grants access"). This
means a failed auth check would send a 401 response body but still pass the access phase.

The example as written denies access correctly. The access handler then returns 401.

That said, the wording "On normal completion the handler grants access" reads ambiguously, which is what made the example look broken. Reworded to make the precondition explicit:

"A handler that returns without calling r.return() or r.decline() grants access."

Also added an explicit return after r.return(401) in the example so the early-exit pattern is obvious and the snippet stays composable if more logic is added below.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

In reference.xml, the four new readRequest* entries are inserted after r.remoteAddress:

corrected.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

"And friends" is too informal for reference documentation.

We do this in commit log regularly, but yes, not in the reference. corrected.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

The maxKeys option for r.readRequestForm() only says "caps the number of fields parsed from the form" with no mention of:

Default value (or that there is no limit by default)
Behavior when the cap is reached (silent truncation vs. error)

added the default and what happens when cap is reached.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

r.return() Amendment — Missing Wrapper (minor)

added tags.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

js_content accepts both function and module.function, ..."

this is incorrect for english version. But this still exists in Russian documentation, corrected with a separate commit.

@xeioex
Copy link
Copy Markdown
Collaborator Author

xeioex commented May 6, 2026

Missing Russian Translation for reference.xml (minor)

The Russian version of the references, does not exist. this is a separate task.

Copy link
Copy Markdown
Contributor

@VadimZhestikov VadimZhestikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants