Article View: borland.public.cppbuilder.internet.web
Article #1543Re: TWebRequest: How do I upload files?
From: 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
Technical Details
Message-ID:
<413dc750$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<4137865a$1@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: feeec,13e82ec923f5058e X-Google-Attributes: gidfeeec,public X-Google-Language: ENGLISH,ASCII-7-bit From: "TerryC" <terryc@sweetwaterhsa.com> Sender: "TerryC" <terryc@sweetwaterhsa.com> Reply-To: "TerryC" <terryc@sweetwaterhsa.com> Subject: Re: TWebRequest: How do I upload files? Newsgroups: borland.public.cppbuilder.internet.web X-User-Info: 63.250.179.198 References: <4137865a$1@newsgroups.borland.com> NNTP-Posting-Host: 207.105.83.66 Message-ID: <413dc750$1@newsgroups.borland.com> Date: 7 Sep 2004 07:36:00 -0700 X-Trace: newsgroups.borland.com 1094567760 207.105.83.66 (7 Sep 2004 07:36:00 -0700) Lines: 154 Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail