2 Commits

40 changed files with 204 additions and 576 deletions

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
@@ -36,32 +34,9 @@ func (b *Boolean) valueTag() tag {
return booleanValueTag return booleanValueTag
} }
func unmarshalSingleAttribute(byteStream io.Reader) (string, []byte) {
var length uint16
binary.Read(byteStream, binary.BigEndian, &length)
attributeName := make([]byte, length)
if length > 0 {
binary.Read(byteStream, binary.BigEndian, attributeName)
}
binary.Read(byteStream, binary.BigEndian, &length)
attributeValue := make([]byte, length)
binary.Read(byteStream, binary.BigEndian, attributeValue)
return string(attributeName), attributeValue
}
func (b *Boolean) unmarshal(byteStream io.Reader) { func (b *Boolean) unmarshal(byteStream io.Reader) {
name, data := unmarshalSingleAttribute(byteStream)
var length uint16 b.name = name
binary.Read(byteStream, binary.BigEndian, &length)
attributeName := make([]byte, length)
if length > 0 {
binary.Read(byteStream, binary.BigEndian, attributeName)
}
b.name = string(attributeName)
binary.Read(byteStream, binary.BigEndian, &length)
data := make([]byte, length)
binary.Read(byteStream, binary.BigEndian, data)
//name, data := unmarshalSingleAttribute(byteStream)
if data[0] == 0 { if data[0] == 0 {
b.value = false b.value = false
return return
@@ -84,3 +59,8 @@ func (b *Boolean) marshal() []byte {
} }
return buf.Bytes() return buf.Bytes()
} }
func (b *Boolean) size() int {
l := 5 + len(b.name)
return l
}

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
type charsetAttribute struct { type charsetAttribute struct {

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
@@ -45,3 +43,10 @@ func (c *CharSetValue) marshal() []byte {
func (c *CharSetValue) marshalInto([]byte) int { func (c *CharSetValue) marshalInto([]byte) int {
return 0 return 0
} }
func (c *CharSetValue) size() int {
l := 1 + 4 // The attribute tag + 2 lengths
l += len(c.name)
l += len(c.value)
return l
}

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,94 +0,0 @@
34
00 00
00 11 // Name length
6d 65 64 69 61 2d 63 6f 6c 2d 64 65 66 61 75 6c 74 // "media-col-default"
00 00 // Always zero
4a // Collection member
00 00 // Always zero
00 0a // Value length
6d 65 64 69 61 2d 74 79 70 65 // "media-type"
44 // Keyword
00 00 00 0a
73 74 61 74 69 6f 6e 65 72 79 // "stationery"
4a // Collection member
00 00 // Always zero
00 0a // Value length
6d 65 64 69 61 2d 73 69 7a 65 // Member name "media-size"
34 // Begin Collection
00 00 // Name Length (In this case there is no name)
00 00 // Always zero
4a
00 00
00 0b
78 2d 64 69 6d 65 6e 73 69 6f 6e // "x-dimension"
21 // Integer value
00 00
00 04
00 00 52 08
4a
00 00
00 0b
79 2d 64 69 6d 65 6e 73 69 6f 6e // "y-dimension"
21 // Integer value
00 00
00 04
00 00 74 04
37 00 00 00 00 // End
4a
00 00
00 13
6d 65 64 69 61 2d 62 6f 74 74 6f 6d 2d 6d 61 72 67 69 6e // "media-bottom-margin"
21
00 00
00 04
00 00 01 b0
4a
00 00
00 11
6d 65 64 69 61 2d 6c 65 66 74 2d 6d 61 72 67 69 6e
21
00 00
00 04
00 00 01 b0
4a
00 00
00 12
6d 65 64 69 61 2d 72 69 67 68 74 2d 6d 61 72 67 69 6e // "media-right-margin"
21 00 00 00 04 00 00 01 b0
4a
00 00
00 10
6d 65 64 69 61 2d 74 6f 70 2d 6d 61 72 67 69 6e
21 00 00 00 04 00 00 01 b0
4a
00 00
00 0c
6d 65 64 69 61 2d 73 6f 75 72 63 65 // "media-source"
44 // Keyword
00 00
00 04
61 75 74 6f // "auto"
37 00 00 00 00 // End
23 00 1d 6f 72 69 65 6e 74 61 74 69 6f 6e 2d 72 65
From ipptool
media-col-default (collection) =
{media-type=stationery media-size={x-dimension=21000 y-dimension=29700}
media-bottom-margin=432
media-left-margin=432
media-right-margin=432
media-top-margin=432 media-source=auto}

View File

@@ -1,9 +1,6 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"fmt" "fmt"
) )
@@ -31,6 +28,10 @@ func (e *Enum) valueTag() tag {
return enumValueTag return enumValueTag
} }
func (e *Enum) size() int {
return 9 + len(e.name)
}
func (e *Enum) addValue(v interface{}) { func (e *Enum) addValue(v interface{}) {
e.values = append(e.values, v.(int32)) e.values = append(e.values, v.(int32))
} }
@@ -38,11 +39,3 @@ func (e *Enum) addValue(v interface{}) {
func (e *Enum) marshal() []byte { func (e *Enum) marshal() []byte {
return marshalInteger(enumValueTag, e.name, e.values) return marshalInteger(enumValueTag, e.name, e.values)
} }
func (e *Enum) unmarshal(byteStream *bufio.Reader) {
soi, err := unmarshalIntegers(byteStream, integerValueTag)
if err != nil {
return
}
e.values = soi.values
}

View File

@@ -1,12 +1,10 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io"
) )
type Integer struct { type Integer struct {
@@ -33,6 +31,10 @@ func (i *Integer) valueTag() tag {
return integerValueTag return integerValueTag
} }
func (i *Integer) size() int {
return 9 + len(i.name) // The attribute tag + 2 lengths
}
func (i *Integer) addValue(v interface{}) { func (i *Integer) addValue(v interface{}) {
i.values = append(i.values, v.(int32)) i.values = append(i.values, v.(int32))
} }
@@ -41,15 +43,6 @@ func (i *Integer) marshal() []byte {
return marshalInteger(integerValueTag, i.name, i.values) return marshalInteger(integerValueTag, i.name, i.values)
} }
func (i *Integer) unmarshal(byteStream *bufio.Reader) {
soi, err := unmarshalIntegers(byteStream, integerValueTag)
if err != nil {
return
}
i.name = soi.name
i.values = soi.values
}
func marshalInteger(t tag, name string, values []int32) []byte { func marshalInteger(t tag, name string, values []int32) []byte {
l := 9 + len(name) + 9*(len(values)-1) l := 9 + len(name) + 9*(len(values)-1)
b := make([]byte, 0, l) b := make([]byte, 0, l)
@@ -67,3 +60,8 @@ func marshalInteger(t tag, name string, values []int32) []byte {
} }
return buf.Bytes() return buf.Bytes()
} }
func unmarshalSingleInteger(byteStream io.Reader) (string, int32) {
name, data := unmarshalSingleAttribute(byteStream)
return name, int32(binary.BigEndian.Uint32(data))
}

View File

@@ -1,9 +1,6 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"bytes" "bytes"
"testing" "testing"
@@ -19,12 +16,10 @@ func TestUnMarshalSinglePositiveInteger(T *testing.T) {
} }
buf := bytes.NewBuffer(testdata) buf := bytes.NewBuffer(testdata)
bufbuf := bufio.NewReader(buf)
var i Integer n, v := unmarshalSingleInteger(buf)
i.unmarshal(bufbuf) assert.Equal(T, "flop", n, "Should be equal")
assert.Equal(T, "flop", i.name, "Should be equal") assert.Equal(T, int32(4), v, "Should be equal")
assert.Equal(T, int32(4), i.values[0], "Should be equal")
} }
func TestUnMarshalSingleNegativeInteger(T *testing.T) { func TestUnMarshalSingleNegativeInteger(T *testing.T) {
@@ -34,11 +29,10 @@ func TestUnMarshalSingleNegativeInteger(T *testing.T) {
0x00, 0x04, 0x00, 0x04,
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
} }
buf := bytes.NewBuffer(testdata)
bufbuf := bufio.NewReader(buf)
var i Integer buf := bytes.NewBuffer(testdata)
i.unmarshal(bufbuf)
assert.Equal(T, "flop", i.name, "Should be equal") n, v := unmarshalSingleInteger(buf)
assert.Equal(T, int32(-4), i.values[0], "Should be equal") assert.Equal(T, "flop", n, "Should be equal")
assert.Equal(T, int32(-4), v, "Should be equal")
} }

View File

@@ -1,11 +1,5 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import (
"bufio"
)
type KeyWord struct { type KeyWord struct {
sos *SetOfStrings sos *SetOfStrings
} }
@@ -25,6 +19,10 @@ func (k KeyWord) String() string {
return k.sos.String() return k.sos.String()
} }
func (k *KeyWord) size() int {
return k.sos.size()
}
func (k *KeyWord) valueTag() tag { func (k *KeyWord) valueTag() tag {
return k.sos.valueTag() return k.sos.valueTag()
} }
@@ -33,10 +31,7 @@ func (k *KeyWord) marshal() []byte {
return k.sos.marshal() return k.sos.marshal()
} }
func (k *KeyWord) unmarshal(byteStream *bufio.Reader) {
k.sos.unmarshal(byteStream, keyWordValueTag)
}
func (k *KeyWord) addValue(v interface{}) { func (k *KeyWord) addValue(v interface{}) {
k.sos.AddValue(v.(string)) k.sos.AddValue(v.(string))
} }

View File

@@ -1,10 +1,6 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"bytes"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -24,28 +20,6 @@ import (
// assert.Equal(T, k.values[0], "printer-make-and-model") // assert.Equal(T, k.values[0], "printer-make-and-model")
// } // }
func TestUnmarshalKeywordWithMultipleStrings(t *testing.T) {
// test data from rfc8010 example A8 Get-Jobs request
testdata := []byte{0x00, 0x14,
'r', 'e', 'q', 'u', 'e', 's', 't', 'e', 'd', '-', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', 's',
0x00, 0x06,
'j', 'o', 'b', '-', 'i', 'd',
0x44, 0x00, 0x00, 0x00, 0x08,
'j', 'o', 'b', '-', 'n', 'a', 'm', 'e',
0x44, 0x00, 0x00, 0x00, 0x0f,
'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', '-', 'f', 'o', 'r', 'm', 'a', 't',
}
buf := bytes.NewBuffer(testdata)
r := bufio.NewReader(buf)
k := NewKeyWord("")
k.unmarshal(r)
assert.Equal(t, k.Name(), "requested-attributes")
assert.Len(t, k.sos.values, 3)
assert.Equal(t, k.sos.values[0], "job-id")
assert.Equal(t, k.sos.values[1], "job-name")
assert.Equal(t, k.sos.values[2], "document-format")
}
func TestMarshalSimpleKeyword(T *testing.T) { func TestMarshalSimpleKeyword(T *testing.T) {
testdata := []byte{ testdata := []byte{
0x44, 0x00, 0x14, 0x44, 0x00, 0x14,
@@ -60,28 +34,3 @@ func TestMarshalSimpleKeyword(T *testing.T) {
assert.Equal(T, testdata, m, "Should be equal") assert.Equal(T, testdata, m, "Should be equal")
} }
func TestUnMarshalKeywordWithAdditionalValues(T *testing.T) {
testdata := []byte{
0x00, 0x04,
0x72, 0x65, 0x71, 0x75,
0x00, 0x06,
0x70, 0x72, 0x69, 0x6e, 0x74, 0x65,
0x44, 0x00, 0x00,
0x00, 0x04,
0x6e, 0x69, 0x72, 0x70,
0x44, 0x00, 0x00,
0x00, 0x05,
0x70, 0x72, 0x69, 0x6e, 0x74, 0x00,
}
b := bytes.NewBuffer(testdata)
buf := bufio.NewReader(b)
k := NewKeyWord("")
k.unmarshal(buf)
assert.Equal(T, "requ", k.sos.name, "Wrong name")
assert.Equal(T, "printe", k.sos.values[0], "Wrong value 0")
assert.Equal(T, "nirp", k.sos.values[1], "Wrong value 1")
assert.Equal(T, "print", k.sos.values[2], "Wrong value 2")
}

View File

@@ -1,6 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
//Package ipp provides functonality to handle ipp messages //Package ipp provides functonality to handle ipp messages
//go:generate stringer -type jobState -type printerState //go:generate stringer -type jobState -type printerState
package ipp package ipp
@@ -97,18 +94,18 @@ const (
Stopped printerState = 5 Stopped printerState = 5
) )
// // jobstate defined in rfc8011 ch 5.3.7 // jobstate defined in rfc8011 ch 5.3.7
// type jobState uint16 type jobState uint16
// const ( const (
// pending jobState = 3 pending jobState = 3
// pendingHeld jobState = 4 pendingHeld jobState = 4
// processing jobState = 5 processing jobState = 5
// processingStoppped jobState = 6 processingStoppped jobState = 6
// cancelled jobState = 7 cancelled jobState = 7
// aborted jobState = 8 aborted jobState = 8
// completed jobState = 9 completed jobState = 9
// ) )
type statusCode uint16 type statusCode uint16
@@ -128,8 +125,19 @@ func (v versionNumber) String() string {
return fmt.Sprintf("%x.%x", vn&0xff00>>8, vn&0x00ff) return fmt.Sprintf("%x.%x", vn&0xff00>>8, vn&0x00ff)
} }
// unmarshalSingleValue reads a single key value pair from the byte stream func unmarshalSingleAttribute(byteStream io.Reader) (string, []byte) {
// RFC 8010: Attribute-with-one-value var length uint16
binary.Read(byteStream, binary.BigEndian, &length)
attributeName := make([]byte, length)
if length > 0 {
binary.Read(byteStream, binary.BigEndian, attributeName)
}
binary.Read(byteStream, binary.BigEndian, &length)
attributeValue := make([]byte, length)
binary.Read(byteStream, binary.BigEndian, attributeValue)
return string(attributeName), attributeValue
}
func unmarshalSingleValue(byteStream io.Reader) (string, string) { func unmarshalSingleValue(byteStream io.Reader) (string, string) {
var length uint16 var length uint16
binary.Read(byteStream, binary.BigEndian, &length) binary.Read(byteStream, binary.BigEndian, &length)
@@ -154,52 +162,11 @@ func marshalNameValue(name, value string, b []byte) {
copy(b[p:], []byte(value)) copy(b[p:], []byte(value))
} }
// func readAttribute(byteStream *bufio.Reader) (string, [][]byte) {
// var length uint16
// values := make([][]byte, 0, 1)
// binary.Read(byteStream, binary.BigEndian, &length)
// attributeName := make([]byte, length)
// if length > 0 {
// binary.Read(byteStream, binary.BigEndian, attributeName)
// }
// binary.Read(byteStream, binary.BigEndian, attributeValue)
// values = append(values, string(attributeValue))
// next, err := byteStream.Peek(1)
// if err != nil {
// panic("Failed to peek")
// }
// if next[0] != byte(keyWordValueTag) {
// // No additional values
// return string(attributeName), values
// }
// binary.Read(byteStream, binary.BigEndian, &length)
// for length > 0 {
// attributeValue := make([]byte, length)
// binary.Read(byteStream, binary.BigEndian, &length)
// attributeValue := make([]byte, length)
// if length > 0 {
// binary.Read(byteStream, binary.BigEndian, attributeValue)
// }
// values = append(values, string(attributeValue))
// next, err := byteStream.Peek(1)
// if err != nil {
// panic("Failed to peek")
// }
// if next[0] != byte(keyWordValueTag) {
// // No additional values
// return string(attributeName), values
// }
// }
// }
type Attribute interface { type Attribute interface {
Name() string Name() string
valueTag() tag valueTag() tag
marshal() []byte marshal() []byte
//size() int
} }
type Attributes struct { type Attributes struct {
@@ -260,10 +227,11 @@ func UnMarshalAttributes(bytestream *bufio.Reader) *Attributes {
} }
currentAttributeGroup := t currentAttributeGroup := t
var lastAddValuer AddValuer
for { for {
err = binary.Read(bytestream, binary.BigEndian, &t) err = binary.Read(bytestream, binary.BigEndian, &t)
if err != nil { if err != nil {
log.Fatalf("End of input before end of attributes tag (%v)", err.Error()) log.Fatal("End of input before end of attributes tag (%v)", err.Error())
} }
log.Debugf("Value tag - %v", t) log.Debugf("Value tag - %v", t)
switch t { switch t {
@@ -289,10 +257,15 @@ func UnMarshalAttributes(bytestream *bufio.Reader) *Attributes {
a.addAttribute(currentAttributeGroup, n) a.addAttribute(currentAttributeGroup, n)
log.Debugf("%v %v", n.name, n.value) log.Debugf("%v %v", n.name, n.value)
case keyWordValueTag: case keyWordValueTag:
k := NewKeyWord("", "") name, value := unmarshalSingleValue(bytestream)
k.unmarshal(bytestream) if name == "" {
lastAddValuer.addValue(value)
} else {
k := NewKeyWord(name, value)
a.addAttribute(currentAttributeGroup, k) a.addAttribute(currentAttributeGroup, k)
log.Debugf("%v : %v", k.Name(), k.String()) lastAddValuer = k
}
log.Debugf("%v : %v", name, value)
case nameWithoutLanguageValueTag: case nameWithoutLanguageValueTag:
n := NewNameWithoutLanguage("", "") n := NewNameWithoutLanguage("", "")
n.unmarshal(bytestream) n.unmarshal(bytestream)
@@ -304,25 +277,45 @@ func UnMarshalAttributes(bytestream *bufio.Reader) *Attributes {
a.addAttribute(currentAttributeGroup, attr) a.addAttribute(currentAttributeGroup, attr)
log.Debugf("%v %v", attr.name, attr.value) log.Debugf("%v %v", attr.name, attr.value)
case mimeMediaTypeValueTag: case mimeMediaTypeValueTag:
m := NewMimeMediaType("") name, value := unmarshalSingleValue(bytestream)
m.unmarshal(bytestream) if name == "" {
lastAddValuer.addValue(value)
} else {
m := NewMimeMediaType(name, value)
a.addAttribute(currentAttributeGroup, m) a.addAttribute(currentAttributeGroup, m)
log.Debugf("%v : %v", m.Name(), m.String()) lastAddValuer = m
}
log.Debugf("%v : %v", name, value)
case integerValueTag: case integerValueTag:
i := NewInteger("") name, value := unmarshalSingleInteger(bytestream)
i.unmarshal(bytestream) if name == "" {
lastAddValuer.addValue(value)
} else {
i := NewInteger(name, value)
a.addAttribute(currentAttributeGroup, i) a.addAttribute(currentAttributeGroup, i)
log.Debugf("%v : %v", i.name, i.values) lastAddValuer = i
}
log.Debugf("%v : %v", name, value)
case rangeOfIntegerValueTag: case rangeOfIntegerValueTag:
r := NewRangeOfInteger("") name, value := unmarshalSingleRangeOfInteger(bytestream)
r.unmarshal(bytestream) if name == "" {
lastAddValuer.addValue(value)
} else {
r := NewRangeOfInteger(name, value)
a.addAttribute(currentAttributeGroup, r) a.addAttribute(currentAttributeGroup, r)
log.Debugf("%v : %v", r.name, r.values) lastAddValuer = r
}
log.Debugf("%v : %v", name, value)
case enumValueTag: case enumValueTag:
e := NewEnum("") name, value := unmarshalSingleInteger(bytestream)
e.unmarshal(bytestream) if name == "" {
lastAddValuer.addValue(value)
} else {
e := NewEnum(name, value)
a.addAttribute(currentAttributeGroup, e) a.addAttribute(currentAttributeGroup, e)
log.Debugf("%v : %v", e.name, e.values) lastAddValuer = e
}
log.Debugf("%v : %v", name, value)
case begCollectionValueTag: case begCollectionValueTag:
// For now just consume the collection // For now just consume the collection
consumeCollection(bytestream) consumeCollection(bytestream)
@@ -330,6 +323,7 @@ func UnMarshalAttributes(bytestream *bufio.Reader) *Attributes {
attr := NewUnsupportedValue() attr := NewUnsupportedValue()
attr.unmarshal(bytestream) attr.unmarshal(bytestream)
a.addAttribute(currentAttributeGroup, attr) a.addAttribute(currentAttributeGroup, attr)
case jobAttributes: case jobAttributes:
log.Debug("Start job attributes") log.Debug("Start job attributes")
currentAttributeGroup = jobAttributes currentAttributeGroup = jobAttributes

View File

@@ -1,9 +1,5 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import "bufio"
type MimeMediaType struct { type MimeMediaType struct {
sos *SetOfStrings sos *SetOfStrings
} }
@@ -23,6 +19,10 @@ func (m MimeMediaType) String() string {
return m.sos.String() return m.sos.String()
} }
func (m *MimeMediaType) size() int {
return m.sos.size()
}
func (m *MimeMediaType) valueTag() tag { func (m *MimeMediaType) valueTag() tag {
return m.sos.valueTag() return m.sos.valueTag()
} }
@@ -31,10 +31,6 @@ func (m *MimeMediaType) marshal() []byte {
return m.sos.marshal() return m.sos.marshal()
} }
func (m *MimeMediaType) unmarshal(byteStream *bufio.Reader) {
m.sos.unmarshal(byteStream, mimeMediaTypeValueTag)
}
func (m *MimeMediaType) addValue(v interface{}) { func (m *MimeMediaType) addValue(v interface{}) {
m.sos.AddValue(v.(string)) m.sos.AddValue(v.(string))
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import "io" import "io"
@@ -39,6 +37,13 @@ func (n *NameWithoutLanguage) marshal() []byte {
return b return b
} }
func (n *NameWithoutLanguage) size() int {
l := 1 + 4 // The attribute tag + 2 lengths
l += len(n.name)
l += len(n.value)
return l
}
func (n NameWithoutLanguage) Value() string { func (n NameWithoutLanguage) Value() string {
return n.value return n.value
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
@@ -41,3 +39,10 @@ func (c *NaturalLanguage) marshal() []byte {
marshalNameValue(c.name, c.value, b[1:]) marshalNameValue(c.name, c.value, b[1:])
return b return b
} }
func (c *NaturalLanguage) size() int {
l := 1 + 4 // The attribute tag + 2 lengths
l += len(c.name)
l += len(c.value)
return l
}

View File

@@ -1,11 +1,9 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -44,44 +42,14 @@ func (r *RangeOfInteger) marshal() []byte {
return []byte{} return []byte{}
} }
func (r *RangeOfInteger) unmarshal(byteStream *bufio.Reader) error {
var length uint16
r.values = make([]IRange, 0, 1)
binary.Read(byteStream, binary.BigEndian, &length)
name := make([]byte, length)
if length > 0 {
binary.Read(byteStream, binary.BigEndian, name)
}
r.name = string(name)
binary.Read(byteStream, binary.BigEndian, &length)
if length != 8 {
return fmt.Errorf("wrong value-length of range-of-integer attribute %v", length)
}
for length > 0 {
var i IRange
err := binary.Read(byteStream, binary.BigEndian, &i.lower)
if err != nil {
return err
}
err = binary.Read(byteStream, binary.BigEndian, &i.upper)
if err != nil {
return err
}
r.values = append(r.values, i)
next, err := byteStream.Peek(3)
if err != nil {
break
}
if next[0] != byte(rangeOfIntegerValueTag) || next[1] != 0x00 || next[2] != 0x00 {
break
}
// Remove the value tag with the zero length from the stream
byteStream.Discard(3)
binary.Read(byteStream, binary.BigEndian, &length)
}
return nil
}
func (r *RangeOfInteger) addValue(v interface{}) { func (r *RangeOfInteger) addValue(v interface{}) {
r.values = append(r.values, v.(IRange)) r.values = append(r.values, v.(IRange))
} }
func unmarshalSingleRangeOfInteger(byteStream io.Reader) (string, IRange) {
name, data := unmarshalSingleAttribute(byteStream)
var r IRange
r.lower = int32(binary.BigEndian.Uint32(data[0:4]))
r.upper = int32(binary.BigEndian.Uint32(data[4:8]))
return name, r
}

View File

@@ -1,53 +1,24 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (
"bufio"
"bytes" "bytes"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestUnmarshalSingleRange(T *testing.T) { func TestUnMarshalSingleRange(T *testing.T) {
testdata := []byte{ testdata := []byte{
0x00, 0x04, 0x00, 0x04,
0x66, 0x6c, 0x6f, 0x70, //flop 0x66, 0x6c, 0x6f, 0x70, //flop
0x00, 0x08, 0x00, 0x08,
0x00, 0x0, 0x0, 0x4, 0x00, 0x0, 0x0, 0x5, 0x00, 0x0, 0x0, 0x4, 0x00, 0x0, 0x0, 0x5,
} }
b := bytes.NewBuffer(testdata)
buf := bufio.NewReader(b)
var r RangeOfInteger buf := bytes.NewBuffer(testdata)
r.unmarshal(buf)
assert.Equal(T, "flop", r.name, "Should be equal")
assert.Equal(T, int32(4), r.values[0].lower, "Should be equal")
assert.Equal(T, int32(5), r.values[0].upper, "Should be equal")
}
func TestUnmarshalDualRanges(T *testing.T) {
testdata := []byte{
0x00, 0x04,
0x66, 0x6c, 0x6f, 0x70, //flop
0x00, 0x08,
0x00, 0x0, 0x0, 0x4, 0x00, 0x0, 0x0, 0x5,
0x33, 0x00, 0x00,
0x00, 0x08,
0x00, 0x0, 0x0, 0x6, 0x00, 0x0, 0x0, 0x9,
}
b := bytes.NewBuffer(testdata)
buf := bufio.NewReader(b)
var r RangeOfInteger
r.unmarshal(buf)
assert.Equal(T, "flop", r.name, "Should be equal")
assert.Equal(T, int32(4), r.values[0].lower, "Should be equal")
assert.Equal(T, int32(5), r.values[0].upper, "Should be equal")
assert.Equal(T, int32(6), r.values[1].lower, "Should be equal")
assert.Equal(T, int32(9), r.values[1].upper, "Should be equal")
n, v := unmarshalSingleRangeOfInteger(buf)
assert.Equal(T, "flop", n, "Should be equal")
assert.Equal(T, int32(4), v.lower, "Should be equal")
assert.Equal(T, int32(5), v.upper, "Should be equal")
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,56 +0,0 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp
import (
"bufio"
"encoding/binary"
"fmt"
)
// setOfIntegers is a helper type that is used to handle integer types
// which only differs in tag value.
type setOfIntegers struct {
name string
values []int32
}
func unmarshalIntegers(byteStream *bufio.Reader, valueTag tag) (*setOfIntegers, error) {
s := new(setOfIntegers)
s.values = make([]int32, 0, 1)
var length uint16
binary.Read(byteStream, binary.BigEndian, &length)
name := make([]byte, length)
if length > 0 {
binary.Read(byteStream, binary.BigEndian, name)
}
s.name = string(name)
binary.Read(byteStream, binary.BigEndian, &length)
if length != 4 {
return nil, fmt.Errorf("wrong value-length of integer attribute %v", length)
}
var value int32 //valueBytes := make([]byte, length)
for length > 0 {
err := binary.Read(byteStream, binary.BigEndian, &value)
if err != nil {
return nil, err
}
s.values = append(s.values, value)
next, err := byteStream.Peek(3)
if err != nil {
// end of byte stream
break
}
if next[0] != byte(valueTag) || next[1] != 0x00 || next[2] != 0x00 {
// End of attribute
break
}
// Remove the value tag with the zero length from the stream
byteStream.Discard(3)
binary.Read(byteStream, binary.BigEndian, &length)
}
return s, nil
}

View File

@@ -1,11 +1,6 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import "encoding/binary"
"bufio"
"encoding/binary"
)
// SetOfStrings is the strings attribute // SetOfStrings is the strings attribute
type SetOfStrings struct { type SetOfStrings struct {
@@ -35,37 +30,17 @@ func (s *SetOfStrings) valueTag() tag {
return s.vTag return s.vTag
} }
func (s *SetOfStrings) unmarshal(byteStream *bufio.Reader, valueTag tag) error { // func (k *keyWord) unmarshal(byteStream io.Reader) {
var length uint16 // if len(k.values) == 0 {
s.vTag = valueTag // var v string
s.values = make([]string, 0, 1) // k.name, v = unmarshalSingleValue(byteStream)
binary.Read(byteStream, binary.BigEndian, &length) // k.values = append(k.values, v)
name := make([]byte, length) // } else {
if length > 0 { // var v string
binary.Read(byteStream, binary.BigEndian, name) // _, v = unmarshalSingleValue(byteStream)
} // k.values = append(k.values, v)
s.name = string(name) // }
binary.Read(byteStream, binary.BigEndian, &length) // }
for length > 0 {
valueBytes := make([]byte, length)
err := binary.Read(byteStream, binary.BigEndian, valueBytes)
if err != nil {
return err
}
s.values = append(s.values, string(valueBytes))
next, err := byteStream.Peek(3)
if err != nil {
break
}
if next[0] != byte(valueTag) || next[1] != 0x00 || next[2] != 0x00 {
break
}
// Remove the value tag with the zero length from the stream
byteStream.Discard(3)
binary.Read(byteStream, binary.BigEndian, &length)
}
return nil
}
func (s *SetOfStrings) marshal() []byte { func (s *SetOfStrings) marshal() []byte {
l := 5 + len(s.name) + len(s.values[0]) l := 5 + len(s.name) + len(s.values[0])
@@ -102,3 +77,16 @@ func (s *SetOfStrings) marshal() []byte {
func (s *SetOfStrings) AddValue(v string) { func (s *SetOfStrings) AddValue(v string) {
s.values = append(s.values, v) s.values = append(s.values, v)
} }
func (s *SetOfStrings) size() int {
l := 1 + 2 // The value tag (0x44) + name-length field (2 bytes)
l += len(s.name)
l += 2 // value-length field (2 bytes)
l += len(s.values[0])
// Add all additional values
for _, v := range s.values[1:] {
l += 1 + 4 // The value tag (0x44) + 2 length fields (2 bytes)
l += len(v)
}
return l
}

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import "io" import "io"
@@ -42,3 +40,10 @@ func (c *TextWithoutLanguage) marshal() []byte {
marshalNameValue(c.name, c.value, b[1:]) marshalNameValue(c.name, c.value, b[1:])
return b return b
} }
func (c *TextWithoutLanguage) size() int {
l := 1 + 4 // The attribute tag + 2 lengths
l += len(c.name)
l += len(c.value)
return l
}

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package ipp package ipp
import ( import (

View File

@@ -1,10 +1,7 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package mdnsserver package mdnsserver
import ( import (
"context" "context"
"fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -12,40 +9,40 @@ import (
"github.com/holoplot/go-avahi" "github.com/holoplot/go-avahi"
) )
func Run(ctx context.Context, location string, port uint16, name string) { func Run(ctx context.Context) {
conn, err := dbus.SystemBus() conn, err := dbus.SystemBus()
if err != nil { if err != nil {
return return
} }
a, err := avahi.ServerNew(conn) a, err := avahi.ServerNew(conn)
if err != nil { if err != nil {
log.Fatalf("Failed to connect to avahi: %v", err) log.Fatalf("Avahi new failed: %v", err)
} }
eg, err := a.EntryGroupNew() eg, err := a.EntryGroupNew()
if err != nil { if err != nil {
log.Fatalf("Failed to create entry group: %v", err) log.Fatalf("EntryGroupNew() failed: %v", err)
} }
fqdn, err := a.GetHostNameFqdn() fqdn, err := a.GetHostNameFqdn()
if err != nil { if err != nil {
log.Fatalf("failed to get hostname: %v", err) log.Fatalf("GetHostNameFqdn() failed: %v", err)
} }
var txt [][]byte var txt [][]byte
notestring := fmt.Sprintf("note=%v", location)
txt = append(txt, []byte(notestring)) txt = append(txt, []byte("note=burken"))
txt = append(txt, []byte("product=ChroBroPrint V1")) txt = append(txt, []byte("product=ChroBroPrint V1"))
txt = append(txt, []byte("Color=T")) txt = append(txt, []byte("Color=T"))
txt = append(txt, []byte("rp=ipp/print")) txt = append(txt, []byte("rp=ipp/print"))
txt = append(txt, []byte("ty=ChroBroPrint")) txt = append(txt, []byte("ty=ChroBroPrint"))
err = eg.AddService(avahi.InterfaceUnspec, avahi.ProtoUnspec, 0, name, "_ipp._tcp", "local", fqdn, port, txt) err = eg.AddService(avahi.InterfaceUnspec, avahi.ProtoUnspec, 0, "ChroBroPrint", "_ipp._tcp", "local", fqdn, 1234, txt)
if err != nil { if err != nil {
log.Fatalf("Failed to add service to avahi: %v", err) log.Fatalf("AddService() failed: %v", err)
} }
err = eg.Commit() err = eg.Commit()
if err != nil { if err != nil {
log.Fatalf("Failed to commit avahi changes: %v", err) log.Fatalf("Commit() failed: %v", err)
} }
<-ctx.Done() <-ctx.Done()

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import "ippserver/packages/ipp" import "ippserver/packages/ipp"

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (
@@ -15,7 +13,7 @@ func handleGetJobAttributes(r *ipp.Request, requestID uint32) (*ipp.Response, er
request := ipp.NewRequest(ipp.GetJobAttributes, requestID) request := ipp.NewRequest(ipp.GetJobAttributes, requestID)
request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8"))
request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en")) request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en"))
request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", ippurl.String())) request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", "ipp://"+printerURI))
request.AddOperatonAttribute(r.GetAttribute("job-id")) request.AddOperatonAttribute(r.GetAttribute("job-id"))
request.AddOperatonAttribute(r.GetAttribute("requesting-user-name")) request.AddOperatonAttribute(r.GetAttribute("requesting-user-name"))
request.AddOperatonAttribute(r.GetAttribute("requested-attributes")) request.AddOperatonAttribute(r.GetAttribute("requested-attributes"))
@@ -25,7 +23,7 @@ func handleGetJobAttributes(r *ipp.Request, requestID uint32) (*ipp.Response, er
downStreamRequest := request.Marshal() downStreamRequest := request.Marshal()
b := bytes.NewBuffer(downStreamRequest) b := bytes.NewBuffer(downStreamRequest)
downStreamResponse, err := http.Post(httpurl.String(), "application/ipp", b) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (
@@ -15,7 +13,7 @@ func handleGetJobs(r *ipp.Request, requestID uint32) (*ipp.Response, error) {
request := ipp.NewRequest(ipp.GetJobs, requestID) request := ipp.NewRequest(ipp.GetJobs, requestID)
request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8"))
request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en")) request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en"))
request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", ippurl.String())) request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", "ipp://"+printerURI))
request.AddOperatonAttribute(r.GetAttribute("requesting-user-name")) request.AddOperatonAttribute(r.GetAttribute("requesting-user-name"))
request.AddOperatonAttribute(r.GetAttribute("requested-attributes")) request.AddOperatonAttribute(r.GetAttribute("requested-attributes"))
@@ -24,7 +22,7 @@ func handleGetJobs(r *ipp.Request, requestID uint32) (*ipp.Response, error) {
downStreamRequest := request.Marshal() downStreamRequest := request.Marshal()
b := bytes.NewBuffer(downStreamRequest) b := bytes.NewBuffer(downStreamRequest)
downStreamResponse, err := http.Post(httpurl.String(), "application/ipp", b) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import "ippserver/packages/ipp" import "ippserver/packages/ipp"

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (
@@ -13,15 +11,15 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
//const printerURI = "brn30055cb5e3ae.local:631/ipp/print" const printerURI = "brn30055cb5e3ae.local:631/ipp/print"
func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) (*ipp.Response, error) { func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) (*ipp.Response, error) {
// This request is what will be sent to the real printer // This request is what will be sent to the real printer
request := ipp.NewRequest(ipp.PrintJob, requestID) request := ipp.NewRequest(ipp.PrintJob, requestID)
request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8"))
request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en")) request.AddOperatonAttribute(ipp.NewNaturalLanguage("attributes-natural-language", "en"))
//request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", "ipp://"+printerURI)) request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", "ipp://"+printerURI))
request.AddOperatonAttribute(ipp.NewURIValue("printer-uri", ippurl.String()))
request.AddOperatonAttribute(r.GetAttribute("requesting-user-name")) request.AddOperatonAttribute(r.GetAttribute("requesting-user-name"))
request.AddOperatonAttribute(r.GetAttribute("job-name")) request.AddOperatonAttribute(r.GetAttribute("job-name"))
request.AddOperatonAttribute(ipp.NewMimeMediaType("document-format", "image/pwg-raster")) request.AddOperatonAttribute(ipp.NewMimeMediaType("document-format", "image/pwg-raster"))
@@ -37,8 +35,7 @@ func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) (*ip
b := bytes.NewBuffer(downStreamRequest) b := bytes.NewBuffer(downStreamRequest)
mr := io.MultiReader(b, byteStream) mr := io.MultiReader(b, byteStream)
//downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", mr) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", mr)
downStreamResponse, err := http.Post(httpurl.String(), "application/ipp", mr)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,15 +1,11 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (
"context" "context"
"flag" "flag"
"fmt"
"ippserver/packages/ipp" "ippserver/packages/ipp"
"ippserver/packages/mdnsserver" "ippserver/packages/mdnsserver"
"net/http" "net/http"
"net/url"
"sync" "sync"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -18,45 +14,27 @@ import (
var ( var (
loglevel string loglevel string
location string location string
port uint
printerURI string
printerName string
ippurl, httpurl *url.URL
) )
func init() { func init() {
flag.StringVar(&loglevel, "loglevel", "info", "The wanted loglevel error/info/debug") flag.StringVar(&loglevel, "loglevel", "info", "The wanted loglevel error/info/debug")
flag.StringVar(&location, "location", "somewhere", "locaton of the printer as shown in mDNS")
flag.UintVar(&port, "port", 1234, "tcp port")
flag.StringVar(&printerURI, "printer", "", "URL to the real printer, typical ipp://printername.local:631/ipp/print")
flag.StringVar(&printerName, "name", "ChroBroPrint", "Name of the printer advertised with mDNS")
} }
func main() { func main() {
var err error
flag.Parse()
customFormatter := new(log.TextFormatter) customFormatter := new(log.TextFormatter)
customFormatter.TimestampFormat = "2006-01-02 15:04:05" customFormatter.TimestampFormat = "2006-01-02 15:04:05"
log.SetFormatter(customFormatter) log.SetFormatter(customFormatter)
customFormatter.FullTimestamp = true customFormatter.FullTimestamp = true
log.SetLevel(log.InfoLevel) log.SetLevel(log.InfoLevel)
ippurl, err = url.Parse(printerURI)
if err != nil {
fmt.Printf("Failed to parse printer URL %v", err.Error())
return
}
httpurl, _ = url.Parse(printerURI)
httpurl.Scheme = "http"
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
go mdnsserver.Run(ctx, location, uint16(port), printerName) go mdnsserver.Run(ctx)
http.HandleFunc("/ipp/print", handle) http.HandleFunc("/ipp/print", handle)
log.Infof("http server starting on :%v", port) log.Info("http server started on :1234")
err = http.ListenAndServe(fmt.Sprintf(":%v", port), nil) err := http.ListenAndServe(":1234", nil)
if err != nil { if err != nil {
log.Fatal("ListenAndServe: " + err.Error()) log.Fatal("ListenAndServe: " + err.Error())
} }

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import "ippserver/packages/ipp" import "ippserver/packages/ipp"

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import "ippserver/packages/ipp" import "ippserver/packages/ipp"

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import "ippserver/packages/ipp" import "ippserver/packages/ipp"

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (

View File

@@ -1,5 +1,3 @@
// Copyright 2021, Henrik Sölver henrik.solver@gmail.com
// SPDX-License-Identifier: BSD-3-Clause
package main package main
import ( import (
@@ -20,7 +18,7 @@ func main() {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
go mdnsserver.Run(ctx, "some location", 1234, "ChroBroPrint") go mdnsserver.Run(ctx)
http.HandleFunc("/ipp/print", handle) http.HandleFunc("/ipp/print", handle)