2

I'm trying to file upload and download in fastcgi.

To use sendfile() I need the web server's open socket to the client (browser).

fastcgi doesn't pass it to me (I don't think).

I'm clueless on how to get the browser's socket descriptor.

I'm also open to another approach without a redirect or opening a new connection.

help is appreciated

C2H5OH
  • 5,452
  • 2
  • 27
  • 39
garyM
  • 802
  • 2
  • 12
  • 29

2 Answers2

2

You don't get a socket to the browser in FastCGI. The only socket you get directly is connected to the web server, and it's expecting FastCGI data frames, not just raw data.

The most typical solution for file downloads is the X-Sendfile header, which directs the web server to spit out a file (probably using something like sendfile() internally) instead of your response. It was introduced by Lighttpd, is supported natively by nginx, and is supported by Apache via mod_xsendfile.

  • Thanks.. Your comment was where I was when I posted the question.. I cannot use the std. web server's mods for sendfile, clients have a different namespaces than the file system. I have a few options, more complex than I want to engage. maybe someone has a different approach – garyM May 25 '12 at 01:47
  • 1
    If you can't use x-sendfile, you're pretty much stuck reading in the file piece by piece and sending it over fastcgi. There's really no other shortcuts. –  May 25 '12 at 03:04
1

Remember that a socket and a file is mostly handled the same, so you can use the standard output file descriptor as output "socket" instead of a real socket:

#include <unistd.h>

int in_fd = open(...);

sendfile(STDOUT_FILENO, in_fd, NULL, length_of_file);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you.. Yes, the problem is I need access to the open socket descriptor which is running in the apache process. If I open a "new" socket, I need to tell the client to connect via a redirect to a new socket. The problem is the overhead of the new open. The std io descriptors in fastcgi are emulated in user space and tunneled though their interface. That defeats the purpose of using sendfile() which should send to the open connection between the client and the server without hitting user space. – garyM May 26 '12 at 03:30
  • Also note that there are a few surprising non-equivalencies where `sendfile()` is concerned. On many OSes, it can only copy data from a file to a stream socket -- not other types of fds. –  May 26 '12 at 03:39