Forum > Third party

HTTP/2+HTTP/1.1+WebSocket server with Free Pascal

(1/2) > >>

iLya2IK:
The fpweb library is certainly good, but it clearly lacks modern features - namely, full-fledged http/1.1 with persistent connections, and also http/2. I completed my search for the desired analog by creating a server with all the necessary. I would like to present to your attention my project - WCHTTPServer.

The project builds on the fcl-web library and extends it to increase functionality:

Client management using cookies (saving and maintaining sessions).

* Saving information about clients and sessions in SQLite database.
* Saving information about the latest requests and saving logs in SQLite database.
* Multithreading preparation and execution of requests based on thread pools e.g. helpful classes to work with EventSources.
* Client rankings based on the frequency of client requests.
* Built-in support for gzip and deflate compression methods.
* The WebSocket (RFC 6455) protocol is supported with the "permessage-deflate" extension (RFC 7692).
* Ability to start the server both in HTTP/2 (RFC 7540) mode and in HTTP/1.1 mode.
* Modified OpenSSL modules (added necessary TLS extensions) in order to create and maintain HTTP/2 connections.
* Added the ability to save the master key and a random set of client data on the server-side (necessary for debugging TLS dumps using WireShark).
* Works under both Windows and Linux
Link to project on GitHub : https://github.com/iLya2IK/wchttpserver

At the moment, the server follows the RFC 7540 specification fairly closely, but I continue to test and debug to meet a number of non-obvious protocol requirements. For testing, I use the h2spec and h2load utilities. 


--- Code: XML  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# h2spec -p 8080 http2 -t -k -o 2094 tests, 91 passed, 0 skipped, 3 failedHypertext Transfer Protocol Version 2 (HTTP/2)  4. HTTP Frames    4.2. Frame Size            × 1: Sends a DATA frame with 2^14 octets in length        -> The endpoint MUST be capable of receiving and minimally processing frames up to 2^14 octets in length.           Expected: HEADERS Frame (stream_id:1)             Actual: Connection closed            Comment: Error in h2spec - DATA payload size didn't equal the value of "content-length" header.     5. Streams and Multiplexing    5.5. Extending HTTP/2            × 2: Sends an unknown extension frame in the middle of a header block        -> The endpoint MUST treat as a connection error of type PROTOCOL_ERROR.           Expected: GOAWAY Frame (Error Code: PROTOCOL_ERROR)                     Connection closed             Actual: Timeout            Comment: I didn't find any references in RFC 7540 that unknown extension frame in the middle                     of a header block should cause a connection error   8. HTTP Message Exchanges    8.1. HTTP Request/Response Exchange      8.1.2. HTTP Header Fields        8.1.2.2. Connection-Specific Header Fields                    × 1: Sends a HEADERS frame that contains the connection-specific header field            -> The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.               Expected: GOAWAY Frame (Error Code: PROTOCOL_ERROR)                         RST_STREAM Frame (Error Code: PROTOCOL_ERROR)                         Connection closed                 Actual: DATA Frame (length:845, flags:0x01, stream_id:1)                Comment: I know that this violates the requirements of RFC 7540, but I sincerely consider them                         redundant and the type of reaction to the header value should remain on the server side      
And here are the results of testing with h2load

--- Code: XML  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# h2load -n32000 -c32 -m10 --header=connection:keep-alive --header=cookie:cid=11  https://localhost:8080        starting benchmark...spawning thread #0: 32 total client(s). 32000 total requestsTLS Protocol: TLSv1.2Cipher: ECDHE-RSA-AES256-GCM-SHA384Server Temp Key: X25519 253 bitsApplication protocol: h2progress: 10% doneprogress: 20% doneprogress: 30% doneprogress: 40% doneprogress: 50% doneprogress: 60% doneprogress: 70% doneprogress: 80% doneprogress: 90% doneprogress: 100% done finished in 17.22s, 1858.68 req/s, 1.54MB/srequests: 32000 total, 32000 started, 32000 done, 32000 succeeded, 0 failed, 0 errored, 0 timeoutstatus codes: 32000 2xx, 0 3xx, 0 4xx, 0 5xxtraffic: 26.46MB (27746560) total, 126.38KB (129408) headers (space savings 95.01%), 25.79MB (27040000) data                     min         max         mean         sd        +/- sdtime for request:    16.59ms    327.96ms    150.22ms     35.42ms    77.80%time for connect:     7.17ms       1.96s       1.15s    618.49ms    62.50%time to 1st byte:    59.55ms       2.00s       1.20s    629.72ms    62.50%req/s           :      58.09       72.88       61.87        4.42    81.25% # h2load -n32000 -c32 -t8 -m1 --h1 --header=connection:keep-alive --header=cookie:cid=11  https://localhost:8080-t: warning: the number of threads is greater than hardware cores.starting benchmark...spawning thread #0: 4 total client(s). 4000 total requestsspawning thread #1: 4 total client(s). 4000 total requestsspawning thread #2: 4 total client(s). 4000 total requestsspawning thread #3: 4 total client(s). 4000 total requestsspawning thread #4: 4 total client(s). 4000 total requestsspawning thread #5: 4 total client(s). 4000 total requestsspawning thread #6: 4 total client(s). 4000 total requestsspawning thread #7: 4 total client(s). 4000 total requestsTLS Protocol: TLSv1.2Cipher: ECDHE-RSA-AES256-GCM-SHA384Server Temp Key: X25519 253 bitsApplication protocol: http/1.1progress: 10% doneprogress: 20% doneprogress: 30% doneprogress: 40% doneprogress: 50% doneprogress: 60% doneprogress: 70% doneprogress: 80% doneprogress: 90% doneprogress: 100% done finished in 29.06s, 1101.26 req/s, 1.01MB/srequests: 32000 total, 32000 started, 32000 done, 32000 succeeded, 0 failed, 0 errored, 0 timeoutstatus codes: 32000 2xx, 0 3xx, 0 4xx, 0 5xxtraffic: 29.39MB (30816000) total, 2.53MB (2656000) headers (space savings 0.00%), 25.79MB (27040000) data                     min         max         mean         sd        +/- sdtime for request:     7.99ms    208.16ms     26.31ms      5.94ms    93.71%time for connect:     8.22ms       3.08s       1.25s    943.18ms    62.50%time to 1st byte:    99.48ms       3.12s       1.31s    913.25ms    62.50%req/s           :      34.42       38.74       36.31        1.25    62.50%

iLya2IK:
The latest update adds support for the websocket protocol, and therefore the demo site has been changed. As an example of interaction over the websocket protocol, the JSON-RPC application level protocol (well, or some of its similarity  ::) - you can change it to your own) is used. Now I am working on adding the permessage-deflate extension (RFC 7692)

Leledumbo:
While I admire this work, I find it hard to not have a clear separation between which files belong to the library/package, demo/examples and so on. See fcl-web's own directory structure as an example.

iLya2IK:

--- Quote from: Leledumbo on May 14, 2021, 05:23:49 am ---While I admire this work, I find it hard to not have a clear separation between which files belong to the library/package, demo/examples and so on. See fcl-web's own directory structure as an example.

--- End quote ---

Yes, I get it - this is really a problem. I will start reworking the repository in the near future.

iLya2IK:
The structure of the project has been put in order. Added lpk file. The "permessage-deflate" extension for websocket has been fully implemented.

Navigation

[0] Message Index

[#] Next page

Go to full version