custom handler module - dynamic response with unknown content length
Yasser Zamani
yasser.zamani at live.com
Sat Mar 1 17:26:40 UTC 2014
On Sat 01 Mar 2014 06:27:38 PM IRST, Yasser Zamani wrote:
>
>
> The transcoding process already is doing by an external process,
> ffmpeg, into an incomplete file. I just need to read from first of
> this incomplete file one by one chunks and send them to client until
> seeing a real EOF. I have following plan for nginx configuration:
> location \*.mp4 { mymodule; }
>
> So, did you mean if two clients get x.mp4 and y.mp4 in same time then
> one of them is blocked until another one get complete file?! I don't
> think so while web servers usually make new threads.
>
> I saw './nginx-1.4.5/src/http/ngx_http_upstream.c' but was so complex
> for me to understand.
>
> However, I saw FastCGI is simple for me to understand. So, do you
> advise me to `regularly read ffmpeg output file` in a FastCGI script
> and then fasctcgi_pass the nginx to that?
Thank you very much Maxim; Good news that as you advised, I finally
have done it in a nice way via FastCGI:
1. I wrote my code in a FastCGI structure with a lot of thanks to [4].
[4] http://chriswu.me/blog/writing-hello-world-in-fcgi-with-c-plus-plus/
2. I compiled and fcgi-spawn my executable on 127.0.0.1:8000 (see [4])
3. I configured nginx to proxy requests to 127.0.0.1:8000 (see [4])
4. I started my friend, nginx, and pointed the browser to
localhost:8080.
RESULTS:
1. Multiple sametime clients download same file in a very good balanced
speed.
2. There is no error in nginx error log.
3. OK, the best one result...we escaped from write_event_handler and
NGX_AGAIN(=-2) :)
THE FASTCGI CODE: (for future researchers ;) )
#include <iostream>
#include "fcgio.h"
using namespace std;
int main(void) {
// Backup the stdio streambufs
streambuf * cin_streambuf = cin.rdbuf();
streambuf * cout_streambuf = cout.rdbuf();
streambuf * cerr_streambuf = cerr.rdbuf();
FCGX_Request request;
FCGX_Init();
FCGX_InitRequest(&request, 0, 0);
while (FCGX_Accept_r(&request) == 0) {
fcgi_streambuf cin_fcgi_streambuf(request.in);
fcgi_streambuf cout_fcgi_streambuf(request.out);
fcgi_streambuf cerr_fcgi_streambuf(request.err);
cin.rdbuf(&cin_fcgi_streambuf);
cout.rdbuf(&cout_fcgi_streambuf);
cerr.rdbuf(&cerr_fcgi_streambuf);
cout << "Content-type: application/octet-stream\r\n";
int i;
for(i=0;i<1000000;i++) cout
<< "\r\n"
<< "<html>\n"
<< " <head>\n"
<< " <title>Hello, World!</title>\n"
<< " </head>\n"
<< " <body>\n"
<< " <h1>Hello, World!</h1>\n"
<< " </body>\n"
<< "</html>\n";
// Note: the fcgi_streambuf destructor will auto flush
}
// restore stdio streambufs
cin.rdbuf(cin_streambuf);
cout.rdbuf(cout_streambuf);
cerr.rdbuf(cerr_streambuf);
return 0;
}
More information about the nginx
mailing list