Git Product home page Git Product logo

go-ipp's Introduction

go-ipp

Version Documentation Go Report Card Licence

Go Get

To get the package, execute:

go get -u github.com/phin1x/go-ipp

Features

  • only depends on the standard go library (only dependency is for testing)
  • basic ipp 2.0 compatible Client
  • extended client for cups server
  • create custom ipp requests
  • parse ipp responses and ipp control files

Example

Print a file with the ipp client

package main

import "github.com/phin1x/go-ipp"

func main() {
    // create a new ipp client
    client := ipp.NewIPPClient("printserver", 631, "user", "password", true)
    // print file
    client.PrintFile("/path/to/file", "my-printer", map[string]interface{}{})
}

Craft and send a custom request

package main

import "github.com/phin1x/go-ipp"

func main() {             
    // define a ipp request
    req := ipp.NewRequest(ipp.OperationGetJobs, 1)
    req.OperationAttributes[ipp.AttributeWhichJobs] = "completed"
    req.OperationAttributes[ipp.AttributeMyJobs] = myJobs
    req.OperationAttributes[ipp.AttributeFirstJobID] = 42
    req.OperationAttributes[ipp.AttributeRequestingUserName] = "fabian"
    
    // encode request to bytes
    payload, err := req.Encode()
    if err != nil {
        panic(err)
    }
    
    // send ipp request to remote server via http
    httpReq, err := http.NewRequest("POST", "http://my-print-server:631/printers/my-printer", bytes.NewBuffer(payload))
    if err != nil {
        panic(err)
    }
    
    // set ipp headers
    httpReq.Header.Set("Content-Length", len(payload))
    httpReq.Header.Set("Content-Type", ipp.ContentTypeIPP)
    
    httpClient := &http.Client()
    httpResp, err := httpClient.Do(httpReq)
    if err != nil {
        panic(err)
    }
    defer httpResp.Body.Close()
    
    // response must be 200 for a successful operation
    // other possible http codes are: 
    // - 500 -> server error
    // - 426 -> sever requests a encrypted connection
    // - 401 -> forbidden -> need authorization header or user is not permitted
    if httpResp.StatusCode != 200 {
        panic("non 200 response from server")
    }
    
    // decode ipp response
    resp, err := ipp.NewResponseDecoder(httpResp.Body).Decode(nil)
    if err != nil {
        panic(err)
    }
    
    // check if the response status is "ok" 
    if err := resp.CheckForErrors(); err != nil {
        panic(err)
    }
    
    // do something with the returned data
    for _, job := resp.JobAttributes {
        // ...
    }
}

Licence

Apache Licence Version 2.0

go-ipp's People

Contributors

dennisoehme avatar gregory112 avatar guilyx avatar jameshalsall avatar korylprince avatar muesli avatar nirnanaaa avatar phin1x avatar the-goodies avatar willglynn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

go-ipp's Issues

Unable to get printer list

Getting error while decoding the response for OperationCupsGetPrinters

runtime error: makeslice: len out of range

Using without cups

I'm hoping to use this from Windows or from a container environment that does not have cups.

Noticed the PrintJob function eventually refer to localhost. Am I wrong in thinking that at least in principle, IPP is not tied to cups?

Question regarding tests

Hi
I guess there were a lot of of tests for this package
But only one was added to repository
Are you going to add existing tests?
Thanks

Setting collections attributes?

Thank you for making this library, it has helped so far a lot however I have a question regarding nesting/collections. For example, below is a config file used for testing in IPP tool where in the collection for media-col I would set the paper size dimensions. How is this achieved using this tool?

{
    VERSION 2.0
    OPERATION Print-Job

    GROUP operation-attributes-tag
    ATTR charset attributes-charset utf-8
    ATTR language attributes-natural-language en
    ATTR mimeMediaType document-format application/pdf
    ATTR uri printer-uri $uri
    ATTR enum orientation-requested 4

    GROUP job-attributes-tag
    ATTR keyword print-scaling none
    ATTR collection media-col {
        MEMBER keyword media-source "by-pass-tray"
        MEMBER collection media-size {
            MEMBER integer x-dimension 13510
            MEMBER integer y-dimension 14800
        }
    }

    FILE $filename
}

ipp client to printer

Hi,
I'm quite new to go and just starting with ipp, so please forgive my ignorance. I have a project where one of the goals is to print pdf & text files directly to a printer with some options like tray selection. Printers have ipp build in, so I was hoping to use your library to do that, but it seems that ipp client is geared towards a (local?) cups server - when trying to GetPrinterAttributes, getPrinterUri always returns "localhost/" and "printers/" uri, and getHttpUri will return host:port but again + hardcoded "printers/" + printer name, which for direct connection to the printer will not work, as far as I can tell. I believe it should be "host:port/ipp/print" for both http uri & printer uri. I'm basing my statement on my tests with ippserver from https://github.com/istopwg/ippsample.
So, I guess the question should be, is my assumption that ipp client is not able to connect to printer directly correct, or am I missing something, and if so, could you please point me in the right direction?

Thanks,
art

Lack of tests

I really like this module, but I don't feel 100% confident when updating it because of the lack of tests.

Ideally we want tests for:

  • request encoding
  • request decoding
  • client (against a mock IPP server)

We could do this gradually over time, maybe starting with the request encoding/decoding as a priority.

If you've done any work on testing outside of this module, or have a collection of example payloads we can use as fixtures, I'm happy to make a start.

help, can't print pdf with my hp1020

Dear, very new to IPP, when use above sample code to send pdf to my CUPS server, and specifid printer HP 1020, it didn't work.
so I wonder if IPP command trig CUPS filter process? Or I have to send pbm to directly? (acutally, it didn't work either)

thanks for your advise.

With #3 landed, I'm able to use go-ipp to print documents with arbitrary attributes by assembling the pieces myself:

req := ipp.NewRequest(ipp.OperationPrintJob, 1)
req.OperationAttributes["printer-uri"] = "ipp://localhost/printers/" + printerName
req.OperationAttributes["job-name"] = "Label"
req.OperationAttributes["document-format"] = "application/pdf"
req.JobAttributes["media"] = "w36h136"
req.JobAttributes["orientation-requested"] = 4
req.JobAttributes["scaling"] = 100
req.File = bytes.NewReader(buf)
req.FileSize = len(buf)
resp, err := c.SendRequest("http://localhost:631/printers/"+printerName, req)
jobID := resp.Jobs[0]["job-id"][0].Value.(int)

This PR adds a PrintJob() function to IPPClient, which allows me to write instead:

c := ipp.NewIPPClient("localhost", 631, "", "", false)

document := ipp.Document{
	Document: bytes.NewReader(buf),
	Size:     len(buf),
	Name:     "Label",
	MimeType: "application/pdf",
}

jobID, err := c.PrintJob(document, printerName, map[string]interface{}{
	"media":                 "w36h136",
	"orientation-requested": 4,
	"scaling":               100,
})

PrintJob() is higher level and requires less domain knowledge than constructing a whole ipp.OperationPrintJob request from scratch, while retaining the ability to specify job attributes and to perform the operation in a single request.

Missing printer-is-default Attribute

Hi @phin1x πŸ‘‹πŸ»

As far as I've read & checked, there is no available attribute to extract / get the default printer. Is it possible to get the default one from all of the connected printers?

Please help.
Thanks.

panics and/or EOF errors during GetPrinters request

(possibly connected with #29)

Present implementation of the http-based adapter has a strange behaviour with a partial or erroneous get printer list response. The GetPrinters request return only a part of the entire printers list or panics with "makeslice: len out of range" / completes with an EOF error. The source of the issue seems to be at AttributeDecoder#decodeString method where the number of read bytes is ignored but sometimes the actual number of read bytes is less than the provided slice length.

There is a possible work-around - read entire CUPS response into a []byte slice and to ResponseDecoder.Decode() not the original http.Response.Body but the bytes.NewReader of the slice.

The behaviour can be reproduced with: https://github.com/kruftik/go-ipp-panics-repro

Why no print-color-mode attribute?

I'm wondering how to request color printing using this library. From this page, it seems like I set the "print-color-mode" attribute to "color" in the request. However, I didn't find the string "print-color-mode" anywhere in this library, leading me to think that maybe I shouldn't hard-code it in my own application either. Why isn't that string anywhere in this library?

panic: runtime error: makeslice: len out of range

The length returned by the readValueLength function in attribute.go is negative in some cases, resulting in an error in make in the decodeString function

Error info:

panic: runtime error: makeslice: len out of range

goroutine 15 [running]:
github.com/phin1x/go-ipp.(*AttributeDecoder).decodeString(0xc00051fc10, 0xc000016a00, 0x200a, 0x0, 0x0)
/root/go/pkg/mod/github.com/phin1x/[email protected]/attribute.go:456 +0xc5
github.com/phin1x/go-ipp.(*AttributeDecoder).Decode(0xc00004cc10, 0xc000428518, 0x1, 0x1, 0x1)
/root/go/pkg/mod/github.com/phin1x/[email protected]/attribute.go:411 +0x163
github.com/phin1x/go-ipp.(*RequestDecoder).Decode(0xc00051fc80, 0x818e80, 0xc000072bd0, 0x8, 0xc00004cbe8, 0x6ada57)
/root/go/pkg/mod/github.com/phin1x/[email protected]/request.go:201 +0x331

Unexpected EOF

Hi,

I'm having a little issue with the sample code thats provided in the readme.

I'm trying to print a simple PDF document as following:

package main

import (
	"fmt"

	"github.com/phin1x/go-ipp"
)

func main() {
	// create a new ipp client
	client := ipp.NewIPPClient("10.0.2.18", 631, "", "", false)
	// print file
	int, err := client.PrintFile("Invoice.pdf", "lp1", map[string]interface{}{})

	fmt.Println(int, err)
}

But for some reason the output of the Println ends up with -1 for the returned integer and EOF for the error. Am I overseeing something?

Thanks in advance,
Ramon

Get all printers using IPP

Hello,
I am trying to

  • get all the printers on cups server.
  • get the state of printer.
  • if state = pause then resume or resume all.
    Would be grateful if get example. I tried IPP package but failed to import package and use the func get printers.
    Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.