
Building a Website with C++ - daftpanda
https://blog.sourcerer.io/building-a-website-with-c-db942c801aee
======
chubot
Really? Escaping, people! This code isn't practical or useful; it's dangerous
and sloppy.

    
    
        cout << "<body>\n";
        ...
        cout << getenv("QUERY_STRING");     
        cout << "</body>\n";
    
    

FWIW I wrote an article about HTML escaping and shell here:
[http://www.oilshell.org/blog/2017/09/19.html](http://www.oilshell.org/blog/2017/09/19.html)

Followup:
[http://www.oilshell.org/blog/2017/09/29.html](http://www.oilshell.org/blog/2017/09/29.html)

Also if you want to use a native language for web sites (which I don't), Go is
a better choice, as the standard library has html/template which protects you
from naive injections:

[https://golang.org/pkg/html/template/](https://golang.org/pkg/html/template/)

~~~
bcjpjk
Yeah... this example code is bad. Not to mention that CGI is slow,
problematic, and chock full of potential security issues. At the very least,
spawning a process per request is a DOS attack waiting to happen, even if the
code were immaculate.

~~~
poizan42
Classic CGI is not the best performing interface, yes. But there's a big
difference in launching a complete interpreter for every request, and running
a small purpose-built native program. And remember that people did manage the
former 20 years ago, sites like Slashdot were running CGI Perl scripts back
then.

I'm not sure about the "chock full of potential security issues". You have to
be careful with trusting environment variables as the Bash guys learned, but I
don't know what else there is that is specific to CGI.

~~~
jayrwren
Forking a process per request is expensive, interpreter or not.

Slashdot used apache mod_perl back then. It never forked a process per
request.

~~~
poizan42
Slashdot started in 1997, the first release of mod_perl was on 12.03.1998.
They certainly used cgi at first, just check the url here:
[https://web.archive.org/web/19980113191337/http://slashdot.o...](https://web.archive.org/web/19980113191337/http://slashdot.org:80/slashdot.cgi?mode=contrib)
\- it says cgi right there.

Edit: Seems I was wrong about the date, it was actually 28-Jul-1997[1],
nevertheless slashdot was only launched two months later, and as the link
above witnesses didn't seem to have used it at first.

[1]:
[https://web.archive.org/web/19971210053529/http://perl.apach...](https://web.archive.org/web/19971210053529/http://perl.apache.org:80/src/)

------
byuu
I run [https://byuu.org](https://byuu.org) using C++. Not just for page
generation, but also for the server itself. It's all a single package, so no
CGI is involved. Although I do use nginx as an HTTP->HTTPS proxy because TLS
is scary. It's handled being linked on the front page of a few major sites
with no issues.

In my case, I just prefer coding in that language over PHP et al. It's on a
$2.50/mo VPS and I can spawn a new instance in five minutes if need be. Every
memory access (for strings, vectors, etc) go through containers with bounds
checking. The server/webapp itself runs as its own unprivileged user. If the
server crashes, it'll stay offline and give me a core dump, which should let
me find and fix the bug in my library.

The code's open, too:
[https://gitlab.com/higan/higan/blob/master/nall/http/server....](https://gitlab.com/higan/higan/blob/master/nall/http/server.hpp)

It's certainly not 100% perfect security, but what really is? Between
Heartbleed, Meltdown, Spectre, weekly Wordpress exploits, etc ... I don't
think the risk is particularly higher.

(aside: the forum runs on PHP on another VPS instance; separation of security
concerns.)

~~~
jchw
Oh hey, you are still using Vultr? How have they been? I'm pretty sure I'm the
one who suggested it some years ago on the forum and have wondered ever since
if the at least then-unproven VPS company ended up being reliable. It looks
like their prices have stayed competitive at least!

~~~
whb07
I’m using vultr now and I vastly prefer it over Linode (I’ve yet to fully try
DO).

It’s super simple UI to start an instance with a basic script (like update
distro and developer tools etc). Lastly, you can pass in your pub keys and
just ssh directly without doing it yourself the moment you log in for the
first time.

All in all highly recommend it!

~~~
jchw
I will have to try Vultr again. My last experience was good, but regrettably I
still use DO and AWS for everything.

Remarking on that, Digital Ocean is nothing special, but they have added some
nice features in the past year or two. I like that their control panel
supports multiple teams with permissions, I like that it has a nice tag-based
firewall, the DNS service works fine, and it has an S3 clone called Spaces
which is pretty handy. I believe they also announced recently that private
networking would be isolated per-team instead of being the entire data center,
another networking improvement that most low-end VPSes do not provide.

All in all, if you just need a low end VPS, I would say there's no fault in
going with something like Vultr, but Digital Ocean adds a few extra features
that might be more useful if you're developing a medium-complexity system. Of
course though, at that point, you probably want to at least consider Google
Cloud Platform, a reasonably cost-effective host with very rich features. (And
AWS, but my feelings for AWS have shrunk in recent times after having better
experiences with GCP consistently at my day job.)

------
fuball63
I'm in the early stages of a FaaS platform that uses CGI for the functions. As
such, I have been collecting articles about general CGI development, and have
them listed in my docs. If anyone is interested in writing large scale CGI
apps (CGI is popping up a lot around here lately), these are some good
resources: [https://bigcgi.com/docs](https://bigcgi.com/docs)

~~~
ddorian43
Isn't cgi slow ? Don't you need something like fast-cgi (which lambda does I
think) ?

~~~
fuball63
CGI is slow because of the spin up time for individual processes for each
request. FastCGI is fast because they run as one long running process that
handles multiple requests.

While plain CGI is a slower, the advantage is that you don't have long running
and potentially idle processes for low traffic periods, and process isolation
is a little security boost.

I chose to have a slightly slower startup time, which hopefully remain
constant in a load balanced cluster, to gain the advantages above.

~~~
dfox
Also the spinup time is considerably larger problem for various interpreters
and virtual machines than for native code binary.

I would even expect that you can write non-trivial CGI application whose
startup time is smaller than the additional overhead from parsing of the
FastCGI protocol.

------
flatline
Pion[0] is a fairly robust and well-written HTTP server implementation in C++.
You can spin up a server very quickly and reverse proxy through Apache or
Nginx. Microsoft has a cross-platform offering of some sort in the works using
C++11, now I don’t remember the name but I think Herb Sutter has a write-up in
it from a couple years ago. It’s definitely possible to write modern web
applications in C++, I feel like the cgi route is pretty old school.

[0] [https://github.com/splunk/pion](https://github.com/splunk/pion)

~~~
zura
> Microsoft has a cross-platform offering of some sort in the works using
> C++11

Casablanca, but I'm not sure how active is the project nowadays.

~~~
RotsiserMho
It's called the C++ REST SDK
([https://github.com/Microsoft/cpprestsdk](https://github.com/Microsoft/cpprestsdk))
now and is fairly active. I've used it client-side and I've really enjoyed it.

------
billconan
I wrote a c++/Qt web framework as a hobby.

[https://github.com/shi-yan/Swiftly](https://github.com/shi-yan/Swiftly)

------
awiesenhofer
Reminds me of the BCHS-Stack: BSD, C, httpd, SQLite.

[https://learnbchs.org/](https://learnbchs.org/)

I am still unsure if its satire or not.

------
utopcell
Using CGI is silly and slow, for all but the simplest, stateless servers. If
one wishes to avoid the overhead of learning a new framework, at least FastCGI
should be considered. A relevant (but dated) discussion about web frameworks
in C++ can be found in [1].

I am personally a big fan of CROW [2] and have used it many times in the past.

[1]
[https://softwareengineering.stackexchange.com/questions/5362...](https://softwareengineering.stackexchange.com/questions/53624/can-
c-be-used-as-a-server-side-web-development-language) [2]
[https://github.com/ipkn/crow/blob/master/README.md](https://github.com/ipkn/crow/blob/master/README.md)

~~~
chubot
CGI isn't slow -- starting interpreters is slow. Starting Python or Ruby can
easily be 1000x more expensive than starting a process in C, which takes
MICROSECONDS, not hundreds of milliseconds.

See this 7 year old message by Richard Hipp (of sqlite):

[https://www.mail-archive.com/fossil-users@lists.fossil-
scm.o...](https://www.mail-archive.com/fossil-users@lists.fossil-
scm.org/msg02065.html)

[https://news.ycombinator.com/item?id=3036124](https://news.ycombinator.com/item?id=3036124)

 _This server takes over a quarter million requests per day, 10GB of traffic
/day, and it does so using less than 3% of of the CPU on a virtual machine
that is a 1/20th slice of a real server._

~~~
goldenkey
People just throw around qualifier attacks these days without thinking about
the reality of modern processing power and what is really overoptimization.
Just because CGI is slow-er- does not make it slow. So many hours are wasted
on overoptimization, myself guilty of it - simply because of OCD type
tendencies. I hope when I am finally on my deathbed I am not picky about the
color of the sheets...

------
marmaduke
I was expecting something like Wt
([https://www.webtoolkit.eu/wt](https://www.webtoolkit.eu/wt))

~~~
stargrazer
I would suggest/recommend this as well.

------
xaduha
If you want to use something like that for web, then use
[http://websocketd.com](http://websocketd.com). There's no need to generate
html on the server, unless you really don't want to touch JS at all.

------
bsenftner
Interested parties desiring production quality security and significanlty
better performance than CGI, check out the C++11 library Restbed
[https://github.com/corvusoft/restbed](https://github.com/corvusoft/restbed)
Restbed replaces Apache, or put another way puts the web server inside your
application, so your C++ app is its own server. It is easy to create REST APIs
with executable as small as 100K, and that is all you need - no Apache or
Nginx other web server needed. I have created a fairly sophisticated facial
recognition REST API that host itself, only occupies 500K and can run circles
around pretty much anything - while running on a $99 Intel Compute Stick. I've
created web sites and servers and web APIs in a most of the fashionable web
best practices, and I gotta say Restbed blows everything away.

~~~
bjornlouser
Looks great but it's AGPL unless you buy a license.

~~~
bsenftner
Sometimes, software is worth paying for...

------
dahart
> In this article, I’ll explain how you can use C++ to develop a website and
> some concrete reasons why you might consider doing so.

I only saw one reason: performance. Did I miss some? Do people have other good
use cases that justify paying the dev cost of using C++ for a web server? I'd
guess with caching and a decent backend, it would be fairly hard to
demonstrate a true need for performance that requires C++, but I'm sure there
are a few demanding applications out there that need it.

Since a web page's throughput is usually network bottlenecked and not CPU
bound, I'm curious (just for fun) what the max possible performance benefit of
going C++ is, especially behind a CGI interface?

There's probably a small latency benefit at all times, and I'd guess there's a
throughput benefit that is only visible if you're doing more than a few
thousand requests per second..?

~~~
ecshafer
I doubt the performance of a c++ web site would be better than c#/java or some
other compiled languages for most non-trivial web sites. Once things like jits
come into play, and you see large projects (1million+ loc) the performance
advantage of c++ often disappears or it becomes less performant for things
like web sites. Most companies do not have the time nor ability to do all
those optimizations that theoretically exist that would make c++ more
performant.

This isn't even counting the dev time difference

~~~
kazinator
> _c++ web site would be_

No "would" about it C++ web sites are real and have been around for a long
time. I'm thinking of sites running on Windows using "ISAPI".

~~~
dahart
Is their performance demonstrably better than other sites? Parent wasn't
saying that c++ sites don't exist, just speculating that it doesn't
necessarily make the site clearly faster to browse. I'd speculate the same,
but would appreciate if there's hard data around to educate me, I'm genuinely
curious what the benefits of going c++ are.

------
booleandilemma
Reminds me of this:

[https://m.imgur.com/r/ProgrammerHumor/INBvStO](https://m.imgur.com/r/ProgrammerHumor/INBvStO)

------
stargrazer
Some other libraries I have seen for http protocol based applications:

[https://github.com/Qihoo360/evpp](https://github.com/Qihoo360/evpp) \-
network library for developing high performance network services in
TCP/UDP/HTTP protocols

[https://github.com/rep-movsd/see-phit](https://github.com/rep-movsd/see-phit)
\- C++ HTML template engine that uses compile time HTML parsing

[https://github.com/boostorg/beast](https://github.com/boostorg/beast) \- HTTP
and WebSocket built on Boost.Asio in C++11

[https://github.com/emweb/wt](https://github.com/emweb/wt) \- Wt, C++ Web
Toolkit

~~~
kakwa_
Personally, I've used:
[https://github.com/civetweb/civetweb](https://github.com/civetweb/civetweb)

(for implementing an RFC 3161 (crypto timestamp) service.

It's a fork of
[https://github.com/cesanta/mongoose](https://github.com/cesanta/mongoose)

(The Civetweb fork exists due to Mongoose license switch from MIT to GPLv2)

------
sddfd
Bevor I'd use C++ I'd take a hard look at Go, figure out whether I really need
C++ performance, or whether Go is just good enough.

Go is rather performant and in contrast to C++ memory safe.

~~~
pleasecalllater
If you say that C++ is not memory safe you really don't know the modern C++.
Of course you can use only `void *` everywhere... but you can also write your
software in a totally different way. My C++ code has no pointers, just
objects, which are automatically destroyed when I want to. The nice feature is
that I know when the destructor is called, so the object will clear itself in
a very nice way.

~~~
nercury
It's futile battle though to achieve both performance and safety in C++: as an
example, safety requires avoiding moves, using reference counting, while
achieving performance means avoiding copies and passing occasional references
around, among other things. That's why advertising C++ solution as fast does
not work well with "but C++ can be safe too!".

~~~
bcjpjk
Moves can be safe, and copies can be dangerous.

C++ is a language that can be used like a sawed-off shotgun propped against a
developer's foot, and with a hair trigger. Granted, it does not _have_ to be
used this way, but it can be.

A good developer can be "safe by default" and can use profile-directed
optimization to speed up areas that are performance critical. A great
developer can build proofs that such performance improvements maintain safety
guarantees. For the average developer, following modern C++ development
practices creates code on par with other languages in terms of both safety and
performance.

For most languages, a lot can be done in terms of optimization, profiling, and
security. Even in higher-level languages, an FFI is available to rewrite
critical portions of code in a lower level language for performance
improvements. Careful attention to detail can provide critical performance
improvements in any language without compromising on safety. Getting there
requires model checking or formal methods, but that is also becoming more of a
part of modern development practices.

~~~
pjmlp
The problem is that many developers don't care, they just want to do something
that works and move on.

This is not specific to C++, but it is worse in C and C++ given the nature of
these languages.

It also doesn't help that management even cares less about QA than those devs.

------
degenerate
What's with all the weird spam at the bottom of these comments? Someone
seriously loves rust.

------
jcelerier
Cutelyst is a nice C++ web server with a much better api imho:
[https://cutelyst.org/](https://cutelyst.org/)

------
z92
I wrote my blog site in C. Runs as CGI and works just as fast as other tech
stacks, say PHP.

C has very low startup time compare to say Java. And process fork-exec isn't
as heavy weight under Linux as in Windows.

~~~
pjmlp
Java can be C like when compiled into native code, OpenJDK isn't the only JVM
around.

------
taylorking
You can do this with libboost with this
[https://github.com/ipkn/crow](https://github.com/ipkn/crow)

------
gumby
> I know it sounds strange, and perhaps even an exercise in novel futility,
> but it isn’t.

Oh come on, C++ is a systems programming language and certainly can handle
this, so “futility” seems over the top. Hell, you can write cgi handlers in
assembly.

Around 94 I wrote Cygnus’ web interface (and then cron job too) to our big
system in sh. Sure, I wouldn’t make the same choice today, but it’s hardly
absurd.

------
allover
Am I right in thinking the main reason not to do this is memory safety (as
demonstrated by Cloudbleed)?

~~~
nkozyra
That's part of what I'd argue is the main argument against: not reinventing
the wheel. The only argument for is experimenting. These are all toy examples.
I'd argue that through CGI it won't even be more performant than opcode cached
interpreted languages.

------
mfontani
This brings me back... I was doing this exact sort of stuff at the turn of the
century, although admittedly in C - not C++ - and using/linking to the Delphi
CGI library.

CGI in 2018 seems a bit passé...

~~~
floatboth
Actually, this new hip function-as-a-service thing feels a lot like CGI/inetd…

well, at least in terms of not keeping the server process up all the time,
only when it's used.

To combine "only running when necessary" and "not restarting for every request
when there's a lot of requests", I made a thing:
[https://github.com/myfreeweb/soad](https://github.com/myfreeweb/soad) —
little wrapper listens on a socket, spawns your server with the socket passed
in, terminates the server when there were no new connections in a while,
rinse, repeat.

~~~
z92
You can check inetd which does exactly that and comes preinstalled and pre
activated with Linux installations. Or at lest it was common once upon a time.
Don't know if it still is.

[https://en.wikipedia.org/wiki/Inetd](https://en.wikipedia.org/wiki/Inetd)

------
bitoneill
UTF-8 handling is a big reason I prefer a language like Python 3 or Go over
C++ for the web.

------
kelvin0
Building parts of a web site backend in C++, maybe. Anything else with the
current state of technology seems futile for a production environment.

------
CapacitorSet
tl;dr: CGI.

------
mproud
You can build a website with any language… I mean, sometimes it’s nice to go
back to the basics, but aren’t there better packages and frameworks written in
C++ to handle the job?

------
zebra_cross21
Just use rust man :| why do you want to bring all your security
vulnerabilities and undefined behaviors to web?

~~~
calebtroyer
Why do people think the C++ of today is the same as the C++ of 1998? Today we
have concepts such as RAII to clean up our objects when they go out of scope.
We have references which are essentially safe pointers _to an extent_ (see
dangling references). References have always existed, but people _insist_ on
using raw pointers still. Finally, for those use cases where heap allocated
memory is _absolutely necessary_ , we have smart pointers which clean up the
memory they own when the smart pointer object goes out of scope (an
application of RAII). Other unsafe practices carried over from C such as void
* type erasure are being replaced with type-safe objects (see std::any for
C++17, boost::any for pre-C++17).

~~~
Jare
There's still plenty of ways to shoot yourself in the foot if you are "not
careful" with the modern C++ code you write. See for example
[http://foonathan.net/blog/2017/03/22/string_view-
temporary.h...](http://foonathan.net/blog/2017/03/22/string_view-
temporary.html)

Modern C++ has a lot of great stuff to help, but the sense of safety you get
when you use Rust is something else entirely.

------
giancarlostoro
Its always interesting to see C++ but as someone else mentioned I expected to
see Wt. If I want nearest to C++ speeds I rather go with D (using vibe.d) or
Rust. C++ isn't my area of expertise though but those two other languages are
years more approachable for me personally. Not saying I could never do C++
though. I know OkCupid is C++ using Wt iirc. I wish they'd give D a try or
Rust to see how much more productive they become.

~~~
bcjpjk
Why would you assume that D or Rust would be make developers more productive?
If the developer already knows C++, then switching to D or Rust would make the
developer significantly less productive over six months to a year, after
which, the developer would likely be just as productive as he/she was when
writing C++.

Languages are not panaceas. Rust and D are both hard languages, as is C++.
Selecting one of these only makes sense if the application warrants it. Each
have advantages and disadvantages. I don't really think any of them are suited
to web development, but claiming that D or Rust would be a more productive web
development language than C++ seems equally silly to seriously considering C++
as a web development language.

~~~
jordigh
> Why would you assume that D or Rust would be make developers more
> productive? If the developer already knows C++, then switching to D

Because D is very obviously C++ but better. Rust isn't, though. But D, down to
the very name, has lots of things that appeal to C++ users. It has advanced
metaprogramming, is multiparadigm, it compiles down to machine code, and has
very similar syntax to C++.

D has had other influences, but it is written by C++ compiler writers who
think they can do better than C++. I say this as someone raised on C++ and who
is now trying D. It is a very natural progression to make, if you're inclined
to try something new.

Furthermore, Vibe.d is kind of a burgeoning "killer app" for D. D's package
manager, for example, was originally made for Vibe.d. This isn't the only way
in which Vibe.d has influenced D development. Vibe.d is one of the most
popular D libraries. It's the only D library I know that has its own published
book,

[https://dlang.org/blog/2017/09/13/the-making-of-d-web-
develo...](https://dlang.org/blog/2017/09/13/the-making-of-d-web-development/)

