Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.051 c
15-1189450087
Andy BitOff
2007-09-10 22:48
2007.10.07
Не стирает привод, HL-DT-ST DVDRAM GSA-H42L (LG)


11-1172737932
Trible
2007-03-01 11:32
2007.10.07
TKOLmdvXLGrid


15-1188973346
de.
2007-09-05 10:22
2007.10.07
Город мастеров (Полу сабж, полу вопрос... :)


2-1189582237
Wood
2007-09-12 11:30
2007.10.07
TColorDialog.


15-1189009721
fisher
2007-09-05 20:28
2007.10.07
cos(x) в полярной системе