FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Small victory: HTTP microservice without any .lib at all
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Small victory: HTTP microservice without any .lib at all
Posted: Thu Jul 03, 2025 12:33 PM
Hello friends,

After `hbinet.lib` and related files disappeared from the current GitHub Harbour repository,
I simply embedded the original C source directly into my `.prg` file — with the help of ChatGPT — using

#pragma BEGINDUMP ... #pragma ENDDUMP

Result:

a fully functional HTTP microservice in a single `.prg` file

no external `.lib`, no framework, no Apache

runs directly as `.exe`, responds live on port 9090

returns correct JSON — e.g., `{ "status": "ok" }`

This is what real development freedom looks like —
and we have it with FIVEWIN / HARBOUR.


According to ChatGPT, response times under 30 ms are realistic,
since everything runs as a persistent process — no interpreter startup, no CGI overhead.

Best regards,
Otto

Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Thu Jul 03, 2025 07:46 PM
HTTP microservice is now 100% RFC-compliant
The Content-Length is correct
Performance at 2–5 ms = excellent!
Chrome, Firefox, curl = all return clean responses

Posts: 1818
Joined: Wed Oct 26, 2005 02:49 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 12:51 PM
Hola Otto, buenos dĂ­as como estas?

Genial :D :D :D :D estamos necesitando implementar un servicio de esa manera, quería saber si ya esta funcional? y si puedes publicar un ejemplo sobre como hacerlo? y también saber si la lib que estas usando es de pago, para comprarla; claro que antes necesitamos hacer algunas pruebas.

gracias de antemano
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 01:21 PM

Hello Leandro, I'm not planning to create a general-purpose library. What I did was directly include the available source files from the Harbour Contrib GitHub repository using #pragma. The first prototype is just 85 lines and works very well.

At the moment, I still have an issue with mixed requests: curl, Firefox, Chrome – the HTTP protocols behave slightly differently.

Right now, I don't have anything ready to share.

Best regards,

Otto

Posts: 8523
Joined: Tue Dec 20, 2005 07:36 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 03:30 PM

Good afternoon my friend Otto, if you still have nothing to share, forgive my ignorance, but where is the VICTORY? You post some code as if you had won a fierce battle, but you have nothing to share? hahahahahahaha.

Buenas tardes, amigo Otto. Si aún no tienes nada que compartir, perdona mi ignorancia, pero ¿dónde está la VICTORIA? Publicas código como si hubieras ganado una batalla feroz, ¿pero no tienes nada que compartir? Jajajajajaja.

Just kidding, dear Otto, just for fun.

SĂłlo bromeaba, querido Otto, sĂłlo por diversiĂłn.

Gracias, tks.

Regards, saludos.

JoĂŁo Santos - SĂŁo Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 05:42 PM

Hello Joao,

The real success lies in the fact that, despite the library no longer being available on GitHub, I was able to create a working program from the raw C code using #pragma. By now, I'm glad I took this approach—especially since I’ve gained a better understanding of the issues surrounding Winsock.

When working with WebSockets, it becomes clear how sensitive they are to different HTTP protocol variants. If you’ve integrated the code yourself and understand it, you naturally stay "close to the metal" and keep learning. A Windows update can quickly cause malfunctions—and if you're just using a third-party library, you're dependent on others until someone releases an update.

Now, in case of errors, I receive very clear feedback, for example:

Return Value Meaning

0 Success – Winsock was successfully initialized

WSASYSNOTREADY The network subsystem is not ready

WSAVERNOTSUPPORTED The requested Winsock version is not supported

WSAEINPROGRESS A blocking Winsock operation is already in progress

WSAEPROCLIM Maximum number of tasks or threads has been reached

WSAEFAULT Invalid pointer to the WSADATA structure (e.g., NULL)

Of course, it's not like you just sit down and everything works immediately. Questions like how to secure, deploy, or use the services productively later on are complex. But I’m convinced: the topic of microservices for DBF is exactly the kind of future many developers are looking for.

Many people today are facing the issue that traditional client-server programs with DBF files over network drives have become too sensitive to network disruptions. New ADS licenses aren’t available everywhere—so a lightweight, custom microservice for DBF access is a very welcome alternative.

As for sharing code: of course you’re happy to share—but you hope for feedback or at least a bit of support. These days, however, you might wait a long time for that.

Why don’t you share it? – That question always comes when you just haven’t shared it.

But when you do share it, the silence is often deafening.

Who shares code, waits for feedback.

Who doesn’t share it, gets it immediately.

Let me finish developing it first.

Best regard,

Otto

Posts: 231
Joined: Fri Jul 20, 2012 01:49 AM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 05:55 PM
It’s really cool for testing—I’ve done it several times on different OSes.

But in the end, you already have a solid and good alternative: Charly UT solution.

• https://github.com/carles9000/ut
• https://github.com/carles9000/ut.samples/tree/main

(Note: I’m not using it myself, but I’ve heard from some users that it’s a great solution. And from what I’ve discussed with Charly, his work is really impressive!)

In the end, you’ll still need to write some code to analyze POST/GET requests and handle different types of JSON/FORM data.

You can definitely save time by using it! 😄

But if it’s just for personal experience, it’s a really fun exercise—go for it! 👍
Regards,

Lailton Fernando Mariano
Posts: 8523
Joined: Tue Dec 20, 2005 07:36 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 06:53 PM

My dear master Otto, I fully trust that you will be absolutely successful in your journey. Take as much time as you need to develop something complete for your own use or for others. The important thing is that you never give up. Thank you for the feedback. Although I was just breaking the "ice" with you. Hahahahahaha. Strength and forward!

Mi querido maestro Otto, confío plenamente en que tendrás un éxito rotundo en tu camino. Tómate el tiempo que necesites para desarrollar algo completo para ti o para los demás. Lo importante es que nunca te rindas. Gracias por tus comentarios. Aunque solo estaba rompiendo el hielo contigo. Jajajajaja. ¡Fuerza y ​​adelante!

Gracias, tks.

Regards, saludos.

JoĂŁo Santos - SĂŁo Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 06:58 PM
Hello Lailton,

The most important aspect today is maintainability of software and compatibility with ChatGPT & similar tools.
Our programming must be AI-friendly – meaning: understandable, modular, well-documented, and analyzable.


What I’m doing here is a web service, not to be confused with what Charly is doing via UT.
The goal is to move DBF files to a server and access them using curl, fetch() or php file_get_contents().
No more network drives, no more local file access.

Discussion: Does everything really need to be built as a class? (Harbour/Xbase++)

I’d like to open a discussion on whether the reflex “everything must be built as a class” is still appropriate today.

This mindset comes from the classical OOP school (C++, Java, later C#) – useful in the 1990s/2000s to structure complex desktop applications.

However, in today’s world – with microservices, clean APIs, scripts, JSON, and AI – this class obsession is often a disadvantage.

Better suited approaches include:
Modularization without class hierarchies
Pure functions and stateless design
Plain JSON instead of object serialization


Simple composition instead of inheritance

This makes code easier to test, refactor, and analyze – even for tools like ChatGPT or static analysis tools.
And: It remains flexible for future development – whether in PHP, Node.js, Python, or Harbour.


And the same applies to libraries:
Instead of large, monolithic frameworks with deep class hierarchies, today's demand is for lightweight, modular libraries – ideally with clear, documented functions that can also be used in isolation.

This not only helps with debugging, but also with integration into AI tools, static analysis, or the gradual migration of legacy systems.


Looking forward to your thoughts on:

Web service vs. traditional DBF access
Class obsession vs. modular units
How do we code “future-proof”?

Best regards,
Otto
Posts: 231
Joined: Fri Jul 20, 2012 01:49 AM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Fri Jul 04, 2025 08:26 PM
I got it. really good.

Keep going and share your progress with us, all it is very intersting 8)
Regards,

Lailton Fernando Mariano
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Sat Jul 05, 2025 01:21 PM

Microservices thrive on Winsock – and few people realize how much this silent network API does behind the scenes. Winsock has been a core part of Windows since version 3.11 (via ws2_32.dll) and forms the bridge between your code and the TCP/IP stack in the kernel.

And it doesn't take many commands: with socket(), bind(), listen(), accept(), recv(), and send(), you have everything you need for a high-performance TCP server. No framework, no overhead – just direct access to what matters. Ideal if you're working at the C level – efficient, portable, and understandable.

What many underestimate: recv() with timeout works without custom timers – the OS handles it via setsockopt(). send() automatically segments and buffers. And accept() doesn’t block in a loop – it’s intelligently awakened by the kernel.

If you're still opening F:\kunden.dbf over a network share, you're using yesterday's technology. SMB is error-prone, not process-safe, and unsuitable for modern applications. The clear path leads to microservices: instead of opening a file, you send GET /kunde?such=meier – and the server responds with targeted JSON.

Bottom line: Winsock is not an outdated relic, but a stable, efficient TCP manager – perfect for building your own microservices, especially in DBF-based systems. Few commands, maximum control – ideal for those who want something lean and robust.

Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Sun Jul 06, 2025 06:17 AM
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Sun Jul 06, 2025 04:36 PM
Microservice Implementation with Harbour



🔹 Left Side (C-Part in #pragma BEGINDUMP)
This is the low-level HTTP microservice server, written in C using Winsock, embedded in Harbour via #pragma BEGINDUMP.

Key Sections:
HB_FUNC( STARTHTTPSERVER )
– This is the main entry point, triggered by StartHttpServer() from Harbour.

while (1)
– An infinite loop that continuously listens for incoming TCP connections (blocking accept()).

-> ROUTER
– This comment marks the internal routing logic, which checks for request paths like /search.

-> CLIENTSOCKET_RESPONSE
– Here, the server prepares and sends back the HTTP response (usually JSON) to the client.

The orange arrow shows the flow:

StartHttpServer() is called,

a request is received,

routed based on URL,

a response is generated and sent back to the client.

🔹 Right Side (Harbour Code – SearchName() function)
This is the business logic part written in Harbour. It defines what happens when /search?name=... is called.

Step-by-step breakdown:
Variable Setup

cPRGPATH points to the DBF file: "x:\xxhdaten\DATAWIN\KUNDEN.dbf"

a is the array that will hold the search results

USE ... SHARED
– Opens the DBF file with alias "data" in shared mode (multi-user safe)

Loop Through Records
– do while !eof() loops over each record in the DBF

Lines 29–31 (highlighted)
– Extracts the fields: name, ort, plz
– Converts them using my_AnsiToUtf8() to ensure UTF-8 output (important for JSON and web)

AAdd() in Line 34
– Adds each record as an associative array to the result array a

Limit to 20 results
– The loop exits early if more than 20 records are added

Return JSON
– hb_jsonEncode() serializes the result into JSON and returns it to the C-part

🔄 How Both Parts Work Together
A client (e.g. browser or search.php) sends:
GET /search?name=max

The C-based microservice parses the request

Calls Harbour like:
SearchName("max")

The Harbour function:

Opens KUNDEN.dbf

Collects matching records

Returns them as a JSON array

The C-part builds a full HTTP response and sends it back to the client

🧾 What the Client Receives
The client (e.g. a browser or a PHP proxy) receives a response like:

json
Kopieren
Bearbeiten
{
"status": "ok",
"results": [
{ "name": "max", "ort": "Testhausen", "plz": "1234" },
...
]
}



Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Wed Jul 09, 2025 10:26 AM
With the new WebSocket-based microservice, I was able to significantly improve performance compared to the previous timer-based file approach.

Example:
When updating a single column in a table, the execution time dropped from around 135 ms to under 35 ms – a gain of more than 100 ms.

Instead of relying on temporary files, the communication now runs directly over WebSocket as a transport channel.
At the same time, the race condition during parallel access was reliably eliminated.


Router
if (stricmp(httpMethod, "POST") == 0)
    {
        if (stricmp(httpPath, "/updaterecord") == 0)
        {
            jsonBodyStart = strstr(recvbuf, "\r\n\r\n");
            if (jsonBodyStart)
            {
                jsonBodyStart += 4;
    
                snprintf(logMsg, sizeof(logMsg), "Route: POST /updaterecord (Body: %s)", jsonBodyStart);
                loglineEx(logMsg, __LINE__);
    
                hb_vmPushSymbol(hb_dynsymSymbol(hb_dynsymFindName("HANDLEEDITRECORD")));
                hb_vmPushNil();
                hb_vmPushString(jsonBodyStart, strlen(jsonBodyStart));
                hb_vmDo(1);
                json = hb_parc(-1);
    
                BuildJsonResponse(response, sizeof(response), json, connection);
            }
            else
            {
                snprintf(response, sizeof(response),
                         "HTTP/1.1 404 Not Found\r\n"
                         "Content-Type: text/plain\r\n"
                         "Content-Length: 10\r\n"
                         "Connection: close\r\n\r\nNot found.");
                loglineEx("Route: POST unknown → 404", __LINE__);
            }
        }
    }
harbour-function
FUNCTION HANDLEEDITRECORD( cJson )
    LOCAL h := {}
    LOCAL cDbf
    
    hb_jsonDecode( cJson, @h )
    
    DebugHash( h, "HANDLEEDITRECORD" )
 
    ? "EditRequest:"
    ? "cDbf",  h["databasePath"]
    ? "RecordId:  ", h["recordId"]
    ? "Column:    ", h["columnName"]
    ? "New Value: ", h["newValue"]
    cDbf    := h["databasePath"]

    USE ( cDbf ) NEW ALIAS DATA SHARED
    GOTO VAL( h["recordId"] )
    
    IF !EOF()
       DBRLOCK()
       FIELD->&( h["columnName"] ) := h["newValue"]
       DBUNLOCK()
    ENDIF
    CLOSE DATA

? "OK - gespeichert"

 RETURN hb_jsonEncode( { "success" => .T., "status" => "ok", "message" => "Daten empfangen (Dummy)" } )
Posts: 231
Joined: Fri Jul 20, 2012 01:49 AM
Re: Small victory: HTTP microservice without any .lib at all
Posted: Wed Jul 09, 2025 05:40 PM

Otto,

Have you tried the CGI with windows IIS?

I have program accessing database, doing operation with less 30ms using that ( from a remote pc )

Regards,

Lailton Fernando Mariano