Re: Return application octet-stream data

Noah Silverman <[email protected]> Tue, 18 Sep 2012 14:41:48 -0700
Newsgroups gmane.comp.web.fastcgi.devel
Message-ID <[email protected]>
--===============1012856473349296286==
Content-Type: multipart/alternative; boundary="Apple-Mail=_AEF5F371-9E45-4CCA-8511-B9E72677A952"


--Apple-Mail=_AEF5F371-9E45-4CCA-8511-B9E72677A952
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=windows-1252

Hi,

It looks like I'm still having a bit of trouble.

Thanks to Jay's help, I can reliably return a binary string from the =
fastcgi program back to the webserver(and remote connection).

I've noticed that about 50% of the *incoming* requests aren't getting =
parsed properly.  All incoming requests are sent as post data of an =
octet-stream.   My guess is that the way I'm reading them in isn't happy =
with a null character or something similar. =20

Any ideas on how to fix this one?  I imagine that there is a "best =
practices" way to safely read in the post data from nginx.

Thanks!

Here is the c++ snippet: =20
(Taken from the example script supplied with fastcgi.)

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
static long gstdin(FCGX_Request * request, char ** content){
    char * clenstr =3D FCGX_GetParam("CONTENT_LENGTH", request->envp);
    unsigned long clen =3D STDIN_MAX;
    if (clenstr){
        clen =3D strtol(clenstr, &clenstr, 10);
        if (*clenstr){
            cerr << "can't parse \"CONTENT_LENGTH=3D"
                 << FCGX_GetParam("CONTENT_LENGTH", request->envp)
                 << "\"\n";
            clen =3D STDIN_MAX;
        }

        // *always* put a cap on the amount of data that will be read
        if (clen > STDIN_MAX) clen =3D STDIN_MAX;

        *content =3D new char[clen];

        cin.read(*content, clen);
        clen =3D cin.gcount();
    }
    else{
        // *never* read stdin when CONTENT_LENGTH is missing or =
unparsable
        *content =3D 0;
        clen =3D 0;
    }

    // Chew up any remaining stdin - this shouldn't be necessary
    // but is because mod_fastcgi doesn't handle it correctly.

    // ignore() doesn't set the eof bit in some versions of glibc++
    // so use gcount() instead of eof()...
    do cin.ignore(1024); while (cin.gcount() =3D=3D 1024);
    return clen;
}

int main (void){

    // Backup the stdio streambufs
    streambuf * cin_streambuf  =3D cin.rdbuf();
    streambuf * cout_streambuf =3D cout.rdbuf();
    streambuf * cerr_streambuf =3D cerr.rdbuf();

    FCGX_Request request;

    FCGX_Init();
    FCGX_InitRequest(&request, 0, 0);
=09
	//The main loop for fast cgi
	  while (FCGX_Accept_r(&request) =3D=3D 0){
		char * content;=20
		unsigned long clen =3D gstdin(&request, &content);
		etc=85
		=85.
	}
	return 0;
}
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D



On Sep 18, 2012, at 2:24 PM, Charles Thomas <[email protected]> =
wrote:

> Yeah... it's a real love-hate relationship for me.  I love fixing the =
problems that I Hate getting.
>=20
> The weirdest one I have had with FastCGI was cross-domain transfer =
from a javascript to fastcgi.  With that one there were some weird =
requirements concerning what headers I could and could not have in the =
request/response.=20
>=20
> Speaking of headers and fastCGI, are there any classes that =
encapsulate the header logic into them?  I know about the fastcgi =
library, and one for Qt  (FastCgiQt), but I was wondering if there are =
any more higher level classes out there?
>=20
> Tom
>=20
> Sent from my iPad
>=20
> On Sep 18, 2012, at 3:54 PM, Jay Sprenkle <[email protected]> wrote:
>=20
>> My guess is that was the issue.
>> The other (terminating the string at the first zero byte) might have =
caused similar problems as well.
>> Computers are so fussy ;)
>>=20
>>=20
>> On Tue, Sep 18, 2012 at 3:49 PM, Charles Thomas =
<[email protected]> wrote:
>> i guess it would help if I read the entire mail message :)... so it =
was the missing Content-Length?
>>=20
>>=20


--Apple-Mail=_AEF5F371-9E45-4CCA-8511-B9E72677A952
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=windows-1252

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space; =
"><div>Hi,</div><div><br></div><div>It looks like I'm still having a bit =
of trouble.</div><div><br></div><div>Thanks to Jay's help, I can =
reliably return a binary string from the fastcgi program back to the =
webserver(and remote connection).</div><div><br></div><div>I've noticed =
that about 50% of the *incoming* requests aren't getting parsed =
properly. &nbsp;All incoming requests are sent as post data of an =
octet-stream. &nbsp; My guess is that the way I'm reading them in isn't =
happy with a null character or something similar. =
&nbsp;</div><div><br></div><div>Any ideas on how to fix this one? =
&nbsp;I imagine that there is a "best practices" way to safely read in =
the post data from =
nginx.</div><div><br></div><div>Thanks!</div><div><br></div><div>Here is =
the c++ snippet: &nbsp;</div><div>(Taken from the example script =
supplied with =
fastcgi.)</div><div><br></div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D</div><div><div>static long gstdin(FCGX_Request * =
request, char ** content){</div><div>&nbsp; &nbsp; char * clenstr =3D =
FCGX_GetParam("CONTENT_LENGTH", request-&gt;envp);</div><div>&nbsp; =
&nbsp; unsigned long clen =3D STDIN_MAX;</div><div>&nbsp; &nbsp; if =
(clenstr){</div><div>&nbsp; &nbsp; &nbsp; &nbsp; clen =3D =
strtol(clenstr, &amp;clenstr, 10);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
if (*clenstr){</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cerr =
&lt;&lt; "can't parse \"CONTENT_LENGTH=3D"</div><div>&nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;&lt; =
FCGX_GetParam("CONTENT_LENGTH", request-&gt;envp)</div><div>&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;&lt; =
"\"\n";</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clen =3D =
STDIN_MAX;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
}</div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; // *always* put a =
cap on the amount of data that will be read</div><div>&nbsp; &nbsp; =
&nbsp; &nbsp; if (clen &gt; STDIN_MAX) clen =3D =
STDIN_MAX;</div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; *content =
=3D new char[clen];</div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
cin.read(*content, clen);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; clen =3D =
cin.gcount();</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; =
else{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; // *never* read stdin when =
CONTENT_LENGTH is missing or unparsable</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; *content =3D 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; clen =3D =
0;</div><div>&nbsp; &nbsp; }</div><div><br></div><div>&nbsp; &nbsp; // =
Chew up any remaining stdin - this shouldn't be =
necessary</div><div>&nbsp; &nbsp; // but is because mod_fastcgi doesn't =
handle it correctly.</div><div><br></div><div>&nbsp; &nbsp; // ignore() =
doesn't set the eof bit in some versions of glibc++</div><div>&nbsp; =
&nbsp; // so use gcount() instead of eof()...</div><div>&nbsp; &nbsp; do =
cin.ignore(1024); while (cin.gcount() =3D=3D 1024);</div><div>&nbsp; =
&nbsp; return clen;</div><div>}</div></div><div><br></div><div>int main =
(void){</div><div><br></div><div><div>&nbsp; &nbsp; // Backup the stdio =
streambufs</div><div>&nbsp; &nbsp; streambuf * cin_streambuf &nbsp;=3D =
cin.rdbuf();</div><div>&nbsp; &nbsp; streambuf * cout_streambuf =3D =
cout.rdbuf();</div><div>&nbsp; &nbsp; streambuf * cerr_streambuf =3D =
cerr.rdbuf();</div><div><br></div><div>&nbsp; &nbsp; FCGX_Request =
request;</div><div><br></div><div>&nbsp; &nbsp; =
FCGX_Init();</div><div>&nbsp; &nbsp; FCGX_InitRequest(&amp;request, 0, =
0);</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span></div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>//The main loop for fast =
cgi</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span> &nbsp;while (FCGX_Accept_r(&amp;request) =3D=3D =
0){</div></div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">		</span>char * =
content;&nbsp;</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">		</span>unsigned long clen =3D =
gstdin(&amp;request, &amp;content);</div><div><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">		=
</span>etc=85</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">		</span>=85.</div><div><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>}</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>return =
0;</div><div>}</div><div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D</div><div></div></div><div><br></div><div><br></div><br><div>=
<div>On Sep 18, 2012, at 2:24 PM, Charles Thomas &lt;<a =
href=3D"mailto:[email protected]">[email protected]</a>&gt; =
wrote:</div><br class=3D"Apple-interchange-newline"><blockquote =
type=3D"cite"><div bgcolor=3D"#FFFFFF"><div>Yeah... it's a real =
love-hate relationship for me. &nbsp;I love fixing the problems that I =
Hate getting.</div><div><br></div><div>The weirdest one I have had with =
FastCGI was cross-domain transfer from a javascript to fastcgi. =
&nbsp;With that one there were some weird requirements concerning what =
headers I could and could not have in the =
request/response.&nbsp;</div><div><br></div><div>Speaking of headers and =
fastCGI, are there any classes that encapsulate the header logic into =
them? &nbsp;I know about the fastcgi library, and one for Qt =
&nbsp;(FastCgiQt), but I was wondering if there are any more higher =
level classes out there?</div><div><br></div><div>Tom</div><div><br>Sent =
from my iPad</div><div><br>On Sep 18, 2012, at 3:54 PM, Jay Sprenkle =
&lt;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; =
wrote:<br><br></div><div></div><blockquote type=3D"cite">My guess is =
that was the issue.<div>The other (terminating the string at the first =
zero byte) might have caused similar problems as =
well.</div><div>Computers are so fussy ;)<br><div><br><br><div =
class=3D"gmail_quote">On Tue, Sep 18, 2012 at 3:49 PM, Charles Thomas =
<span dir=3D"ltr">&lt;<a href=3D"mailto:[email protected]" =
target=3D"_blank">[email protected]</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
bgcolor=3D"#FFFFFF"><div>i guess it would help if I read the entire mail =
message :)... so it was the missing Content-Length?</div>
<div><br><br></div></div></blockquote></div>
</div></div>
</blockquote></div></blockquote></div><br></body></html>=

--Apple-Mail=_AEF5F371-9E45-4CCA-8511-B9E72677A952--

--===============1012856473349296286==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
FastCGI-developers mailing list
FastCGI-developers-xGejAJT2w6xVgU18Zptdi0EOCMrvLtNR@public.gmane.org
http://mailman.fastcgi.com/mailman/listinfo/fastcgi-developers

--===============1012856473349296286==--