Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
November 27, 2006 D CGI Hang with fgets | ||||
---|---|---|---|---|
| ||||
Hi there! I'm trying to make a D CGI script, and one of the essential things it should do is to get POST data. My attempt below in D hangs at fgets()... I've made it output to a file so that it may be tested on a webserver (where I've been testing it). When the script has POST data to get, it performs exactly the same as it does in the console (hangs at fgets()). I've been using a guide to C and CGI as my reference here: http://www.cs.tut.fi/~jkorpela/forms/cgic.html <code> //Imports import std.stdio; //writefln() import std.string; //toString() import std.date : getUTCtime; // time + benchmarking import std.conv; //toInt() import std.stream; //testing only alias char[] string; //ease of use void writeNewLine(string line, string filename) { std.file.append(filename, line~"\n"); } extern (C) { char* getPOSTData(uint len = 2048){ char *prawData; printf("hang?"); writeNewLine("Hanging point entered \n", "baz.txt"); prawData = fgets(prawData, len+1, stdin); writeNewLine("Hanging point exited \n", "baz.txt"); printf("Not hanging.. =-)"); return prawData; } } extern (C) char* getenv(char*); void main() { string introduction = "New test at " ~ toString(getUTCtime()); writeNewLine(introduction, "baz.txt"); char *pdataLength= getenv("CONTENT_LENGTH"); string scontentLength = toString(pdataLength); //Ensure no conversion error when no post data is passed if(scontentLength == ""){ scontentLength = "0"; } uint contentLength = toInt(scontentLength); char *ppostData = getPOSTData(); writefln("Post Data: %s", toString(ppostData)); writeNewLine("Post Data: " ~ toString(ppostData), "baz.txt"); } </code> Any ideas? Thank you very much for your time, ~Morgan McDermott |
November 27, 2006 Re: D CGI Hang with fgets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Morgan McDermott | Morgan McDermott escribió: > Hi there! > I'm trying to make a D CGI script, and one of the essential things it should do is to get POST data. My attempt below in D hangs at fgets()... I've made it output to a file so that it may be tested on a webserver (where I've been testing it). When the script has POST data to get, it performs exactly the same as it does in the console (hangs at fgets()). > > I've been using a guide to C and CGI as my reference here: > http://www.cs.tut.fi/~jkorpela/forms/cgic.html > > <code> > //Imports > import std.stdio; //writefln() > import std.string; //toString() > import std.date : getUTCtime; // time + benchmarking > import std.conv; //toInt() > import std.stream; //testing only > alias char[] string; //ease of use > > void writeNewLine(string line, string filename) { > std.file.append(filename, line~"\n"); > } > > extern (C) > { > char* getPOSTData(uint len = 2048){ > char *prawData; > Have you tried initializing prawData? prawData = new char [len]; // or similar > printf("hang?"); > writeNewLine("Hanging point entered \n", "baz.txt"); > > prawData = fgets(prawData, len+1, stdin); > > writeNewLine("Hanging point exited \n", "baz.txt"); > printf("Not hanging.. =-)"); > > return prawData; > } > } > extern (C) char* getenv(char*); > > void main() { > string introduction = "New test at " ~ toString(getUTCtime()); > writeNewLine(introduction, "baz.txt"); > char *pdataLength= getenv("CONTENT_LENGTH"); > string scontentLength = toString(pdataLength); > //Ensure no conversion error when no post data is passed > if(scontentLength == ""){ > scontentLength = "0"; > } > uint contentLength = toInt(scontentLength); > char *ppostData = getPOSTData(); > writefln("Post Data: %s", toString(ppostData)); > writeNewLine("Post Data: " ~ toString(ppostData), "baz.txt"); > } > </code> > > Any ideas? > > Thank you very much for your time, > ~Morgan McDermott -- Carlos Santander Bernal |
November 27, 2006 Re: D CGI Hang with fgets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander | Carlos Santander wrote:
> Morgan McDermott escribió:
>> Hi there!
>> I'm trying to make a D CGI script, and one of the essential things it should do is to get POST data. My attempt below in D hangs at fgets()... I've made it output to a file so that it may be tested on a webserver (where I've been testing it). When the script has POST data to get, it performs exactly the same as it does in the console (hangs at fgets()).
>>
>> I've been using a guide to C and CGI as my reference here:
>> http://www.cs.tut.fi/~jkorpela/forms/cgic.html
>>
>> <code>
>> //Imports
>> import std.stdio; //writefln()
>> import std.string; //toString()
>> import std.date : getUTCtime; // time + benchmarking
>> import std.conv; //toInt()
>> import std.stream; //testing only
>> alias char[] string; //ease of use
>>
>> void writeNewLine(string line, string filename) {
>> std.file.append(filename, line~"\n");
>> }
>>
>> extern (C)
>> {
>> char* getPOSTData(uint len = 2048){
>> char *prawData;
>>
>
> Have you tried initializing prawData?
> prawData = new char [len]; // or similar
>
>> printf("hang?");
>> writeNewLine("Hanging point entered \n", "baz.txt");
>>
>> prawData = fgets(prawData, len+1, stdin);
>>
>> writeNewLine("Hanging point exited \n", "baz.txt");
>> printf("Not hanging.. =-)");
>>
>> return prawData;
>> }
>> }
>> extern (C) char* getenv(char*);
>>
>> void main() {
>> string introduction = "New test at " ~ toString(getUTCtime());
>> writeNewLine(introduction, "baz.txt");
>> char *pdataLength= getenv("CONTENT_LENGTH");
>> string scontentLength = toString(pdataLength);
>> //Ensure no conversion error when no post data is passed
>> if(scontentLength == ""){
>> scontentLength = "0";
>> }
>> uint contentLength = toInt(scontentLength);
>> char *ppostData = getPOSTData();
>> writefln("Post Data: %s", toString(ppostData));
>> writeNewLine("Post Data: " ~ toString(ppostData), "baz.txt");
>> }
>> </code>
>>
>> Any ideas?
>>
>> Thank you very much for your time,
>> ~Morgan McDermott
>
>
Carlos,
Good idea, and thanks for the reply. Unfortunately, the script still hangs at the same point. I've done a bit more work and an essentially equivilant C script also hangs at this point, so I doubt that this is a D-problem. All the same, any help from this great community is very much appreciated :).
Thanks again,
~Morgan McDermott
|
November 28, 2006 Re: D CGI Hang with fgets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Morgan McDermott Attachments: | Morgan McDermott schrieb am 2006-11-27:
> Hi there!
> I'm trying to make a D CGI script, and one of the essential things it
> should do is to get POST data. My attempt below in D hangs at fgets()...
> I've made it output to a file so that it may be tested on a webserver
> (where I've been testing it). When the script has POST data to get, it
> performs exactly the same as it does in the console (hangs at fgets()).
>
> I've been using a guide to C and CGI as my reference here: http://www.cs.tut.fi/~jkorpela/forms/cgic.html
>
><code>
> //Imports
> import std.stdio; //writefln()
> import std.string; //toString()
> import std.date : getUTCtime; // time + benchmarking
> import std.conv; //toInt()
> import std.stream; //testing only
>
> alias char[] string; //ease of use
>
> void writeNewLine(string line, string filename) {
> std.file.append(filename, line~"\n");
> }
>
> extern (C)
> {
> char* getPOSTData(uint len = 2048){
> char *prawData;
>
> printf("hang?");
> writeNewLine("Hanging point entered \n", "baz.txt");
>
> prawData = fgets(prawData, len+1, stdin);
>
> writeNewLine("Hanging point exited \n", "baz.txt");
> printf("Not hanging.. =-)");
>
> return prawData;
> }
> }
>
> extern (C) char* getenv(char*);
>
> void main() {
> string introduction = "New test at " ~ toString(getUTCtime());
> writeNewLine(introduction, "baz.txt");
>
> char *pdataLength= getenv("CONTENT_LENGTH");
> string scontentLength = toString(pdataLength);
> //Ensure no conversion error when no post data is passed
> if(scontentLength == ""){
> scontentLength = "0";
> }
>
> uint contentLength = toInt(scontentLength);
>
> char *ppostData = getPOSTData();
> writefln("Post Data: %s", toString(ppostData));
> writeNewLine("Post Data: " ~ toString(ppostData), "baz.txt");
> }
></code>
>
> Any ideas?
Change
# char *prawData;
to
# char *prawData = (new char[len]).ptr;
And send intput to stdin e.g.:
#
# programm < some_file
#
Thomas
|
November 28, 2006 Re: D CGI Hang with fgets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Morgan McDermott | Morgan McDermott wrote: > Carlos Santander wrote: >> Morgan McDermott escribió: >>> Hi there! >>> I'm trying to make a D CGI script, and one of the essential things it should do is to get POST data. My attempt below in D hangs at fgets()... I've made it output to a file so that it may be tested on a webserver (where I've been testing it). When the script has POST data to get, it performs exactly the same as it does in the console (hangs at fgets()). >>> >>> I've been using a guide to C and CGI as my reference here: >>> http://www.cs.tut.fi/~jkorpela/forms/cgic.html >>> >>> <code> >>> //Imports >>> import std.stdio; //writefln() >>> import std.string; //toString() >>> import std.date : getUTCtime; // time + benchmarking >>> import std.conv; //toInt() >>> import std.stream; //testing only >>> alias char[] string; //ease of use >>> >>> void writeNewLine(string line, string filename) { >>> std.file.append(filename, line~"\n"); >>> } >>> >>> extern (C) >>> { >>> char* getPOSTData(uint len = 2048){ >>> char *prawData; >>> >> >> Have you tried initializing prawData? >> prawData = new char [len]; // or similar >> >>> printf("hang?"); >>> writeNewLine("Hanging point entered \n", "baz.txt"); >>> >>> prawData = fgets(prawData, len+1, stdin); >>> >>> writeNewLine("Hanging point exited \n", "baz.txt"); >>> printf("Not hanging.. =-)"); >>> >>> return prawData; >>> } >>> } >>> extern (C) char* getenv(char*); >>> >>> void main() { >>> string introduction = "New test at " ~ toString(getUTCtime()); >>> writeNewLine(introduction, "baz.txt"); >>> char *pdataLength= getenv("CONTENT_LENGTH"); >>> string scontentLength = toString(pdataLength); >>> //Ensure no conversion error when no post data is passed >>> if(scontentLength == ""){ >>> scontentLength = "0"; >>> } >>> uint contentLength = toInt(scontentLength); >>> char *ppostData = getPOSTData(); >>> writefln("Post Data: %s", toString(ppostData)); >>> writeNewLine("Post Data: " ~ toString(ppostData), "baz.txt"); >>> } >>> </code> >>> >>> Any ideas? >>> >>> Thank you very much for your time, >>> ~Morgan McDermott >> >> > Carlos, > Good idea, and thanks for the reply. Unfortunately, the script still hangs at the same point. I've done a bit more work and an essentially equivilant C script also hangs at this point, so I doubt that this is a D-problem. All the same, any help from this great community is very much appreciated :). > > Thanks again, > ~Morgan McDermott Further research leads me to conclude that the problem is giving fgets a pointer instead of a char array. When I replace prawData with something like rawData[1000], everything works as planned. <code> char rawData[1000]; fgets(rawData, len+1, stdin); </code> Although this works, I would really rather put the data from stdin into something of variable size. I got my C-code to work with this modification, so I ported it over to D and allowed it to take as much data as you want it to by looping through the stdin data. I haven't optimized buffer size for anything in particular... If you plan on using this function, then you probably want to play around with that. To use this in a CGI environment, you're going to need to: 1) split apart the data into key value pairs 2) decode the data with an unencode function ( Cashew has one ) <code> //Imports import std.stdio; //writefln import std.string; import std.c.stdlib; //Environmental Vars import std.c.stdio; //fgets import std.c.string; alias char[] string; extern (C) char* getenv(char*); char[] d_getPOSTData(uint maxlen = 2048){ //Buffer info char dataBuffer[512]; ulong bufferSize = dataBuffer.length; //Define some pointers char *lenstr; char *pblank; char[] error; //Variable to hold lenstr in int form long len; lenstr = getenv("CONTENT_LENGTH"); //Test for null length if(lenstr == pblank){ //throw error error = "No POST data"; return error; } else { //copy lenstr into len with format width=long, type = decimal integer sscanf(lenstr,"%ld",&len); } if( len > maxlen ){ error = "POST data has exceeded size limits"; return error; } else { char *ptmpData; char[] tempString; char[] dataStorage; //While stream pointer is at a valid location, [stdin has more data to give us] while(fgets(dataBuffer, bufferSize, stdin)){ //Set pointer to buffer ptmpData = dataBuffer; //Get the contents of the buffer into tempString tempString = toString(ptmpData); //Append tempString to dataStorage dataStorage ~= tempString; } if(dataStorage.length >= len){ dataStorage.length = len - 1; } return dataStorage; } } void main(){ //Output HTTP headers -- Necessary when testing on Apache string ctype = "Content-Type:text/html;charset="; string encoding = "iso-8859-1"; string char1 = "\x0D"; string char2 = "\x0A"; writef("%s%s%s%s\n", ctype, encoding,char1,char2); char[] postData = d_getPOSTData(); writefln("Post Data: %s", postData); } </code> **Problem solved** Thank you for your help, D Community ^_~. |
Copyright © 1999-2021 by the D Language Foundation