TBrookHTTPServer
brook是c写的,以dll供delphi和lazarus调用。
unit Brook.HTTPServer; //cxg 2023-2-12 interface uses sock.router, System.JSON, Json.help, keyValue.serialize, api.router, BrookHTTPRequest, BrookHTTPResponse, BrookHTTPServer, global, IniFiles, Classes, SysUtils; var BinApis: TJSONObject; //二进制API RestApis: TJSONObject; //REST API,包括json,protobuf const //content-type cBin = 'application/octet-stream; charset=utf-8'; cJson = 'application/json; charset=utf-8'; cProtobuf = 'application/protobuf; charset=utf-8'; type TbrookServer = class(TBrookHTTPServer) protected procedure DoRequest(ASender: TObject; ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse); override; public constructor Create; overload; destructor Destroy; override; end; var SERVER: TbrookServer; implementation function strof(const aBytes: TBytes): RawByteString; overload; begin SetLength(Result, Length(aBytes)); Move(aBytes[0], Result[1], Length(aBytes)); end; function ReadJsonFile(const FileName: string): string; begin var f: TStringList := TStringList.Create; f.LoadFromFile(FileName, TEncoding.UTF8); Result := f.Text; f.Free; end; procedure setHeader(const Ctxt: TBrookHTTPResponse); begin Ctxt.Headers.Add('Access-Control-Allow-Origin', '*'); Ctxt.Headers.Add('Access-Control-Allow-Methods', '*'); Ctxt.Headers.Add('Access-Control-Allow-Headers', '*'); end; procedure router(const Ctxt: TBrookHTTPRequest; const Ctxt2: TBrookHTTPResponse); //brook router begin if Pos('/bin', Ctxt.path) > 0 then //二进制 API begin setHeader(Ctxt2); var req: TSerialize := tserialize.Create; var res: TSerialize := tserialize.Create; if Ctxt.Payload.Length > 0 then req.unMarshal(Ctxt.Payload.Content); var url: string := Ctxt.path; var arr: TArray<string> := url.Split(['/']); var funcName: string := arr[2]; var ja: TJSONArray := BinApis.A['bin']; for var i: Integer := 0 to ja.Count - 1 do begin var o: TJSONObject := ja.Items[i] as TJSONObject; if o.S['funcname'] = funcName then begin RouterAPI(o.S['classname'], o.S['funcname'], [req, res]); Break; end; end; var r: TBytes := res.marshal2; Ctxt2.SendBytes(r, Length(r), cBin, 200); req.Free; res.Free; end else if Pos('/rest', Ctxt.path) > 0 then //JSON API begin setHeader(Ctxt2); var url: string := Ctxt.path; var arr: TArray<string> := url.Split(['/']); var resource: string := arr[2]; var req: TSerialize := tserialize.Create; var res: TSerialize := tserialize.Create; req.asStr['url'] := url; var body: RawByteString; if Ctxt.Payload.Length > 0 then begin body := strof(Ctxt.Payload.Content); req.asStr['body'] := body; end; req.asStr['type'] := 'json'; var ja: TJSONArray := RestApis.A[resource]; for var i: Integer := 0 to ja.Count - 1 do begin var o: TJSONObject := ja.Items[i] as TJSONObject; if o.S['method'] = Ctxt.Method then begin RouterAPI(o.S['classname'], o.S['funcname'], [req, res]); Break; end; end; Ctxt2.Send(UTF8Encode(res.asStr['res']), cJson, 200); req.Free; res.Free; end else if Pos('/protobuf', Ctxt.path) > 0 then //PROTOBUF API begin setHeader(Ctxt2); var url: string := Ctxt.path; var arr: TArray<string> := url.Split(['/']); var resource: string := arr[2]; var req: TSerialize := tserialize.Create; var res: TSerialize := tserialize.Create; req.asStr['url'] := url; if Ctxt.Payload.Length > 0 then req.asBytes['body'] := Ctxt.Payload.Content; req.asStr['type'] := 'protobuf'; var ja: TJSONArray := RestApis.A[resource]; for var i: Integer := 0 to ja.Count - 1 do begin var o: TJSONObject := ja.Items[i] as TJSONObject; if o.S['method'] = Ctxt.Method then begin RouterAPI(o.S['classname'], o.S['funcname'], [req, res]); Break; end; end; var r: TBytes := res.asBytes['res']; Ctxt2.SendBytes(r, Length(r), cProtobuf, 200); req.Free; res.Free; end; end; constructor TbrookServer.Create; var ini: tinifile; begin SERVER := TbrookServer.Create(nil); ini := TIniFile.Create(svrcfg); ini.readinteger('config', 'httpport', 0); var threadnum: Integer := ini.readinteger('config', 'threadnum', 32); if threadnum > 256 then threadnum := 256; server.ThreadPoolSize := threadnum; SERVER.Port :=ini.readinteger('config', 'httpport', 0); ini.free; SERVER.Open; {$IFDEF console} Writeln('New brook http server'); Writeln('Http port: ', SERVER.Port); Writeln('Thread num: ', server.ThreadPoolSize); {$ENDIF} end; destructor TbrookServer.Destroy; begin SERVER.Free; inherited; end; procedure TbrookServer.DoRequest(ASender: TObject; ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse); begin router(ARequest, AResponse); end; initialization binapis := TJSONObject.Create; restapis := TJSONObject.Create; binapis.Parse(ReadJsonFile(ExtractFilePath(ParamStr(0)) + 'binrouter.json')); restapis.Parse(ReadJsonFile(ExtractFilePath(ParamStr(0)) + 'restrouter.json')); finalization FreeAndNil(binapis); FreeAndNil(restapis); end.
标签:begin,end,res,req,TBrookHTTPServer,var,Ctxt From: https://www.cnblogs.com/hnxxcxg/p/17483287.html