harwey / cups4j

Cups4j Java printing library for CUPS/IPP
http://cups4j.org
GNU Lesser General Public License v3.0
130 stars 64 forks source link

URLs instead of URIs #34

Open grenik opened 4 years ago

grenik commented 4 years ago

RFC says:

  • Each Printer object is identified with one or more URIs. The Printer's "printer-uri-supported" attribute contains the URI(s).

However, you use URLs, not URIs. Since ipp:// is not a valid protocol for a java.net.URL class, you simply replace ipp with http. This is already error-prone since some printers URIs have ipps:// protocol and you fail to process them.

To prove the issue, you can call getDefaultPrinter() on a cups client with 127.0.0.1 as host and 631 as port. You will get the following error:

java.net.MalformedURLException: unknown protocol: ipps
    at java.net.URL.<init>(URL.java:618)
    at java.net.URL.<init>(URL.java:508)
    at java.net.URL.<init>(URL.java:457)
    at org.cups4j.operations.cups.CupsGetDefaultOperation.getDefaultPrinter(CupsGetDefaultOperation.java:62)
    at org.cups4j.CupsClient.getDefaultPrinter(CupsClient.java:154)

If you use localhost as the host, you won't get an error.

In addition to that, I see that to compare two URLs you call toString() on them and compare the resulting strings which doesn't seem right. Maybe you are doing the comparison this way because equals cannot be used on java.net.URL since it has some issues (tries to resolve the hostname to an IP address).

Since URIs in IPP have the same meaning as java.net.URI in Java (they both conform to RFC2396), I suggest that you switch to java.net.URI. You won't have issues with ipp(s) protocol and could also use equals() to compare them because it is not broken as in java.net.URL.

harwey commented 4 years ago

Hi Nikolay, this seem reasonable to me. I iwll take a look - hopefully soon. I sadly don't have much time for Cups4j, and with Corona around things don't get better. I will try to look at this soon. Thanks for your message! Harald

gmuth commented 3 years ago

I can't provide a fix for this library, but a potential solution for your use case, grenik: With Corona around I had time to reimplement a new IppClient from scratch in Kotlin that supports ipps and also includes a CupsClient.