FastCGI, SCGI, - php

I'm writing a web server in C, and I need to figure out a way to use CGI to execute dynamic content server-side.
I'm looking at the FastCGI protocol and it looks annoying. It reminds me of the bit twiddling I had to do in a class when I was converting ASCII to UTF-8 and back (that seemed useless then, but maybe it wasn't...)
I found a great library written in PHP where I could just start up php-cgi -b localhost:8888 and start communicating with it. Obviously, I'd like that in C.
I'd appreciate it if someone could find a library (for FastCGI clients!). If not, then I'm fine with contributing to the open source community by writing one.
Also, how exactly do I use SCGI? There's barely any documentation on it (that I can find, anyway). What socket do I connect to? Where do I send the requests?
Also, php-cgi is only for PHP, so how do things work for Perl, Python, etc?
Thanks again.

mario said (in the question comments):
There are a few libraries mentioned on the FastCGI homepage. http://fastcgi.com/drupal/node/5. The development kit should include the server.
The client implementation is included there for, too. http://fastcgi.com/devkit/doc/fcgi-devel-kit.htm
SCGI http://python.ca/scgi/protocol.txt is extremely simple to implement even without reference code.
You need an SCGI client that runs as deamon, and that accepts socket connections on an agreed port (4000 or 5000 seem common).
SCGI is no different than FastCGI. Each language would require its own daemon, you can run multiple. And accepting CGI requests is pretty much what they do. The only difference is the socket and the header format instead of a CGI stdin pipe and env variables.
To this I'd like to add: CGI (which is exactly what the question asks for) is different from FCGI and SCGI in their working models. It's quite easy to mistake one for others. Luckily, it seems like Preetam asked for FCGI and SCGI.

Related

How does the PHP interpreter interact with Apache?

We've been thinking on writing a php interpreter for a project we've been working on. Interpreting aside, I've been trying - with no success - to find how the PHP interpreter interfaces with the http server. So I've come to you, o' dear knowledgeable people of Stack Overflow.
I have read that php listens on localhost:9000. Goes without saying that I tried to connect to that and it was no use. Maybe the webserver runs "php file.php" and gets the output?
Also, could a php interpreter that interprets .php files and our interpreter (lets call it pqp for the sake of argument) that interprets .pqp files coexist in a single webserver?
Thank you very much!
There are certain ways in which PHP interacts with a webserver. One is indeed to pipe PHP files into the PHP cli and serve the output as in this question. As I wrote there: It's really not recommended.
The next best thing is to expand the sapi of PHP, which is providing a set of connectors to a webserver. In this case, PHP is going to act like a webserver module (see apache+mod_php). A downside of this is that PHP is trying to parse everything it gets its hands on.
A webserver-independent method is to connect to PHP via the Common Gateway Interface, whcih is a well-defined interface for various interactive serverside components. It is, however, terribly slow (and a bit insecure).
The final step is to implement FastCGI. This is an improvement over CGI in that it tries to connect to a running process. In the PHP world, this is achieved through php-fpm which (by default) indeed listens on 9000/tcp.

Why does PHP just work with Ajax but Python doesn't?

Building a PHP script that responds to an Ajax request is as easy as:
<?php
$command = $_POST["command"];
if ($command == "say_hello") {
$name = $_POST["name"];
echo json_encode(array("message" => "Hello, " . $name));
}
?>
and, at least if you're using jQuery on the client side, and if you specified a callback function on the original request, the array containing the message will be passed into that callback function.
But with Python it's not that simple. Or at least I haven't figured out how to make it that simple. If I just try to "print" a response (paralleling PHP's "echo" statement above) the client doesn't get anything back.
Whenever I've looked on the internet for how to respond to an Ajax request with Python, the answer always involves using Django or some other web framework.
And I know those things are great, but what is PHP doing that makes using a similar package unnecessary? I would like to be writing my server-side script in Python instead of PHP, but I'd prefer a D.I.Y. approach to using a third-party framework for what should be (right?) a pretty simple task.
Any help? An example of how to do this would be much appreciated.
But with Python it's not that simple. Or at least I haven't figured out how to make it that simple. If I just try to "print" a response (paralleling PHP's "echo" statement above) the client doesn't get anything back.
I might have some of the details wrong, but I'll try to explain why this is the case. Firstly, the PHP you're talking about is baked directly into the apache webserver. When you do an echo, it outputs the result to the response stream (a TCP connection between the server and client). When you do print in python, what you're doing is outputting the result to standard out (the command line).
How most languages work with the web, is that a request comes in to some kind of web server, and that web server executes a program. The program is responsible for returning a stream, which the webserver takes, and streams to the client over the TCP connection.
I'm assuming that the webserver redirects PHPs standard out to the webservers stream, and that is how PHP is able to use echo to return its result. This is the exception, not the rule.
So, to use python to serve requests, you need to have a webserver that can execute python in some way. This is traditionally done using CGI. More recently, something like mod_python was used to host the python within apache. Nowadays, wsgi or mod_wsgi is used, which is the standard defined for webservers talking to python.
You might want to look at something like web.py, which is a minimalist python web framework. This will get you very very close to what you're trying to do.
PHP was built with the web in mind from the very beginning. In contrast Python was designed as a general purpose language.
When you echo from PHP you're actually writing to a stream that is sent to the user as part of an HTTP response. When you do a print in python the output, by default, is written to the stdout stream which means instead of being sent to the user over http the output is written to the console (or whatever is capturing stdout at the moment).
So to PHP, HTTP is a first class citizen. To more general purpose languages like Python, Ruby, Erlang, C, C++, and so many other languages. You have to communicate to HTTP in different ways. PHP already handles that communication through apache's mod_php or through something like PHP-FPM.
Sooo....
As far as creating your own server side script, I'd highly suggest against it as Python's Frameworks take the place of the layer that PHP is built on. So creating a standards compliant http server on your own with Python isn't going to be very simple. The reason that this is so hard is that you'd either have to interface with CGI or WSGI (a Python standard for dealing with the web) or create your own HTTP server. If you think you're up to the task then I highly suggest it! You'd probably learn a whole lot by doing it, but it isn't going to be the easiest thing. The great thing is that so many libraries already take care of this communication for you. For example, if you're looking for something lightweight, I highly suggest a micro-framework like flask which is one I personally use if I need something very simple. It is much easier to get started than django, but it also has less batteries included.
Hope this helps!
There is a python module called json. Perhaps so many of the answers deal with frameworks (like Django) because json is web-centric and Django, tornado, twisted, cherrypy, etc. all are the means by which python interacts with the web.
There are many different ways to do this, and those are addressed in other questions. However, to just answer your question, python has a json library in its standard library.
Most PHP installers configure themselves by default to serve php files in web directories by running the script. Most Python installers do not. Quickest way to serve Python with apache:
In your apache config file, add AddHandler cgi-script .py to whatever block can already serve PHP files
shebang your python scripts by adding #!/usr/local/bin/python or whatever path python is on in your system
remember to print headers first, followed by a newline, then body.
use import cgi if you want to do anything more complicated than sending back a response body.
Note that this is not the recommended way to run a python website, just the fast, php-ish way.
Richardhsu has the gist of it correct.
Essentially python is a general purpose scripting language. As such, it needs a way to connect to the web, such as by opening a port and doing network programming etc. You can also use something CGI to attach to apache or other web server.
This is really no different then how Java, Ruby, Perl or C/C++ get to the web either. In fact, PHP does much the same thing. It's interface to the web server is just tighter then CGI.
If you were to have PHP interpreted from the command line, or compiled, then you would have the exact same issues that you do with Python now. The issue isn't PHP vs Python, it's how you get the scripting language of your choice attached to the internet using the HTTP protocol.

PHP without a server

I have a C# application that needs to call a PHP script, and get the output, in the fastest possible way. The options I explored:
Executing the script with PHP CLI (Pro: Easy / Cons: No Opcode Cache / Precompilation ]
Compiling the PHP (Phalanger, Hiphop, etc.) [Pro: No Webserver / Con: Compatibility ]
Using an embedded webserver (AppWeb, Cherokee, Lighttpd) [Pro: Simple / Cons: Deployment ]
Are there any other options left?
EDIT: The best possible option would be to make use of the build-in FastCGI server of PHP, by running php-cgi.exe -b 127.0.0.1. But there seems no (C#) code to talk to a server available. While there are so many server-side libraries (like FCGIDotNet and SharpCGI), they all implement the server-side of the protocol.
One other option could be to run the PHP CLI script as a daemon (good blog post on this here).
If the script has a particularly long startup/cleanup, then running it as a daemon would mean that you only do this once.
The downside is that you'd need to write a way of communicating with that daemon, to get the data from C# to it. You'd also need to keep an eye out on its memory usage over time.
The best method is always going to be specific to your script though.
As you may know, PHP originally stood for "Personal Home Page", it is now said to stand for "PHP: Hypertext Preprocessor", which literally states it's usage, and basically is not something that a developer would embed into his application just to have a scripting option.
Unless you have some really specific piece of software and strong arguments, I'd suggest you to stick to Lua, or similar scripting libraries which are easy to embed and maintain. Otherwise, use it the way as everyone is using it, CLI. Or else be prepared to face the consequences.

PHP-style web development on Ruby: creating microframework for that

In PHP world you can just create index.php file, put some inline code and raw HTML, run Apache and it just works.
There are a lot af talks about bad practices of using inline code an so on. So we won't discuss this theme here, please.
How can I start my Ruby application same way? I want to use ERB for code messing, so it will look this way
# index.rb
<h1>Hello world!</h1>
<div>
1 + 1 = <%= 1 + 1 %>
</div>
So my questions are:
What makes PHP just work.
AFAIU(nderstand) There is native support for HTTP in PHP, so I have to use Rack to support it with Ruby
Some basic knowledge for creating my on "microframework": working with application/http servers (Mongrel, nginx, binding on http port and all such kind of job), working with HTTP requests: sessions, params, GET/POST etc (Rack?), sending responses (ERB templating).
So I can make my own (in educational puprposes) microframework for PHP-style web development with Ruby :D
UPD
What really I want to do is an application wich will just get request url, run just that file and return HTML as a response. Also this application should be allowed to be binded on some port
index.rb
info/about.rb
info/contacts.rb
products/product.rb
so It should parse url localhost/index.rb and run index.rb, localhost/products/product.rb?product_id=10 and run products/product.rb and pass product_id=10 as a params hash.
UPD 2
I think good point to start is to dig into Camping microframework source:
https://github.com/camping/camping
It is about 5Kb weight so I shouldn't be confused in it
It is possible to write CGI scripts with Ruby but this is generally not done because we have better solutions.
One file per page is not a very useful abstraction, it's just the one that PHP supports. Ruby has better ways to abstract a web application (like Sinatra, Rails, or even just Rack) so we prefer to use them.
Putting the file name in the url is another unfortunate side effect of PHP's design. It is implementation revealing and unnecessary (you're not getting a Ruby page, you're getting an HTML page), so we choose not to do that either.
CGI and FCGI in Ruby are also slower than the other solutions. This is not because of some limit on how performant they can be; it's mostly just because the effort to make Ruby web applications faster has been spent in more useful areas like Rack and Rails. No one really uses CGI so no one really cares to make it fast. mod_ruby makes CGI scripts somewhat faster if you really want to go this route, but again: there are better ways.
Apache can run PHP by loading in the mod_php module.
I believe to run ruby you will need to have it installed on the server and have mod_ruby loaded into apache. take a look at: http://www.modruby.net/en/
You are looking for CGI. The Apache modules like mod_php or mod_ruby are just packaging provided for CGI scripts written in PHP or Ruby.

Is PHP or vanilla Perl CGI faster?

I'm developing a web app for an Apache shared hosting server. I have already written some code in Perl but I recently found out, to my surprise, the shared hosting provider does not provided mod_perl or a way to install it.
I have been a bit worried that running a Perl web app through CGI without mod_perl would make it very slow? Should I switch all of my code to PHP instead, would that be faster?
The reason I chose Perl in the first place is, I'm very familiar with Perl more than PHP. Also I wanted to be able to use my Perl libraries outside the realm of web development.
So if any of you are experienced with Apache web development, can you shed some light as to which direction should I take.
For the sake of this question, lets say the web application will get 500+ hits a day.
Which would be faster PHP or Perl without mod_perl?
Thanks in advance for the help.
At only 500 hits a day, you could write your code in just about anything and not have to worry about slow downs. 500 hits a day evens out to about 1 page every 3 minutes. Even assuming a non-normal distribution of hits, you shouldn't really worry about this with such small traffic numbers.
PHP would be faster.
However, with only 500 hits per day, using cgi would not be a problem. Not even with 500 hits an hour.
Much depends on your architecture. Modern Perl frameworks aren't well suited for use as CGI (long start-up times). If you use CGI, Catalyst probably is a bad idea. That said, using classical architecture it should be quite manageable.
Unless your shared host is running PHP as a CGI application (not mod_php or FastCGI), PHP is almost1 always going to be faster. While Perl, running as a CGI, could probably handle your 500 hits a day, an application/page developed with CGI is going to be sluggish.
CGI works by spawning a new process to run your program for each request. Both mod_php and FastCGI applications mitigate this by spawning a set a number of processes and then using these to run your application. In other words, a new processes isn't being spawned for each request. (This is an oversimplified explanation, please don't use in a CS Term Paper. See mod_php and FastCGI docs for more info)
You could come up with pathological examples where it wouldn't be, but then you'd be the kind of person to come up with pathological examples of things, and no one wants that
Speed shouldn't be your concern. Both languages are suitable for web applications.
For the volume of traffic you're looking at, Perl with vanilla CGI shouldn't be an issue, although I would second the earlier recommendations to check out FastCGI as another option which your hosting service may provide.
Or another option would be to look for a different hosting company...
Expanding on what Alan Storm said, you might be able to use Perl with FCGI instead.
FCGI works by having a sort of stand-alone server, a daemon if you like, that connects with your web server via FCGI protocol and delegates/dispatches requests.
This is faster than normal CGI, as this emulates a sort of "servlet" model, the application is persistent, and there is no need for a new initialization on every call like there is with normal CGI.
I have not yet learned how to do this myself, but I believe Catalyst has this option, so its just a matter of learning how to replicate this.
FastCGI/FCGI should be available on drastically more hosts than plain old mod_perl, as FCGI applications are not web-server specific, and some web servers implement PHP via a fcgi utility.
And I've experimented with FCGI webserving a little, and preliminary tests say it can handle at least 500 req/s , far faster than the above concerns of 500/day or 500/hour.
It's possible to hack fastcgi support into a hosting account that doesn't support it. I compiled the fastcgi library with the install prefix set to the same thing as the home directory on the hosting account. Then I synced it up and set up catalyst to use the small cgi-fcgi bridge. It worked well. Nice and fast, because the cgi bridge is just a tiny little executable. The catalyst process persisted in the background just fine.
The answer in everyones mind is: who cares.
500 requests per day is nothing.
Just use whats fastest to implement / maintain and move on.
For lighter web frameworks that will work using CGI then have a look at....
Squatting
CGI::Application
CGI::Lazy
It depends mostly on how complex your code is and how it's put together; if you run it as CGI, perl will compile your script and modules on each invocation, and will have to reconnect to your database for each request. If your code is complex enough, this may take a few seconds per pageview, which may hamper user experience.
If your codebase and used modules isn't huge though, there should be no problem at all.
You can do a perl -c on your code to get a feel for how long perl startup and your compilation time is.

Categories