Chilkat Forum

Technologies => REST / HTTP / HTTPS => Topic started by: Chilkat on February 28, 2018, 09:13:28 AM

Title: Write an HTTP Server using Chilkat?
Post by: Chilkat on February 28, 2018, 09:13:28 AM
I need to write a small http server to get remote access to my application. I tried to find anything that I could use to write a http server in the Chilkat library. Didnít find anything, but just wanted to be sure that I havenít missed anything before finding another simple solution.
Title: Re: Write an HTTP Server using Chilkat?
Post by: Chilkat on February 28, 2018, 09:48:32 AM
There is no simple solution.  Yes, one *can* write a simple HTTP server.   If one Google's "write an HTTP server", you'll get results such as "Write an HTTP server in 500 lines or less" or "Write a simple HTTP server", etc.   Whatever implementation you find by following these links is likely to be just a fragile toy.

You can write an HTTP server with limited functionality which may serve your needs.  It's important to fully understand the scope of what's potentially involved in writing an HTTP server, so you can understand what cababilities your simple implementation may lack.

If I were to begin writing an HTTP server, this is how I would begin.   (First, I would purchase the O'Reilly book "HTTP: The Definitive Guide" as a reference.  Reading the 1st few chapters is good for a fundamental understanding. The remainder is good for reference.  No need to read these books end-to-end.  Eventually, you'll have read it all many times over if you work often with HTTP..)

So here are the steps:

1) Design your architecture for receiving incoming connections and how each accepted connection is handled (perhaps in it's own thread).  We're just talking about non-SSL/TLS port 80 for now.

2) An incoming HTTP request begins with a "start line" ending with a CRLF.  Read that and parse it.  (You need a socket API that can read the socket until a particular desired string is returned.  Chilkat Socket provides a ReceiveToCRLF method.)

3) HTTP requests and responses are MIME.  The HTTP request MIME header follows the start line, so you can read until a double-CRLF is received.  (MIME headers are separated from MIME bodies with a double CRLF.)   For example, you could call Chilkat.Socket.ReadUntilMatch("\r\n\r\n");   

4) You can parse the MIME header using Chilkat.Mime (or CkMime in some programming languages).   Load the HTTP request MIME header by calling Chilkat.Mime.LoadMime.  Now you have access to information about the request.  In the simple case, you'll find a Content-Length header field that indicates the exact number of bytes that constitute the MIME body of the request, which should follow the MIME header. 

5) Read the number of bytes indicated by Content-Length.  Don't assume you have text.  Call Chilkat.Socket.ReceiveBdN to read the MIME body.   But first, append the MIME header to the Chilkat.BinData object you pass to ReceiveBdN.  The ReceiveBdN method will append incoming bytes to the BinData object.  Now you have the full HTTP MIME request in a BinData object.  Create a new Chilkat.Mime object instance and load the full MIME by calling Mime.LoadMimeBd.   This solves a huge amount of potential complexity because the Chilkat.Mime class is correctly handling encodings, charsets, etc.  You can now access the parts of the HTTP request via the Chilkat.MIME API.

6) The response you formulate is similar to the HTTP request.  It's a "start line" followed by the HTTP response, which is MIME.  You could potentially use Chilkat.Mime to compose your response, or you could emit the response as you see fit.  The important part of the response is to ensure the value in the Content-Length response header is the exact raw size of the MIME body that follows.

The above is just the start..  It's still just a toy because there are potentially a huge number of things to consider:

1) Will "chunked encoding" HTTP requests be received?  Should for large responses, should "chunked encoding" responses be sent?

2) How to handle Authentication?  (If a request uses an Authorization header.)

3) Handle the "Expect: 100-continue" header.

4) What if the request uses a gzip Content-Encoding?  Would you want to send a compressed response?

5) How to listen on port 443 w/ TLS?  (Chilkat.Socket can do it, but you'd need a certificate, possibly self-signed if the client doesn't care..)

6) What about anything to do with proxies?

Anyway.. the list goes on and on.  You can build a simple HTTP server, with the awareness of what's lacking so you're not surprised when something's not working because a particular feature is needed. Then, of course, you could add features over time until one day you'll have something that's truly not a toy anymore..  :)