Copyright (C) 1995, Digital Equipment Corporation.
All rights reserved.
created by steveg
Parts Copyright (C) 1997, Columbia University
All rights reserved.
* Last Modified By: Blair MacIntyre
* Last Modified On: Mon Aug 4 14:50:11 1997
MODULE HTTPPayment;
IMPORT App, Fmt, HTTP, TextExtras;
TYPE
PF = {PaymentProtocol, PaymentCash, PaymentAuthorization, PaymentBid,
PaymentReceipt, PaymentOffer, PaymentError, NotAPaymentField};
PROCEDURE PaymentField(field: HTTP.Field): PF =
BEGIN
IF TextExtras.CIEqual(field.name, ProtocolField) THEN
RETURN PF.PaymentProtocol
ELSIF TextExtras.CIEqual(field.name, CashField) THEN
RETURN PF.PaymentCash
ELSIF TextExtras.CIEqual(field.name, AuthorizationField) THEN
RETURN PF.PaymentAuthorization
ELSIF TextExtras.CIEqual(field.name, BidField) THEN
RETURN PF.PaymentBid
ELSIF TextExtras.CIEqual(field.name, ReceiptField) THEN
RETURN PF.PaymentReceipt
ELSIF TextExtras.CIEqual(field.name, OfferField) THEN
RETURN PF.PaymentOffer
ELSIF TextExtras.CIEqual(field.name, ErrorField) THEN
RETURN PF.PaymentError
ELSE
RETURN PF.NotAPaymentField
END;
END PaymentField;
PROCEDURE AppendValue(VAR (* in/out *) text: TEXT; value: TEXT) =
BEGIN
IF text = NIL THEN text := value ELSE text := text & ", " & value END;
END AppendValue;
REVEAL
Reply = ReplyPublic BRANDED "HTTPPayment.Reply" OBJECT
OVERRIDES
init := InitReply;
toReply := ToReply;
END;
PROCEDURE InitReply (self : Reply;
reply: HTTP.Reply;
url : TEXT;
log : App.Log ): Reply RAISES {App.Error} =
VAR
iterator := reply.iterateFields();
field := iterator.next();
BEGIN
self.reply := reply;
self.url := url;
WHILE field # NIL DO
CASE PaymentField(field) OF
| PF.PaymentProtocol => AppendValue(self.protocols, field.value);
| PF.PaymentCash => AppendValue(self.cash, field.value);
| PF.PaymentAuthorization =>
AppendValue(self.authorization, field.value);
| PF.PaymentReceipt => AppendValue(self.receipt, field.value);
| PF.PaymentOffer => AppendValue(self.offer, field.value);
| PF.PaymentError => AppendValue(self.error, field.value);
| PF.PaymentBid =>
log.log(
Fmt.F("Illegal payment (field %s: %s) in reply: %s",
field.name, field.value,
reply.toText(HTTP.DefaultStyle(reply.version), log)),
App.LogStatus.Error);
| PF.NotAPaymentField =>
END;
field := iterator.next();
END;
RETURN self;
END InitReply;
PROCEDURE ToReply (self: Reply; <*UNUSED*>log: App.Log): HTTP.Reply
RAISES {(*App.Error*)} =
VAR hReply := NEW(HTTP.Reply, code := self.reply.code,
reason := self.reply.reason);
BEGIN
self.reply.copyFields(hReply);
EVAL
hReply.addField(NEW(HTTP.Field).init(ProtocolField, self.protocols));
IF self.cash # NIL THEN
EVAL hReply.addField(NEW(HTTP.Field).init(CashField, self.cash));
END;
IF self.authorization # NIL THEN
EVAL hReply.addField(
NEW(HTTP.Field).init(AuthorizationField, self.authorization));
END;
IF self.receipt # NIL THEN
EVAL
hReply.addField(NEW(HTTP.Field).init(ReceiptField, self.receipt));
END;
IF self.offer # NIL THEN
EVAL hReply.addField(NEW(HTTP.Field).init(OfferField, self.offer));
END;
IF self.error # NIL THEN
EVAL hReply.addField(NEW(HTTP.Field).init(ErrorField, self.error));
END;
self.reply := hReply;
RETURN hReply;
END ToReply;
PROCEDURE IsPaymentReply(reply: HTTP.Reply): BOOLEAN =
BEGIN
RETURN reply.lookupField(ProtocolField) # NIL;
END IsPaymentReply;
REVEAL
Request = RequestPublic BRANDED "HTTPPayment.Request" OBJECT
OVERRIDES
init := InitRequest;
toRequest := ToRequest;
END;
PROCEDURE InitRequest (self: Request; request: HTTP.Request; log: App.Log):
Request RAISES {App.Error} =
VAR
iterator := request.iterateFields();
field := iterator.next();
BEGIN
self.request := request;
self.vendorName :=
Fmt.F("%s:%s", request.url.host, Fmt.Int(request.url.port));
WHILE field # NIL DO
CASE PaymentField(field) OF
| PF.PaymentProtocol => AppendValue(self.protocols, field.value);
| PF.PaymentCash => AppendValue(self.cash, field.value);
| PF.PaymentAuthorization =>
AppendValue(self.authorization, field.value);
| PF.PaymentBid => AppendValue(self.bid, field.value);
| PF.PaymentReceipt, PF.PaymentOffer, PF.PaymentError =>
log.log(Fmt.F("Illegal payment (field %s: %s) in request: %s",
field.name, field.value,
request.toText(
HTTP.DefaultStyle(request.version), TRUE, log)),
App.LogStatus.Error);
| PF.NotAPaymentField =>
END;
field := iterator.next();
END;
RETURN self;
END InitRequest;
PROCEDURE ToRequest (self: Request; <* UNUSED *> log: App.Log): HTTP.Request =
VAR
req := NEW(HTTP.Request, method := self.request.method,
url := self.request.url, postData := self.request.postData);
BEGIN
self.request.copyFields(req);
IF self.protocols # NIL THEN
EVAL
req.addField(NEW(HTTP.Field).init(ProtocolField, self.protocols));
END;
IF self.cash # NIL THEN
EVAL req.addField(NEW(HTTP.Field).init(CashField, self.cash));
EVAL req.addField(
NEW(HTTP.Field).init(AuthorizationField, self.authorization));
END;
IF self.bid # NIL THEN
EVAL req.addField(NEW(HTTP.Field).init(BidField, self.bid));
END;
RETURN req;
END ToRequest;
TYPE
ProtocolHandlerList = OBJECT
head: ProtocolHandler;
tail: ProtocolHandlerList;
END;
VAR
protocolHandlers: ProtocolHandlerList;
mu := NEW(MUTEX);
PROCEDURE ParseRequest (request: HTTP.Request; log: App.Log): Request
RAISES {App.Error} =
VAR
handlers: ProtocolHandlerList;
field := request.lookupField(ProtocolField);
BEGIN
IF field = NIL THEN
handlers := NIL;
IF App.Verbose() THEN
log.log(Fmt.F("Not a payment request: %s",
request.toText(
HTTP.DefaultStyle(request.version), TRUE, log)),
App.LogStatus.Verbose);
END;
ELSE
LOCK mu DO
handlers := protocolHandlers;
WHILE handlers # NIL AND NOT handlers.head.accept(field.value) DO
handlers := handlers.tail;
END;
END;
END;
IF handlers # NIL THEN
RETURN handlers.head.parseRequest(request, log);
ELSE
RETURN NEW(Request).init(request, log);
END;
END ParseRequest;
PROCEDURE ParseReply (reply: HTTP.Reply; request: Request; log: App.Log):
Reply RAISES {App.Error} =
VAR
handlers: ProtocolHandlerList;
field := reply.lookupField(ProtocolField);
BEGIN
IF field = NIL THEN
log.log(Fmt.F("Not a payment reply: %s",
reply.toText(HTTP.DefaultStyle(reply.version), log)),
App.LogStatus.Error);
END;
LOCK mu DO
handlers := protocolHandlers;
WHILE handlers # NIL AND NOT handlers.head.accept(field.value) DO
handlers := handlers.tail;
END;
END;
IF handlers # NIL THEN
RETURN handlers.head.parseReply(reply, request, log);
ELSE
RETURN NEW(Reply).init(reply, request.request.url.toText(), log);
END;
END ParseReply;
PROCEDURE RegisterProtocolHandler(handler: ProtocolHandler) =
BEGIN
LOCK mu DO
protocolHandlers := NEW(ProtocolHandlerList, head := handler,
tail := protocolHandlers);
END;
END RegisterProtocolHandler;
BEGIN
END HTTPPayment.