digitalmars.D.learn - D CGI Hang with fgets
- Morgan McDermott (55/55) Nov 26 2006 Hi there!
- Carlos Santander (5/71) Nov 27 2006 Have you tried initializing prawData?
- Morgan McDermott (9/78) Nov 27 2006 Carlos,
- Morgan McDermott (95/174) Nov 27 2006 Further research leads me to conclude that the problem is giving fgets a...
- Thomas Kuehne (17/70) Nov 27 2006 -----BEGIN PGP SIGNED MESSAGE-----
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
Nov 26 2006
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 similarprintf("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
Nov 27 2006
Carlos Santander wrote:Morgan McDermott escribió: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 McDermottHi 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 similarprintf("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
Nov 27 2006
Morgan McDermott wrote:Carlos Santander wrote: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 ^_~.Morgan McDermott escribió: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 McDermottHi 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 similarprintf("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
Nov 27 2006
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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 to And send intput to stdin e.g.: Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFFa+H9LK5blCcjpWoRAo0sAKCk1D2u61K+G0r3N5iLc6LAtXzhvQCgjp5q gh0GeTpX+kJmy+w8tJ6LDVU= =LJup -----END PGP SIGNATURE-----
Nov 27 2006