For those who are unaware — you can use COBOL in two modes: free mode and fixed format mode.
Fixed format mode is (afaik) the original, based on punch card affordances, and specifies specific columns for specific purposes:
* The first 6 columns for line numbers
* Column 7 for the indicator character (notably: * for comments as you can see here https://github.com/jmsdnns/webbol/blob/main/file-structs.cpy )
* Column 8-11 for special division markers, though they can extend beyond (visible in this file: https://github.com/jmsdnns/webbol/blob/main/webserver.cbl)
* Columns 12-72 for ordinary COBOL statements
* Columns 73-80 for programmer comments or whatever notes you like
All the columns are undoubtedly a bit taxing to the modern developer and their tools, so 'free mode' which discards all the above is the suggested default.
But, I think fixed mode is very charming, and if you're going to write COBOL in 2025, you may as well try to get the most authentic experience!
This may help you get the feel (pick the COBOL card at the top). [0]
For an even more authentic experience, write the program on a coding form first, then give it to an assistant for keypunching. [1]
[0] https://www.masswerk.at/keypunch/
[1] https://www.mainframestechhelp.com/tutorials/cobol/coding-sh...
As recently as the 2010s, we used to emit HTML out of COBOL, but fell short of it directly responding to HTTP requests. Instead, we licensed an RPC layer that sits behind Apache and translates HTTP calls through CGI to a listener on the COBOL side that then invokes COBOL programs. Those programs send back HTML strings through the CGIRPC interface and, well, out comes a webpage in your browser.
We're still using it to serve XML and have turned it into a makeshift web service that helps power a traditional web application.
But, honestly, this is way cooler.
What are the security guarantees with writing in COBOL? Like, does COBOL allow out-of-bounds memory access? How does it compare to C or Rust as far as allowing ‘accidental’ security lapses?
Namely, that the code will be read by someone who knows the language. And arguably that the code should be capable of being "self-documenting." Although perhaps people well-versed in COBOL would argue COBOL can be, and I just don't know it.
Cobol on Cogs: http://www.coboloncogs.org/HOME.HTM
Cobol on Wheelchair: https://github.com/azac/cobol-on-wheelchair
MOVE SPACES TO REQUEST-BUFFERI applaud Jms Dnns! This project really makes you think.
I've thought about a COBOL webserver before, but didn't get beyond reading the GnuCOBOL FAQ that mentions it's possible with CGI https://gnucobol.sourceforge.io/faq/gcfaq.html#id1126
I'm definitely going to dig into this project more later. This is very neat!
I never wrote a program on punch cards, but I'd definitely drop card stacks accidentally or get them into a jumble somehow. Having numbered cards and a card sorting machine (radix sort in hardware!) would be extremely helpful then.
A minimal static web server written in COBOL using GnuCOBOL.
index.html for root path requestsmacOS:
brew install gnucobol
Ubuntu/Debian:
sudo apt-get install gnucobol
Fedora/RHEL:
sudo dnf install gnucobol
Clone or download the repository, then compile:
make
This will compile all modules and create the webserver executable.
To clean build artifacts:
make clean
Start the server from the directory you want to serve:
./webserver
The server will start on port 8080 and serve files from the current directory.
# Create a test HTML file
echo "<html><body><h1>Hello from COBOL!</h1></body></html>" > index.html
# Start the server
./webserver
# In another terminal, test it
curl http://localhost:8080/
Once running, you can access files via:
http://localhost:8080/ - serves index.html from the current directoryhttp://localhost:8080/filename.html - serves the specified filehttp://localhost:8080/path/to/file.txt - serves files from subdirectoriesPress Ctrl+C to stop the server.
To change the server port, edit config.cpy and modify the SERVER-PORT value:
01 SERVER-PORT PIC 9(5) VALUE 8080.
Then recompile with make.
webbol/
├── Makefile # Build configuration
├── README.md # This file
├── config.cpy # Server configuration
├── socket-defs.cpy # Socket structure definitions
├── http-structs.cpy # HTTP data structures
├── file-structs.cpy # File handling structures
├── path-utils.cbl # Path validation and sanitization
├── mime-types.cbl # MIME type detection
├── file-ops.cbl # File reading operations
├── http-handler.cbl # HTTP request/response handling
└── webserver.cbl # Main server program
text/htmltext/cssapplication/javascriptapplication/jsonapplication/xmltext/plainimage/pngimage/jpegimage/gifimage/svg+xmlimage/x-iconapplication/pdfAdditional MIME types can be added by editing mime-types.cbl.
.. sequencesPort already in use:
Bind failed - check if port is in use
Another process is using port 8080. Either stop that process or change the port in config.cpy.
Permission denied: Ensure the files you're trying to serve have read permissions and the current user can access them.
File not found (404): Verify the file exists in the current directory where the server is running. File paths are case-sensitive.
This project is released into the public domain. Use it however you'd like.
Built with GnuCOBOL, demonstrating that COBOL can still be used for modern systems programming tasks.
If you're in the context of a professional environment, where you chose the team, it makes sense to be more dogmatic about it to enforce a better overall architecture, and you can safely assume that the next reader at least knows the language already.
Modern COBOL compilers will catch this with an error; if you do manage to compile and run, you'll get a runtime error or immediate crash.
> How does it compare to C or Rust as far as allowing ‘accidental’ security lapses?
COBOL has reference modification that can easily be purposefully used to reference memory outside the bound of the original data you target. It isn't memory safe, it's just very restrictive so many errors/misuses get weeded out during compiling.
* comments use *> at start of line, though I'm not sure i'll keep that
* indentation is flexible, but i prefer how fixed looks
* no column restrictions
for example IT IS YELLING AT US THE WHOLE TIME
PIC 9(9)V99
and the like. What is PIC?Customer: "PERFORM 500-DEDUCT-ACCOUNT-BALANCE"
Bank teller: "Ok, great, and how much?"
Customer:
"01 TRANSACTION RECORD
05 TRANSACTION-AMOUNT PIC 9(9)V99
MOVE 100.00 TO TRANSACTION-AMOUNT"Edit: the numbers in parentheses are repeats. PIC 9(9) means up to 9 digits in the printed representation of the value stored in the variable that has this PIC.