Текущий архив: 2007.10.07;
Скачать: CL | DM;
Вниз
Upload и IdHTTPServer Найти похожие ветки
← →
sairus (2007-02-07 21:55) [0]вопрос собственно не совсем к делфи относится, а к С++ Builder. Но они ведь почти родсвенники...
Так значит так... Мне бы надо организовать возможность загрузки файлов на удаленную машину, но клиент это должен дклать через веб-браузер... Нашел один я код на делфи, думаю он рабочий, но вот при пересройку его на Builder возникли проблемы...procedure TForm1.ServerCommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
Var PostedFile:TMemoryStream;
begin
If ARequestInfo.Document="/" Then begin
With AResponseInfo do begin
ContentText:=HtmlForm;
WriteContent;
end;
end else if ARequestInfo.Document="/upload/" then begin
PostedFile:=TMemoryStream.Create;
Try
Try
PostedFile.LoadFromStream(ARequestInfo.PostStream);
PostedFile.SaveToFile(".\"+(DateToStr(now)+" "+TimeToStr(now)+" "+AThread.Connection.Socket.Binding.PeerIP));
With AResponseInfo do begin
ContentText:=HtmlForm("Upload Successful!");
WriteContent;
end;
except
With AResponseInfo do begin
ContentText:=HTMLForm("Upload Error!");
WriteContent;
end;
end;
finally
PostedFile.Free;
end;
end;
end;
Проблема в том, что в компоненте IdHTTPServer Builder"а нету метода ARequestInfo.PostStream.
Вопрос: как то еще можно было бы переделать этот вот код, ну чтобы ARequestInfo.PostStream не использовался....
Я вот долго мучился с AThread.Connection.ReadStream(...)
Этим воспользоваться можно???- у меня ничего не выходит...
Подскажите пожалуйста, ответ на вопрос долго ищу, пока результат нулевой...
Спасибо.
← →
SlymRO (2007-02-08 07:18) [1]1. Для передачи файлов (особенно "через веб-браузер") должен использоваться <FORM method=post enctype="multipart/form-data"
2. Стандартных средств для обработки multipart в IdHTTPServer нет
Варианты:
1. Придумывать обработку multipart самому
2. Попросить у меня... но у меня на Delphi :)
← →
sairus (2007-02-08 16:21) [2]Если не затруднит, то пожалуйста... очень буду благодарен... С Делфи думаю не будет проблем-переведу...
proxymus@ukr.net
Спасибо.
← →
SlymRO (2007-02-09 09:32) [3]Модуль... не пинайте за баги... as is
unit MultipartFormData;
interface
uses
Classes, IdGlobal, IdException, IdResourceStringsProtocols, IdStreamVCL, SysUtils, IdTStrings,IdCustomHTTPServer;
const
sContentTypeFormData = "multipart/form-data; boundary="; {do not localize}
sContentTypeOctetStream = "application/octet-stream"; {do not localize}
crlf = #13#10;
sContentDisposition = "Content-Disposition: form-data; name="%s""; {do not localize}
sFileNamePlaceHolder = "; filename="%s""; {do not localize}
sContentTypePlaceHolder = "Content-Type: %s"; {do not localize}
sContentTransferEncoding = "Content-Transfer-Encoding: binary"; {do not localize}
type
TFormDataField = class(TCollectionItem)
private
FFileName: string;
FContentType: string;
FFieldName: string;
FData: TStringStream;
//FHeaders:TStrings;
procedure SetContentType(const Value: string);
function GetFieldValue: string;
procedure SetFieldValue(const Value: string);
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
//property Headers:TStrings read FHeaders;
property ContentType: string read FContentType write SetContentType;
property FieldName: string read FFieldName write FFieldName;
property FileName: string read FFileName write FFileName;
property Data: TStringStream read FData;
property FieldValue: string read GetFieldValue write SetFieldValue;
end;
TFormDataFields = class(TCollection)
private
FBoundary: string;
function GetFormDataField(AIndex: Integer): TFormDataField;
function GetFormDataFieldByName(const AName:string): TFormDataField;
function GetItemIndex(const AName: string): integer;
public
constructor Create;
function Add: TFormDataField;
property Items[AIndex: Integer]: TFormDataField read GetFormDataField;
property ItemIndex[const AName:string]: integer read GetItemIndex;
property ItemByName[const AName:string]: TFormDataField read GetFormDataFieldByName;
property Boundary: string read FBoundary write FBoundary;
end;
procedure ParseRequest(RequestInfo: TIdHTTPRequestInfo;FormDataFields:TFormDataFields);
implementation
uses IdGlobalProtocols;
procedure ParseRequest(RequestInfo: TIdHTTPRequestInfo;FormDataFields:TFormDataFields);
var
Strings:TStringList;
UnparsedParams,Part,S:string;
Field: TFormDataField;
begin
if Pos("multipart/form-data",RequestInfo.ContentType)=0 then exit;
Strings:=TStringList.Create;
try
Strings.Delimiter:=";";
Strings.DelimitedText:=RequestInfo.ContentType;
FormDataFields.Boundary:=Strings.Values["boundary"];
if Length(FormDataFields.Boundary)=0 then
raise Exception.Create("No multipart boundary");
UnparsedParams:=RequestInfo.UnparsedParams;
Fetch(UnparsedParams,"--"+FormDataFields.Boundary);
while Length(UnparsedParams)>0 do
begin
Fetch(UnparsedParams,#13#10);
Part:=Fetch(UnparsedParams,#13#10"--"+FormDataFields.Boundary);
if Length(Part)=0 then continue;
Strings.NameValueSeparator:=":";
Strings.Text:="";
repeat
s:=Fetch(Part,#13#10);
if Length(s)=0 then Break;
Strings.Add(s)
until False;
Field:=FormDataFields.Add;
S:=Strings.Values["Content-Disposition"];
Fetch(S,"name=");
Field.FieldName:=AnsiDequotedStr(Fetch(S,";"),""");
S:=Strings.Values["Content-Disposition"];
Fetch(S,"filename=");
Field.FileName:=AnsiDequotedStr(Fetch(S,";"),""");
Field.ContentType:=Strings.Values["Content-Type"];
Field.FieldValue:=Part;
end;
finally
Strings.Free;
end;
end;
{ TFormDataFields }
function TFormDataFields.Add: TFormDataField;
begin
Result := TFormDataField(inherited Add);
end;
constructor TFormDataFields.Create();
begin
inherited Create(TFormDataField);
end;
function TFormDataFields.GetFormDataField(AIndex: Integer): TFormDataField;
begin
Result := TFormDataField(inherited Items[AIndex]);
end;
function TFormDataFields.GetItemIndex(const AName: string): integer;
begin
for result:=0 to Count-1 do
if Items[result].FieldName=AName then
exit;
result:=-1;
end;
function TFormDataFields.GetFormDataFieldByName(const AName:string): TFormDataField;
var i:integer;
begin
i:=ItemIndex[AName];
if i<0 then
raise Exception.CreateFmt("Item by name %s not finded",[AName]);
result:=Items[i];
end;
{ TFormDataField }
constructor TFormDataField.Create(Collection: TCollection);
begin
inherited Create(Collection);
//FHeaders:=TStringList.Create;
FData := TStringStream.Create("");
FFileName := "";
FFieldName := "";
FContentType := "";
end;
destructor TFormDataField.Destroy;
begin
FData.Free;
//FHeaders.Free;
inherited;
end;
procedure TFormDataField.SetContentType(const Value: string);
begin
if Length(Value) > 0 then begin
FContentType := Value;
end else begin
if Length(FFileName) > 0 then begin
FContentType := GetMIMETypeFromFile(FFileName);
end else begin;
FContentType := sContentTypeOctetStream;
end;
end;
end;
function TFormDataField.GetFieldValue: string;
begin
result:=FData.DataString;
end;
procedure TFormDataField.SetFieldValue(const Value: string);
begin
FData.Size:=0;
FData.WriteString(Value);
end;
end.
← →
SlymRO (2007-02-09 09:32) [4]USAGE:
FormDataFields:=TFormDataFields.Create;
try
ParseRequest(RequestInfo,FormDataFields);
if FormDataFields.Count=0 then
begin
ResponseInfo.ContentText:=Format(HTMLStr,[FormStr]);
exit;
end;
FormDataField:=FormDataFields.ItemByName["Unload"];
FileName:=ExtractFileName(FormDataField.FileName);
CheckName(FileName);
UnloadPath:=ServerHandles.ReadIniString("SendUnload","Path","");
if (Length(UnloadPath)=0) or (not DirectoryExists(UnloadPath)) then
raise Exception.Create("Директория выгрузок не доступна");
UnloadPath:=IncludeTrailingPathDelimiter(UnloadPath);
MaxFilesCount:=StrToIntDef(ServerHandles.ReadIniString("SendUnload","MaxUnloadFi les","0"),0);
if MaxFilesCount>0 then
if CountFiles(UnloadPath)>MaxFilesCount then
raise Exception.Create("Достигнут предел количества файлов в директории выгрузок");
FileStream:=TFileStream.Create(UnloadPath+FileName,fmCreate);
try
FileStream.CopyFrom(FormDataField.Data,0);
finally
FileStream.Free;
end;
finally
FormDataFields.Free;
end;
Страницы: 1 вся ветка
Текущий архив: 2007.10.07;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.031 c