Skip to content

Fix IPP request op handling; add Destination attr fetch convenience API#9

Open
Abd002 wants to merge 2 commits intoOpenPrinting:mainfrom
Abd002:main
Open

Fix IPP request op handling; add Destination attr fetch convenience API#9
Abd002 wants to merge 2 commits intoOpenPrinting:mainfrom
Abd002:main

Conversation

@Abd002
Copy link
Copy Markdown
Contributor

@Abd002 Abd002 commented Jan 30, 2026

This PR includes two related changes:

  1. Fix IPP request copying in src/ipp.rs
    IppRequest::send() previously copied requests using ippNew() which does not preserve the operation code. This caused cupsDoRequest() to receive an invalid/empty request for custom operations in some cases.
    Now we grab the op via ippGetOperation() and copy using ippNewRequest(op), ensuring the request sent to CUPS has a valid operation code.

  2. Convenience API for fetching printer attributes
    Adds AttrKind/AttrSpec and Destination::get_attrs() to request missing printer attributes and automatically populate dest.options. This avoids forcing callers to hand-roll IPP requests just to fetch a couple of fields.

Why

  • Makes custom IPP requests behave reliably by preserving the operation code.
  • Reduces boilerplate for common “fetch a few attrs” use cases.

@Abd002 Abd002 marked this pull request as draft January 30, 2026 17:59
@Gmin2
Copy link
Copy Markdown
Collaborator

Gmin2 commented Jan 31, 2026

Hey, little out of sync with this pr, can you explain to me what you are trying to achieve !, I might be completely off track with this !

@Abd002
Copy link
Copy Markdown
Contributor Author

Abd002 commented Jan 31, 2026

The goal is basically to make two things work reliably:
1. ipp.rs fix (must-have):
Right now IppRequest::send() copies the request using ippNew(), which creates an IPP message without the operation code. So when you call cupsDoRequest(), the server can treat it like an empty/invalid request and you don’t get the expected attributes (I hit this when trying GetJobs / custom requests).
The fix is to copy with ippNewRequest(ippGetOperation(original)) so the duplicated request is still a valid IPP request.

  1. Destination::get_attrs convenience:
    This is just to reduce boilerplate for common cases where you only need a couple printer attrs (state message, member-names, etc). Instead of every caller building a full Get-Printer-Attributes request manually, get_attrs() fetches whatever is missing and fills dest.options.
    I’m using it in the lpstat example, it makes the implementation cleaner, but it’s optional and doesn’t change existing behavior.

If you want, I can split it into two PRs (one for the ipp.rs fix, one for the get_attrs helper). The ipp.rs one is definitely required.

@Gmin2
Copy link
Copy Markdown
Collaborator

Gmin2 commented Feb 4, 2026

Okay can yu add an example of how previously it was failing and how the new archi fixed that, like working one and give some sc

@Abd002
Copy link
Copy Markdown
Contributor Author

Abd002 commented Feb 4, 2026

test scenario I used (local CUPS):

  • Setup: CUPS running with a PDF queue at ipp://localhost/printers/PDF.
  • Command: cargo run --example fix_explane (builds a Get-Jobs IPP request via IppRequest::new(IppOperation::GetJobs) and sends it with cupsDoRequest()).

Before the fix: IppRequest::send() duplicated the request with ippNew(), which drops the operation code → CUPS receives an “empty/invalid” request and replies ErrorBadRequest (seen in the first run screenshot).

After the fix: duplicate via ippNewRequest(ippGetOperation(original)) so the op is preserved → the same example returns real job attributes (e.g. job-id / job-state printed in the second run screenshot).
Screenshot 2026-02-04 233526

@Abd002
Copy link
Copy Markdown
Contributor Author

Abd002 commented Feb 4, 2026

For the second change: it’s just a small convenience wrapper. Destination::get_attrs() fetches only the missing printer attributes via a Get-Printer-Attributes request and then populates dest.options, so callers don’t have to hand-build IPP requests for common fields.
Example usage:

 let attrs = [
   AttrSpec { name: "printer-state-reasons", kind: AttrKind::StringLike },
   AttrSpec { name: "printer-state-change-time", kind: AttrKind::IntegerLike },
   AttrSpec { name: "member-names", kind: AttrKind::StringLike }, <- likely for classes
 ];
 dest.get_attrs(&conn, &attrs)?;

This keeps examples (lpstat -> Currently working on) much cleaner without changing existing behavior.
Screenshot 2026-02-04 234140

@Abd002 Abd002 marked this pull request as ready for review February 4, 2026 22:05
@bakayu
Copy link
Copy Markdown

bakayu commented Feb 7, 2026

IppRequest::send() previously copied requests using ippNew() which does not preserve the operation code. This caused cupsDoRequest() to receive an invalid/empty request for custom operations in some cases.
Now we grab the op via ippGetOperation() and copy using ippNewRequest(op), ensuring the request sent to CUPS has a valid operation code.

I faced this exact same issue today, @Abd002 your solution seemed to have fixed it, I tested it on my local. Waiting for this to get merged.

cc: @Gmin2

@Gmin2
Copy link
Copy Markdown
Collaborator

Gmin2 commented Feb 11, 2026

#10 (comment)

@Abd002 Abd002 force-pushed the main branch 4 times, most recently from 16b7836 to 1c4ca08 Compare March 11, 2026 21:09
@Abd002
Copy link
Copy Markdown
Contributor Author

Abd002 commented Mar 11, 2026

@Gmin2 I’ve updated this PR and added tests to make the change easier to review and to show the intended behavior more clearly.

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.

3 participants