Thread View: borland.public.cppbuilder.internet.web
3 messages
3 total messages
Started by TerryC
Thu, 02 Sep 2004 20:45
TWebRequest: How do I upload files?
Author: TerryC
Date: Thu, 02 Sep 2004 20:45
Date: Thu, 02 Sep 2004 20:45
33 lines
1853 bytes
1853 bytes
I have a functioning ISAPI application to which I want to add
file upload capability. The Borland help files don't give much
useful information about how this might be accomplished. I
found the Files property of the TWebRequest object and thought I
had hit pay dirt, but it doesn't seem to work, AFAICT.
I tried the ReadClient() method with this code:
void __fastcall TWMod::WModaiPostUploadAction(TObject *Sender,
TWebRequest *Request, TWebResponse *Response, bool &Handled)
{
int ByteCount;
char *Buffer = new char[Request->ContentLength];
ByteCount =
Request->ReadClient(Buffer, Request->ContentLength);
Response->Content =
"Request->ContentLength = " +
IntToStr(Request->ContentLength) + ". " +
IntToStr(ByteCount) + " bytes transferred.";
delete [] Buffer;
Handled = true;
}
...and I always get -1 bytes transferred.
Does someone have experience and/or some direction to send me
for more help on this? I'm not finding much on Google either...
Many thanks for your time.
Terry
Re: TWebRequest: How do I upload files?
Author: TerryC
Date: Tue, 07 Sep 2004 14:36
Date: Tue, 07 Sep 2004 14:36
153 lines
5851 bytes
5851 bytes
For the benefit of others who may travel this rocky road after
me, here are the two working functions I finally ended up
with.
Feel free to use and/or modify this code for your own app:
void __fastcall TWMod::WModaiPostUploadAction(TObject *Sender,
TWebRequest *Request, TWebResponse *Response, bool &Handled)
{
String Content;
String TempName;
TStringList *Fields = new TStringList;
// Less than ~48K will fit in Request->Content
Content = Request->Content;
// ...so, if there is more, we have work to do
if(Request->Content.Length() < Request->ContentLength){
try{
int ByteCount;
int BytesRead = Request->Content.Length();
int BytesToRead = Request->ContentLength - BytesRead;
// Make room for all of it
Content.SetLength(Request->ContentLength);
char *DataEnd = Content.c_str() + BytesRead;
while(BytesToRead > 0){
ByteCount = Request->ReadClient(DataEnd, BytesToRead);
DataEnd += ByteCount;
BytesRead += ByteCount;
BytesToRead = Request->ContentLength - BytesRead;
}
}
catch(Exception &E){
Response->StatusCode = 500;
Response->Content =
"Server exception in OFI ISAPI application.<BR><BR>"
"Message:" + E.Message;
delete Fields;
Handled = true;
return;
}
}
ParseFields(Content, &TempName, Fields); // See below
if(!TempName.Pos("*Exception")){
int Idx = 1;
// Here I use QueryValues passed in my app to create the
// final file name. The ".tmp" file created in ParseFields()
// is moved here. Substitute with your own situation.
String FileName(UploadPath + "\\" +
Fields->Values["IssueNum"] +
Fields->Values["Type"]);
while(FileExists(FileName + IntToStr(Idx) +
ExtractFileExt(Fields->Values["FileName"])))
++Idx;
FileName = FileName + IntToStr(Idx) +
ExtractFileExt(Fields->Values["FileName"]);
if(CopyFile(TempName.c_str(), FileName.c_str(), false)){
Response->Content = "File data saved to, \"" +
FileName + "\".<BR><BR>Fields: " +
Fields->Text;
DeleteFile(TempName.c_str());
}
else
Response->Content =
"No file data saved.<BR><BR>Fields: " +
Fields->Text;
}
else
Response->Content = "Unable to save to file, \"" +
TempName + "\"!";
delete Fields;
Handled = true;
}
void __fastcall TWMod::ParseFields(const AnsiString &Str,
AnsiString *TempFile, TStrings *Fields)
{
// This method probably oversimplifies parsing the fields,
// but it was sufficient for my application.
String Content(Str);
const String EOL("\r\n");
const String NameTag("Content-Disposition: form-data; name=\"");
const String FileNameTag("filename=\"");
const String ContentTypeTag("Content-Type: ");
const String TagEnd1("\"\r\n");
const String TagEnd2("\";");
String Separator;
int Idx, Len;
String Tag;
String Val;
Fields->Clear();
Len = Content.Pos(EOL) + 1;
Separator = Content.SubString(1, Len);
do {
Idx = Content.Pos(Separator) + Separator.Length();
Len = Content.Length() - Separator.Length();
Content = Content.SubString(Idx, Len);
if(Content.Pos(FileNameTag) && Content.Pos(FileNameTag) <
Content.Pos(EOL)){ // File field
int TmpFile;
Idx = Content.Pos(NameTag) + NameTag.Length();
Len = Content.Pos(TagEnd2) - Idx;
Tag = Content.SubString(Idx, Len);
Idx = Content.Pos(FileNameTag) + FileNameTag.Length();
Len = Content.SubString(Idx, Content.Length() -
Idx + 1).Pos(TagEnd1) - 1;
Val = Content.SubString(Idx, Len);
Idx = Content.Pos(EOL + EOL) + 3;
Len = (Content.Pos(Separator) - 3) - Idx;
*TempFile = String(getenv("temp")) + "\\" + "~DLD" +
IntToStr(RandomRange(1000, 9999)) + ".tmp";
TmpFile = FileCreate(*TempFile);
if(TmpFile > -1){
FileWrite(TmpFile, Content.c_str() + Idx, Len);
FileClose(TmpFile);
}
else
*TempFile = "*Exception: " + *TempFile;
}
else{ // Normal fields
Idx = Content.Pos(NameTag) + NameTag.Length();
Len = Content.Pos(TagEnd1) - Idx;
Tag = Content.SubString(Idx, Len);
Idx = Content.Pos(EOL + EOL) + 4;
Len = Content.SubString(Idx, Content.Length() -
Idx + 1).Pos(EOL) - 1;
Val = Content.SubString(Idx, Len);
}
Fields->Add(Tag + "=" + Val);
} while(Content.Pos(Separator));
}
Hope this helps somebody. It took some work and the sole
example (in Delphi) I could find on the Web to figure it out.
-Terry
Re: TWebRequest: How do I upload files?
Author: Clever Components Team
Date: Wed, 08 Sep 2004 05:33
Date: Wed, 08 Sep 2004 05:33
163 lines
6599 bytes
6599 bytes
Hello Terry,
There's so much simpler way to post/upload files - check this article for
example http://clevercomponents.com/articles/article014/websubmitwizard.asp
With best regards,
Clever Components Team
http://www.clevercomponents.com
"TerryC" <terryc@sweetwaterhsa.com> wrote in message
news:413dc750$1@newsgroups.borland.com...
>
> For the benefit of others who may travel this rocky road after
> me, here are the two working functions I finally ended up
> with.
>
> Feel free to use and/or modify this code for your own app:
>
> void __fastcall TWMod::WModaiPostUploadAction(TObject *Sender,
> TWebRequest *Request, TWebResponse *Response, bool &Handled)
> {
> String Content;
> String TempName;
> TStringList *Fields = new TStringList;
>
> // Less than ~48K will fit in Request->Content
> Content = Request->Content;
>
> // ...so, if there is more, we have work to do
> if(Request->Content.Length() < Request->ContentLength){
> try{
> int ByteCount;
> int BytesRead = Request->Content.Length();
> int BytesToRead = Request->ContentLength - BytesRead;
> // Make room for all of it
> Content.SetLength(Request->ContentLength);
> char *DataEnd = Content.c_str() + BytesRead;
> while(BytesToRead > 0){
> ByteCount = Request->ReadClient(DataEnd, BytesToRead);
> DataEnd += ByteCount;
> BytesRead += ByteCount;
> BytesToRead = Request->ContentLength - BytesRead;
> }
> }
> catch(Exception &E){
> Response->StatusCode = 500;
> Response->Content =
> "Server exception in OFI ISAPI application.<BR><BR>"
> "Message:" + E.Message;
>
> delete Fields;
> Handled = true;
> return;
> }
> }
>
> ParseFields(Content, &TempName, Fields); // See below
>
> if(!TempName.Pos("*Exception")){
> int Idx = 1;
>
> // Here I use QueryValues passed in my app to create the
> // final file name. The ".tmp" file created in ParseFields()
> // is moved here. Substitute with your own situation.
>
> String FileName(UploadPath + "\\" +
> Fields->Values["IssueNum"] +
> Fields->Values["Type"]);
> while(FileExists(FileName + IntToStr(Idx) +
> ExtractFileExt(Fields->Values["FileName"])))
> ++Idx;
> FileName = FileName + IntToStr(Idx) +
> ExtractFileExt(Fields->Values["FileName"]);
> if(CopyFile(TempName.c_str(), FileName.c_str(), false)){
> Response->Content = "File data saved to, \"" +
> FileName + "\".<BR><BR>Fields: " +
> Fields->Text;
> DeleteFile(TempName.c_str());
> }
> else
> Response->Content =
> "No file data saved.<BR><BR>Fields: " +
> Fields->Text;
> }
> else
> Response->Content = "Unable to save to file, \"" +
> TempName + "\"!";
>
> delete Fields;
> Handled = true;
> }
>
> void __fastcall TWMod::ParseFields(const AnsiString &Str,
> AnsiString *TempFile, TStrings *Fields)
> {
> // This method probably oversimplifies parsing the fields,
> // but it was sufficient for my application.
>
> String Content(Str);
> const String EOL("\r\n");
> const String NameTag("Content-Disposition: form-data; name=\"");
> const String FileNameTag("filename=\"");
> const String ContentTypeTag("Content-Type: ");
> const String TagEnd1("\"\r\n");
> const String TagEnd2("\";");
> String Separator;
> int Idx, Len;
> String Tag;
> String Val;
>
> Fields->Clear();
>
> Len = Content.Pos(EOL) + 1;
> Separator = Content.SubString(1, Len);
>
> do {
> Idx = Content.Pos(Separator) + Separator.Length();
> Len = Content.Length() - Separator.Length();
> Content = Content.SubString(Idx, Len);
>
> if(Content.Pos(FileNameTag) && Content.Pos(FileNameTag) <
> Content.Pos(EOL)){ // File field
> int TmpFile;
>
> Idx = Content.Pos(NameTag) + NameTag.Length();
> Len = Content.Pos(TagEnd2) - Idx;
> Tag = Content.SubString(Idx, Len);
>
> Idx = Content.Pos(FileNameTag) + FileNameTag.Length();
> Len = Content.SubString(Idx, Content.Length() -
> Idx + 1).Pos(TagEnd1) - 1;
> Val = Content.SubString(Idx, Len);
>
> Idx = Content.Pos(EOL + EOL) + 3;
> Len = (Content.Pos(Separator) - 3) - Idx;
> *TempFile = String(getenv("temp")) + "\\" + "~DLD" +
> IntToStr(RandomRange(1000, 9999)) + ".tmp";
> TmpFile = FileCreate(*TempFile);
> if(TmpFile > -1){
> FileWrite(TmpFile, Content.c_str() + Idx, Len);
> FileClose(TmpFile);
> }
> else
> *TempFile = "*Exception: " + *TempFile;
> }
> else{ // Normal fields
> Idx = Content.Pos(NameTag) + NameTag.Length();
> Len = Content.Pos(TagEnd1) - Idx;
> Tag = Content.SubString(Idx, Len);
>
> Idx = Content.Pos(EOL + EOL) + 4;
> Len = Content.SubString(Idx, Content.Length() -
> Idx + 1).Pos(EOL) - 1;
> Val = Content.SubString(Idx, Len);
> }
> Fields->Add(Tag + "=" + Val);
>
> } while(Content.Pos(Separator));
> }
>
> Hope this helps somebody. It took some work and the sole
> example (in Delphi) I could find on the Web to figure it out.
>
> -Terry
>
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads