From 21cf29f6512786c28ffd475fb36bdd1d757035fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=C3=B6lver?= Date: Sun, 23 May 2021 15:21:31 +0000 Subject: [PATCH] Avoid panic if printer is off or unreachable for some reason. Closes #16 Closes #17 Closes #15 --- packages/ipp/messages.go | 1 + packages/ipp/request.go | 1 + packages/ipp/response.go | 4 ++++ proxy/handlegetjobattributes.go | 7 +++---- proxy/handlegetjobs.go | 7 +++---- proxy/handleprintjob.go | 7 +++---- proxy/main.go | 27 ++++++++++++++++++++------- 7 files changed, 35 insertions(+), 19 deletions(-) diff --git a/packages/ipp/messages.go b/packages/ipp/messages.go index 994ba24..3879765 100644 --- a/packages/ipp/messages.go +++ b/packages/ipp/messages.go @@ -115,6 +115,7 @@ const ( SuccessfulOkIgnoredOrSubstitutedAttributes statusCode = 0x0001 SuccessfulOkConflictingAttributes statusCode = 0x0002 ClientErrorBadRequest statusCode = 0x0400 + ServerErrorServiceUnavailable statusCode = 0x0502 ) type versionNumber uint16 diff --git a/packages/ipp/request.go b/packages/ipp/request.go index 6acdbf8..fcf9e8c 100644 --- a/packages/ipp/request.go +++ b/packages/ipp/request.go @@ -65,6 +65,7 @@ func (r *Request) RequestID() uint32 { return r.header.requestID } +// Operation returns the operation is of the request. func (r *Request) Operation() OperationID { return r.header.operationID } diff --git a/packages/ipp/response.go b/packages/ipp/response.go index 7a2bc0c..0ab83f3 100644 --- a/packages/ipp/response.go +++ b/packages/ipp/response.go @@ -52,6 +52,10 @@ func (r Response) String() string { return r.header.String() + "\n" + r.a.String() } +func (r Response) Header() ippResponseHeader { + return r.header +} + // Marshal converts the response object to a wire formatted byte stream. func (r *Response) Marshal() []byte { a := make([]byte, 0, 20) diff --git a/proxy/handlegetjobattributes.go b/proxy/handlegetjobattributes.go index c3806bb..5931dc7 100644 --- a/proxy/handlegetjobattributes.go +++ b/proxy/handlegetjobattributes.go @@ -2,14 +2,13 @@ package main import ( "bytes" - "fmt" "ippserver/packages/ipp" "net/http" log "github.com/sirupsen/logrus" ) -func handleGetJobAttributes(r *ipp.Request, requestID uint32) *ipp.Response { +func handleGetJobAttributes(r *ipp.Request, requestID uint32) (*ipp.Response, error) { request := ipp.NewRequest(ipp.GetJobAttributes, requestID) request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) @@ -26,7 +25,7 @@ func handleGetJobAttributes(r *ipp.Request, requestID uint32) *ipp.Response { downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b) if err != nil { - fmt.Print(err) + return nil, err } rb := ipp.NewResponse(0, 0) @@ -42,5 +41,5 @@ func handleGetJobAttributes(r *ipp.Request, requestID uint32) *ipp.Response { response.AddJobAttribute(rb.GetAttribute("job-state")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) - return response + return response, nil } diff --git a/proxy/handlegetjobs.go b/proxy/handlegetjobs.go index 40a140b..8b2ef01 100644 --- a/proxy/handlegetjobs.go +++ b/proxy/handlegetjobs.go @@ -2,14 +2,13 @@ package main import ( "bytes" - "fmt" "ippserver/packages/ipp" "net/http" log "github.com/sirupsen/logrus" ) -func handleGetJobs(r *ipp.Request, requestID uint32) *ipp.Response { +func handleGetJobs(r *ipp.Request, requestID uint32) (*ipp.Response, error) { request := ipp.NewRequest(ipp.GetJobs, requestID) request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) @@ -25,7 +24,7 @@ func handleGetJobs(r *ipp.Request, requestID uint32) *ipp.Response { downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b) if err != nil { - fmt.Print(err) + return nil, err } //log.Printf("response HTTP status: %v %v", downStreamResponse.StatusCode, downStreamResponse.Status) @@ -43,5 +42,5 @@ func handleGetJobs(r *ipp.Request, requestID uint32) *ipp.Response { response.AddJobAttribute(rb.GetAttribute("job-state")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) - return response + return response, nil } diff --git a/proxy/handleprintjob.go b/proxy/handleprintjob.go index 6fc5532..e7cd2c6 100644 --- a/proxy/handleprintjob.go +++ b/proxy/handleprintjob.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "fmt" "io" "ippserver/packages/ipp" "net/http" @@ -14,7 +13,7 @@ import ( const printerURI = "brn30055cb5e3ae.local:631/ipp/print" -func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) *ipp.Response { +func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) (*ipp.Response, error) { // This request is what will be sent to the real printer request := ipp.NewRequest(ipp.PrintJob, requestID) @@ -38,7 +37,7 @@ func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) *ipp mr := io.MultiReader(b, byteStream) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", mr) if err != nil { - fmt.Print(err) + return nil, err } rb := ipp.NewResponse(0, 0) @@ -64,5 +63,5 @@ func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) *ipp response.AddJobAttribute(rb.GetAttribute("job-state")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) - return response + return response, nil } diff --git a/proxy/main.go b/proxy/main.go index 982d3fd..c19ef06 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "flag" "ippserver/packages/ipp" "ippserver/packages/mdnsserver" "net/http" @@ -10,6 +11,15 @@ import ( log "github.com/sirupsen/logrus" ) +var ( + loglevel string + location string +) + +func init() { + flag.StringVar(&loglevel, "loglevel", "info", "The wanted loglevel error/info/debug") +} + func main() { customFormatter := new(log.TextFormatter) customFormatter.TimestampFormat = "2006-01-02 15:04:05" @@ -39,29 +49,32 @@ func handle(w http.ResponseWriter, r *http.Request) { mut.Unlock() if r.Method != http.MethodPost { http.Error(w, "Unsupported method", http.StatusMethodNotAllowed) - } request := ipp.NewRequest(0, 0) request.UnMarshal(r.Body) - log.Infof("Upstream Request: \n%v\n", request) + log.Infof("Upstream Request: id: %v op: %v", request.RequestID(), request.Operation()) var response *ipp.Response + var err error switch request.Operation() { case ipp.GetPrinterAttributes: response = handleGetPrinterAttributes(request) case ipp.PrintJob: - response = handlePrintJob(request, r.Body, requestID) + response, err = handlePrintJob(request, r.Body, requestID) case ipp.GetJobs: - response = handleGetJobs(request, requestID) + response, err = handleGetJobs(request, requestID) case ipp.ValidateJob: response = handleValidateJob(request) case ipp.GetJobAttributes: - response = handleGetJobAttributes(request, requestID) + response, err = handleGetJobAttributes(request, requestID) default: response = ipp.NewResponse(ipp.ClientErrorBadRequest, request.RequestID()) } - - log.Infof("Upstream Response:\n%v\n", response) + if err != nil { + log.Errorf("Failed to handle request: %v", err.Error()) + response = ipp.NewResponse(ipp.ServerErrorServiceUnavailable, request.RequestID()) + } + log.Infof("Upstream Response: %v", response.Header()) data := response.Marshal() w.Write(data) }