MODULEProxy EXPORTSMain ; IMPORT App, FloatMode, Fmt, HTTP, HTTPApp, IO, Lex, ProxyBundle, Rd, RdCopy, Rsrc, Text, TextRd, TextWr, Thread, Wr; VAR port : INTEGER; reject := FALSE; rsrcPath: Rsrc.Path; TYPE RequestHandler = HTTPApp.RequestHandler OBJECT OVERRIDES request := Request; accept := Accept; END; PROCEDUREAccept (<* UNUSED *> self : RequestHandler; <* UNUSED *> request : HTTP.Request; <* UNUSED *> serverData : REFANY; <* UNUSED *> VAR acceptState: REFANY; <* UNUSED *> log : App.Log ): BOOLEAN = BEGIN RETURN TRUE; END Accept; PROCEDURERequest (<* UNUSED *> self : RequestHandler; request : HTTP.Request; <* UNUSED *> serverData, acceptState: REFANY; rd : Rd.T; wr : Wr.T; log : App.Log ) RAISES {App.Error} = BEGIN IF App.Verbose() THEN log.log(Fmt.F("Proxy request headers: %s", request.toText( HTTP.DefaultStyle(request.version), TRUE, log)), App.LogStatus.Verbose); ELSIF App.Debug() THEN log.log( Fmt.F("Proxy request: %s %s", HTTP.MethodText[request.method], request.url.toText()), App.LogStatus.Debug); END; IF reject THEN (* This is an MSM idea to have a proxy to reject add requests... *) HTTP.WriteSimpleReplyHeader( wr, NIL, log, HTTP.StatusCode[HTTP.StatusType.Forbidden], "Rejected by design"); TRY Wr.PutText(wr, "Content-Type: image/gif\r\n\r\n"); Wr.PutText(wr, Rsrc.Get("noads.gif", rsrcPath)); EXCEPT | Rd.Failure, Rsrc.NotFound, Wr.Failure, Thread.Alerted => END; RETURN; END; IF request.method = HTTP.Method.Post AND request.postData # NIL THEN IF App.Verbose() THEN log.log(request.postData, App.LogStatus.Verbose); END; rd := TextRd.New(request.postData); END; HTTPApp.Client( request, HTTPApp.DefaultProxy(), HTTP.DefaultStyle(request.version), rd, wr, NEW(ReplyHandler, request := request), port, log); END Request; TYPE ReplyHandler = HTTPApp.ReplyHandler OBJECT request: HTTP.Request; OVERRIDES reply := Reply; END; PROCEDUREReply (<* UNUSED *> self : ReplyHandler; reply: HTTP.Reply; rd : Rd.T; wr : Wr.T; log : App.Log ) RAISES {App.Error} = VAR twr : TextWr.T; rep : TEXT; contentLengthField: HTTP.Field; length : CARDINAL := LAST(CARDINAL); BEGIN IF App.Verbose() THEN log.log(Fmt.F("Proxy reply headers: %s", reply.toText(HTTP.DefaultStyle(reply.version), log)), App.LogStatus.Verbose); ELSIF App.Debug() THEN log.log( Fmt.F("Proxy reply: %s %s", Fmt.Int(reply.code), reply.reason), App.LogStatus.Debug); END; reply.write(wr, HTTP.DefaultStyle(reply.version), log); contentLengthField := reply.lookupField(HTTP.FieldName[HTTP.FieldType.Content_Length]); TRY IF contentLengthField # NIL THEN TRY length := IO.GetInt(TextRd.New(contentLengthField.value)); EXCEPT | IO.Error => log.log("Proxy error copying request\n", App.LogStatus.Error); END; END; IF App.Verbose() THEN twr := TextWr.New(); EVAL RdCopy.ToWriter(rd, twr, length); rep := TextWr.ToText(twr); log.log(rep, App.LogStatus.Verbose); Wr.PutText(wr, rep); ELSE EVAL RdCopy.ToWriter(rd, wr, length); END; EXCEPT Rd.Failure, Thread.Alerted, Wr.Failure => log.log("Proxy error copying reply\n", App.LogStatus.Error); END; END Reply; TYPE Arg = {Port, Pac, Reject}; TYPE ArgHandler = App.ArgHandler OBJECT OVERRIDES set := SetArg; END; PROCEDURESetArg ( self : ArgHandler; <* UNUSED *> src : App.ArgSource; value: TEXT; log : App.Log ) RAISES {App.Error} = BEGIN CASE VAL(self.id, Arg) OF | Arg.Port => TRY port := Lex.Int(TextRd.New(value)); EXCEPT | Rd.Failure, Thread.Alerted, Lex.Error, FloatMode.Trap => log.log(Fmt.F("Bad port: %s", value), App.LogStatus.Error); END; | Arg.Reject => reject := Text.Equal(value, "TRUE"); ELSE <* ASSERT FALSE *> END; END SetArg; BEGIN rsrcPath := Rsrc.BuildPath("$PROXYPATH", ProxyBundle.Get()); EVAL NEW(ArgHandler, id := ORD(Arg.Reject), hasParam:= FALSE).init( switchName := "reject"); EVAL NEW(ArgHandler, id := ORD(Arg.Port), paramName := "port", default := "8888").init(switchName := "port", register := TRUE); TRY App.InitializeArguments(logConfiguration := FALSE); HTTPApp.RegisterRequestHandler(port, NEW(RequestHandler)); HTTP.SetProgramInfo( HTTP.ProgramInfo{ type := HTTP.ProgramType.Proxy, name := "Chatty_Client_Proxy/1.0"}); HTTP.SetDefaultViaFieldValue(HTTP.CurrentVersion, port); HTTPApp.Serve(port, port); EXCEPT | App.Error => END; END Proxy.