From ba905d3fcd7648142d04b361b75d19dbefa5e1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=C3=B6lver?= Date: Sat, 31 Oct 2020 21:56:18 +0100 Subject: [PATCH] initial parsing of requests --- main.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++--- messages.go | 44 +++++++++++++++++++++++++++------- 2 files changed, 101 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index 4a6547c..73586b4 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/binary" "ippserver/packages/mdnsserver" "net/http" @@ -25,12 +26,74 @@ func main() { func handle(w http.ResponseWriter, r *http.Request) { log.Infoln("handle") - if r.Method != "POST" { + if r.Method != http.MethodPost { http.Error(w, "Unsupported method", http.StatusMethodNotAllowed) } - // Disable caching of this page + var request ippRequest + request.operationAttributes = make(map[string]string) + request.requestedAttributes = make([]string, 0) + log.Info(r.Header) + log.Info(r.ContentLength) + //body := make([]byte, r.ContentLength) + //r.Body.Read(body) + binary.Read(r.Body, binary.BigEndian, &request.header.versionNumber) + binary.Read(r.Body, binary.BigEndian, &request.header.operationId) + binary.Read(r.Body, binary.BigEndian, &request.header.requestId) + var tag uint8 + binary.Read(r.Body, binary.BigEndian, &tag) + if tag == operationAttributesTag { + var length uint16 + binary.Read(r.Body, binary.BigEndian, &tag) + for tag != endOfAttributesTag { + log.Infof("Value tag %x", tag) + switch tag { + case charsetValueTag, uriValueTag, naturalLanguagageValueTag: + binary.Read(r.Body, binary.BigEndian, &length) + attributeName := make([]byte, length) + binary.Read(r.Body, binary.BigEndian, attributeName) + binary.Read(r.Body, binary.BigEndian, &length) + attributeValue := make([]byte, length) + binary.Read(r.Body, binary.BigEndian, attributeValue) + request.operationAttributes[string(attributeName)] = string(attributeValue) + log.Infof("%v %v", string(attributeName), string(attributeValue)) + binary.Read(r.Body, binary.BigEndian, &tag) + case keywordValueTag: + binary.Read(r.Body, binary.BigEndian, &length) + attributeName := make([]byte, length) + set := make([]string, 0) + binary.Read(r.Body, binary.BigEndian, &attributeName) + binary.Read(r.Body, binary.BigEndian, &length) + value := make([]byte, length) + binary.Read(r.Body, binary.BigEndian, &value) + set = append(set, string(value)) + binary.Read(r.Body, binary.BigEndian, &tag) + for tag == keywordValueTag { + var additionalValue uint16 + binary.Read(r.Body, binary.BigEndian, &additionalValue) + binary.Read(r.Body, binary.BigEndian, &length) + value = make([]byte, length) + binary.Read(r.Body, binary.BigEndian, &value) + set = append(set, string(value)) + binary.Read(r.Body, binary.BigEndian, &tag) + } + if string(attributeName) == "requested-attributes" { + request.requestedAttributes = set + } + log.Infof("%v %v", string(attributeName), set) + default: + log.Error("Unsupported tag") - // Check if user is logged in, if not redirect to login page + } + } + log.Infof("Value tag %x", tag) + } else { + log.Error("unexpected tag") + // TODO Return something sensible here + + } + + log.Infof("request %+v", request) + //log.Infof("Body %v", string(body)) } diff --git a/messages.go b/messages.go index 7ae5661..130dd4a 100644 --- a/messages.go +++ b/messages.go @@ -26,15 +26,35 @@ const ( booleanIntegerTag = 0x22 enumValueTag = 0x23 // Character string values - textWithoutLanguagage = 0x41 - nameWithoutLanguagage = 0x42 - keyword = 0x44 - uri = 0x45 - uriScheme = 0x46 - charset = 0x47 - naturalLanguagage = 0x48 - mimeMediaType = 0x49 - memberAttrName = 0x4a + textWithoutLanguagageValueTag = 0x41 + nameWithoutLanguagageValueTag = 0x42 + keywordValueTag = 0x44 + uriValueTag = 0x45 + uriSchemeValueTag = 0x46 + charsetValueTag = 0x47 + naturalLanguagageValueTag = 0x48 + mimeMediaTypeValueTag = 0x49 + memberAttrNameValueTag = 0x4a +) + +// Operation-id, defined in rfc8011 +const ( + PrintJob = 0x0002 + PrintURI = 0x0003 + ValidateJob = 0x0004 + CreateJob = 0x0005 + SendDocument = 0x0006 + SendURI = 0x0007 + CancelJob = 0x0008 + GetJobAttributes = 0x0009 + GetJobs = 0x000a + GetPrinterAttributes = 0x000b + HoldJob = 0x000c + ReleaseJob = 0x000d + RestartJob = 0x000e + PausePrinter = 0x0010 + ResumePrinter = 0x0011 + PurgeJobs = 0x0012 ) type ippRequestHeader struct { @@ -42,3 +62,9 @@ type ippRequestHeader struct { operationId uint16 requestId uint32 } + +type ippRequest struct { + header ippRequestHeader + operationAttributes map[string]string + requestedAttributes []string +}