delphi 带有TIdMultiPartFormDataStream的TIdHTTPServer

xzlaal3s  于 2024-01-07  发布在  其他
关注(0)|答案(2)|浏览(361)

这与我之前的问题here有关,我发现了一个东西,认为这可能是解决我的问题的方法,但我无法让它工作,我需要有人谁可以帮助我。
这是密码
代码TIdMIMEBoundary.FindBoundary()的问题是未声明的标识符和Fetch()。

  1. uses
  2. ...
  3. IdTCPConnection, IdTCPClient, IdHTTP, IdBaseComponent,
  4. IdComponent, IdCustomTCPServer, IdCustomHTTPServer, IdHTTPServer,
  5. IdContext, IdMultipartFormData, IdHeaderList, IdMessageCoder,
  6. IdMessageCoderMIME, IdMessage, IdGlobalProtocols;
  7. procedure DecodeFormData(const Header: String; ASourceStream:TStream);
  8. var
  9. MsgEnd: Boolean;
  10. Decoder: TIdMessageDecoder;
  11. Tmp: String;
  12. Dest: TStream;
  13. begin
  14. MsgEnd := False;
  15. Decoder := TIdMessageDecoderMIME.Create(nil);
  16. try
  17. TIdMessageDecoderMIME(Decoder).MIMEBoundary :=
  18. TIdMIMEBoundary.FindBoundary(Header);
  19. Decoder.SourceStream := ASourceStream;
  20. Decoder.FreeSourceStream := False;
  21. Decoder.ReadLn;
  22. repeat
  23. Decoder.ReadHeader;
  24. case Decoder.PartType of
  25. mcptUnknown:
  26. raise Exception.Create('Unknown form data detected');
  27. mcptText:
  28. begin
  29. Tmp := Decoder.Headers.Values['Content-Type'];
  30. Dest := TMemoryStream.Create;
  31. try
  32. Decoder := Decoder.ReadBody(Dest,MsgEnd);
  33. if AnsiSameText(Fetch(Tmp, ';'),'multipart/mixed') then
  34. DecodeFormData(Tmp, Dest)
  35. else
  36. // use Dest as needed...
  37. finally
  38. FreeAndNil(Dest);
  39. end;//try
  40. end;
  41. mcptAttachment:
  42. begin
  43. Tmp := ExtractFileName(Decoder.FileName);
  44. if Tmp <>'' then
  45. Tmp := 'c:\some folder\' + Tmp
  46. else
  47. Tmp := MakeTempFilename('c:\somefolder\');
  48. Dest := TFileStream.Create(Tmp, fmCreate);
  49. try
  50. Decoder := Decoder.ReadBody(Dest,MsgEnd);
  51. finally
  52. FreeAndNil(Dest);
  53. end;//try
  54. end;
  55. end;
  56. until (Decoder = nil) or MsgEnd;
  57. finally
  58. FreeAndNil(Decoder);
  59. end;//try
  60. end;

字符串

0g0grzrc

0g0grzrc1#

您需要在uses子句中包含IdMessage和IdMessageCoderMIME

vojdkbi0

vojdkbi02#

我创建了一个名为TIdMultiPartFormDataStreamReader的对象,它可以在一个步骤中解码您在服务器上接收到的所有多部分/表单数据内容。

  1. unit idMultipartFormDataReader;
  2. interface
  3. {$I IdCompilerDefines.inc}
  4. uses System.SysUtils, System.Classes, IdGlobal, IdGlobalProtocols,
  5. idMultipartFormData, IdCustomHTTPServer,
  6. IdCoderQuotedPrintable, IdCoderMIME, IdHeaderList;
  7. type
  8. TIdMultiPartFormDataStreamReader = class( TIdMultiPartFormDataStream )
  9. private
  10. FRequestInfo: TIdHTTPRequestInfo;
  11. protected
  12. procedure decodeStream;
  13. public
  14. property Fields: TIdFormDataFields read FFields;
  15. constructor Create( ARequestInfo: TIdHTTPRequestInfo );
  16. end;
  17. implementation
  18. { TIdMultiPartFormDataStreamReader }
  19. constructor TIdMultiPartFormDataStreamReader.Create(
  20. ARequestInfo: TIdHTTPRequestInfo);
  21. begin
  22. inherited Create;
  23. FSize := 0;
  24. FInitialized := False;
  25. FFields := TIdFormDataFields.Create(Self);
  26. FRequestInfo := ARequestInfo;
  27. decodeStream;
  28. end;
  29. procedure TIdMultiPartFormDataStreamReader.decodeStream;
  30. var
  31. delimi, cadStream: string;
  32. cabeceras: TIdHeaderList;
  33. stInfo: TMemoryStream;
  34. posIniPost, posFinPost, posIniRetorno: Integer;
  35. cadenaOri: string;
  36. fieldName: string;
  37. fieldFileName: string;
  38. contentType: string;
  39. charSet: string;
  40. transferEnconding: string;
  41. {$IFDEF STRING_IS_ANSI}
  42. LBytes: TIdBytes;
  43. {$ENDIF}
  44. function ReadStringLn( StreamOri: TStream; var cadenaBus: string; char_set: string ): Boolean;
  45. var
  46. candidato: Boolean;
  47. posIniSO: Integer;
  48. posFinSO: Integer;
  49. StreamDes: TMemoryStream;
  50. bleer: Byte;
  51. begin
  52. candidato := False;
  53. StreamDes := TMemoryStream.Create;
  54. posIniSO := StreamOri.Position;
  55. cadenaBus := '';
  56. while ( not candidato ) and ( StreamOri.Position < StreamOri.Size ) do begin
  57. StreamOri.Read( bleer, 1 );
  58. if ( bleer = 13 ) then begin
  59. StreamOri.Read( bleer, 1 );
  60. if ( bleer = 10 ) then begin
  61. candidato := True;
  62. posFinSO := StreamOri.Position;
  63. StreamOri.Position := posIniSO;
  64. if ( posFinSO - 2 - posIniSO > 0 ) then begin
  65. StreamDes.CopyFrom( StreamOri, posFinSO - 2 - posIniSO );
  66. StreamDes.Position := 0;
  67. cadenaBus := IdGlobalProtocols.ReadStringAsCharset( StreamDes, char_set );
  68. end;
  69. StreamOri.Position := posFinSO;
  70. end;
  71. end;
  72. end;
  73. StreamDes.Free;
  74. Result := candidato;
  75. end;
  76. begin
  77. {$IFDEF STRING_IS_ANSI}
  78. LBytes := nil;
  79. {$ENDIF}
  80. if ( ExtractHeaderItem( FRequestInfo.RawHeaders.Values[ 'Content-Type' ] ) <> 'multipart/form-data' ) then
  81. Exit;
  82. cabeceras := TIdHeaderList.Create( TIdHeaderQuotingType.QuoteHTTP );
  83. delimi := FRequestInfo.RawHeaders.Params['Content-Type', 'boundary'];
  84. FBoundary := delimi;
  85. FRequestContentType := sContentTypeFormData + FBoundary;
  86. FRequestInfo.PostStream.Position := 0;
  87. if ( ReadStringLn( FRequestInfo.PostStream, cadenaOri, FRequestInfo.CharSet ) ) then begin
  88. while ( cadenaOri = '--' + delimi ) and
  89. ( FRequestInfo.PostStream.Position < FRequestInfo.PostStream.Size ) do begin
  90. if ( ReadStringLn( FRequestInfo.PostStream, cadenaOri, FRequestInfo.CharSet ) ) then begin
  91. while ( cadenaOri <> '' ) and
  92. ( FRequestInfo.PostStream.Position < FRequestInfo.PostStream.Size ) do begin
  93. cabeceras.Add( cadenaOri );
  94. ReadStringLn( FRequestInfo.PostStream, cadenaOri, FRequestInfo.CharSet );
  95. end;
  96. fieldName := cabeceras.Params[ 'Content-Disposition', 'name' ];
  97. fieldFileName := cabeceras.Params[ 'Content-Disposition', 'filename' ];
  98. contentType := ExtractHeaderItem( cabeceras.Values[ 'Content-Type' ] );
  99. charSet := cabeceras.Params[ 'Content-Type', 'charset' ];
  100. transferEnconding := cabeceras.Values[ 'Content-Transfer-Encoding' ];
  101. stInfo := TMemoryStream.Create;
  102. posIniPost := FRequestInfo.PostStream.Position;
  103. posFinPost := posIniPost;
  104. ReadStringLn( FRequestInfo.PostStream, cadenaOri, FRequestInfo.CharSet );
  105. while ( cadenaOri <> '--' + delimi ) and ( cadenaOri <> '--' + delimi + '--' ) and
  106. ( FRequestInfo.PostStream.Position < FRequestInfo.PostStream.Size ) do begin
  107. posFinPost := FRequestInfo.PostStream.Position;
  108. ReadStringLn( FRequestInfo.PostStream, cadenaOri, FRequestInfo.CharSet );
  109. end;
  110. posIniRetorno := FRequestInfo.PostStream.Position;
  111. FRequestInfo.PostStream.Position := posIniPost;
  112. if ( posFinPost - 2 - posIniPost > 0 ) then begin
  113. if ( fieldFileName <> '' ) then begin
  114. stInfo.CopyFrom( FRequestInfo.PostStream, posFinPost - 2 - posIniPost );
  115. if ( LowerCase( transferEnconding ) = 'quoted-printable' ) then begin
  116. stInfo.Position := 0;
  117. cadStream := ReadStringFromStream( stInfo );
  118. stInfo.Clear;
  119. stInfo.Position := 0;
  120. TIdDecoderQuotedPrintable.DecodeStream( cadStream, stInfo );
  121. end else if ( LowerCase( transferEnconding ) = 'base64' ) then begin
  122. stInfo.Position := 0;
  123. cadStream := ReadStringFromStream( stInfo );
  124. stInfo.Clear;
  125. stInfo.Position := 0;
  126. TIdDecoderMIME.DecodeStream( cadStream, stInfo );
  127. end;
  128. stInfo.Position := 0;
  129. AddFormField( fieldName, contentType, charSet, stInfo, fieldFileName );
  130. end else begin
  131. stInfo.CopyFrom( FRequestInfo.PostStream, posFinPost - 2 - posIniPost );
  132. cadStream := '';
  133. stInfo.Position := 0;
  134. {$IFDEF STRING_IS_ANSI}
  135. ReadTIdBytesFromStream( stInfo, LBytes, stInfo.Size );
  136. {$ENDIF}
  137. if ( LowerCase( transferEnconding ) = '7bit' ) then begin
  138. {$IFDEF STRING_IS_UNICODE}
  139. cadStream := ReadStringFromStream( stInfo, -1, IndyTextEncoding_ASCII );
  140. {$ELSE}
  141. CheckByteEncoding( LBytes, IndyTextEncoding_ASCII, CharsetToEncoding( charSet ) );
  142. {$ENDIF}
  143. end else if ( LowerCase( transferEnconding ) = 'quoted-printable' ) then begin
  144. {$IFDEF STRING_IS_UNICODE}
  145. cadStream := ReadStringFromStream( stInfo );
  146. cadStream := TIdDecoderQuotedPrintable.DecodeString( cadStream, CharsetToEncoding( charSet ) );
  147. {$ELSE}
  148. BytesToRaw( LBytes, cadStream, Length( LBytes ) );
  149. LBytes := TIdDecoderQuotedPrintable.DecodeBytes( cadStream );
  150. {$ENDIF}
  151. end else if ( LowerCase( transferEnconding ) = 'base64' ) then begin
  152. {$IFDEF STRING_IS_UNICODE}
  153. cadStream := ReadStringFromStream( stInfo );
  154. cadStream := TIdDecoderMIME.DecodeString( cadStream, CharsetToEncoding( charSet ) );
  155. {$ELSE}
  156. BytesToRaw( LBytes, cadStream, Length( LBytes ) );
  157. LBytes := TIdDecoderMIME.DecodeBytes( cadStream );
  158. {$ENDIF}
  159. end else if ( LowerCase( transferEnconding ) = '8bit' ) or ( LowerCase( transferEnconding ) = 'binary' ) then begin
  160. {$IFDEF STRING_IS_UNICODE}
  161. cadStream := ReadStringAsCharset( stInfo, charSet );
  162. {$ENDIF}
  163. end;
  164. {$IFDEF STRING_IS_ANSI}
  165. BytesToRaw( LBytes, cadStream, Length( LBytes ) );
  166. {$ENDIF}
  167. AddFormField( fieldName, cadStream, charSet, contentType );
  168. stInfo.Free;
  169. end;
  170. end;
  171. FRequestInfo.PostStream.Position := posIniRetorno;
  172. cabeceras.Clear;
  173. end;
  174. end;
  175. end;
  176. end;
  177. end.

字符串
项目在https://github.com/enriquecerda/TIdMultiPartFormDataStreamReader

展开查看全部

相关问题