Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2007.10.07;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.047 c
10-1137243244
Alex17
2006-01-14 15:54
2007.10.07
Как это выгледит в Дельфи


2-1189163668
Washington
2007-09-07 15:14
2007.10.07
Опять ошиба :(


1-1185554019
Ice-T
2007-07-27 20:33
2007.10.07
Беда OPenDialog а


2-1189337391
delphiForever
2007-09-09 15:29
2007.10.07
аналог Sleep, но с "мягкой" задержкой


2-1189406477
race1
2007-09-10 10:41
2007.10.07
Ожидание завершения программы из сервиса





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский