Avoid panic if printer is off or unreachable for some reason.

Closes #16
Closes #17
Closes #15
This commit was merged in pull request #18.
This commit is contained in:
2021-05-23 15:21:31 +00:00
committed by Gitea
parent 72ee8c7d1b
commit 21cf29f651
7 changed files with 35 additions and 19 deletions

View File

@@ -115,6 +115,7 @@ const (
SuccessfulOkIgnoredOrSubstitutedAttributes statusCode = 0x0001 SuccessfulOkIgnoredOrSubstitutedAttributes statusCode = 0x0001
SuccessfulOkConflictingAttributes statusCode = 0x0002 SuccessfulOkConflictingAttributes statusCode = 0x0002
ClientErrorBadRequest statusCode = 0x0400 ClientErrorBadRequest statusCode = 0x0400
ServerErrorServiceUnavailable statusCode = 0x0502
) )
type versionNumber uint16 type versionNumber uint16

View File

@@ -65,6 +65,7 @@ func (r *Request) RequestID() uint32 {
return r.header.requestID return r.header.requestID
} }
// Operation returns the operation is of the request.
func (r *Request) Operation() OperationID { func (r *Request) Operation() OperationID {
return r.header.operationID return r.header.operationID
} }

View File

@@ -52,6 +52,10 @@ func (r Response) String() string {
return r.header.String() + "\n" + r.a.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. // Marshal converts the response object to a wire formatted byte stream.
func (r *Response) Marshal() []byte { func (r *Response) Marshal() []byte {
a := make([]byte, 0, 20) a := make([]byte, 0, 20)

View File

@@ -2,14 +2,13 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"ippserver/packages/ipp" "ippserver/packages/ipp"
"net/http" "net/http"
log "github.com/sirupsen/logrus" 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 := ipp.NewRequest(ipp.GetJobAttributes, requestID)
request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) 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) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b)
if err != nil { if err != nil {
fmt.Print(err) return nil, err
} }
rb := ipp.NewResponse(0, 0) 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"))
response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons"))
return response return response, nil
} }

View File

@@ -2,14 +2,13 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"ippserver/packages/ipp" "ippserver/packages/ipp"
"net/http" "net/http"
log "github.com/sirupsen/logrus" 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 := ipp.NewRequest(ipp.GetJobs, requestID)
request.AddOperatonAttribute(ipp.NewCharSetValue("attributes-charset", "utf-8")) 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) downStreamResponse, err := http.Post("http://"+"brn30055cb5e3ae.local:631/ipp/print", "application/ipp", b)
if err != nil { if err != nil {
fmt.Print(err) return nil, err
} }
//log.Printf("response HTTP status: %v %v", downStreamResponse.StatusCode, downStreamResponse.Status) //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"))
response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons"))
return response return response, nil
} }

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"ippserver/packages/ipp" "ippserver/packages/ipp"
"net/http" "net/http"
@@ -14,7 +13,7 @@ import (
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 { 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)
@@ -38,7 +37,7 @@ func handlePrintJob(r *ipp.Request, byteStream io.Reader, requestID uint32) *ipp
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)
if err != nil { if err != nil {
fmt.Print(err) return nil, err
} }
rb := ipp.NewResponse(0, 0) 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"))
response.AddJobAttribute(rb.GetAttribute("job-state-reasons")) response.AddJobAttribute(rb.GetAttribute("job-state-reasons"))
return response return response, nil
} }

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"context" "context"
"flag"
"ippserver/packages/ipp" "ippserver/packages/ipp"
"ippserver/packages/mdnsserver" "ippserver/packages/mdnsserver"
"net/http" "net/http"
@@ -10,6 +11,15 @@ import (
log "github.com/sirupsen/logrus" 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() { func main() {
customFormatter := new(log.TextFormatter) customFormatter := new(log.TextFormatter)
customFormatter.TimestampFormat = "2006-01-02 15:04:05" customFormatter.TimestampFormat = "2006-01-02 15:04:05"
@@ -39,29 +49,32 @@ func handle(w http.ResponseWriter, r *http.Request) {
mut.Unlock() mut.Unlock()
if r.Method != http.MethodPost { if r.Method != http.MethodPost {
http.Error(w, "Unsupported method", http.StatusMethodNotAllowed) http.Error(w, "Unsupported method", http.StatusMethodNotAllowed)
} }
request := ipp.NewRequest(0, 0) request := ipp.NewRequest(0, 0)
request.UnMarshal(r.Body) 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 response *ipp.Response
var err error
switch request.Operation() { switch request.Operation() {
case ipp.GetPrinterAttributes: case ipp.GetPrinterAttributes:
response = handleGetPrinterAttributes(request) response = handleGetPrinterAttributes(request)
case ipp.PrintJob: case ipp.PrintJob:
response = handlePrintJob(request, r.Body, requestID) response, err = handlePrintJob(request, r.Body, requestID)
case ipp.GetJobs: case ipp.GetJobs:
response = handleGetJobs(request, requestID) response, err = handleGetJobs(request, requestID)
case ipp.ValidateJob: case ipp.ValidateJob:
response = handleValidateJob(request) response = handleValidateJob(request)
case ipp.GetJobAttributes: case ipp.GetJobAttributes:
response = handleGetJobAttributes(request, requestID) response, err = handleGetJobAttributes(request, requestID)
default: default:
response = ipp.NewResponse(ipp.ClientErrorBadRequest, request.RequestID()) response = ipp.NewResponse(ipp.ClientErrorBadRequest, request.RequestID())
} }
if err != nil {
log.Infof("Upstream Response:\n%v\n", response) 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() data := response.Marshal()
w.Write(data) w.Write(data)
} }