From c9ba9c85d964bc0fe1b958a241a88c5f22324ca7 Mon Sep 17 00:00:00 2001 From: geby Date: Tue, 29 Apr 2008 08:03:43 +0000 Subject: [PATCH] THTTPSend can handle folded headers in HTTP reply git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@91 7c85be65-684b-0410-a082-b2ed4fbef004 --- httpsend.pas | 80 +++++++++++++++++++++++++++++++--------------------- mimepart.pas | 33 +--------------------- synautil.pas | 39 +++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/httpsend.pas b/httpsend.pas index b661810..86779bc 100644 --- a/httpsend.pas +++ b/httpsend.pas @@ -1,5 +1,5 @@ {==============================================================================| -| Project : Ararat Synapse | 003.012.000 | +| Project : Ararat Synapse | 003.012.001 | |==============================================================================| | Content: HTTP client | |==============================================================================| @@ -374,6 +374,8 @@ var n: integer; pp: string; UsingProxy: boolean; + l: TStringList; + x: integer; begin {initial values} Result := False; @@ -579,39 +581,53 @@ begin { if need receive headers, receive and parse it } ToClose := FProtocol <> '1.1'; if FHeaders.Count > 0 then - repeat - s := FSock.RecvString(FTimeout); - FHeaders.Add(s); - if s = '' then - Break; - su := UpperCase(s); - if Pos('CONTENT-LENGTH:', su) = 1 then + begin + l := TStringList.Create; + try + repeat + s := FSock.RecvString(FTimeout); + l.Add(s); + if s = '' then + Break; + until FSock.LastError <> 0; + x := 0; + while l.Count > x do begin - Size := StrToIntDef(Trim(SeparateRight(s, ' ')), -1); - if (Size <> -1) and (FTransferEncoding = TE_UNKNOWN) then - FTransferEncoding := TE_IDENTITY; + s := NormalizeHeader(l, x); + FHeaders.Add(s); + su := UpperCase(s); + if Pos('CONTENT-LENGTH:', su) = 1 then + begin + Size := StrToIntDef(Trim(SeparateRight(s, ' ')), -1); + if (Size <> -1) and (FTransferEncoding = TE_UNKNOWN) then + FTransferEncoding := TE_IDENTITY; + end; + if Pos('CONTENT-TYPE:', su) = 1 then + FMimeType := Trim(SeparateRight(s, ' ')); + if Pos('TRANSFER-ENCODING:', su) = 1 then + begin + s := Trim(SeparateRight(su, ' ')); + if Pos('CHUNKED', s) > 0 then + FTransferEncoding := TE_CHUNKED; + end; + if UsingProxy then + begin + if Pos('PROXY-CONNECTION:', su) = 1 then + if Pos('CLOSE', su) > 0 then + ToClose := True; + end + else + begin + if Pos('CONNECTION:', su) = 1 then + if Pos('CLOSE', su) > 0 then + ToClose := True; + end; end; - if Pos('CONTENT-TYPE:', su) = 1 then - FMimeType := Trim(SeparateRight(s, ' ')); - if Pos('TRANSFER-ENCODING:', su) = 1 then - begin - s := Trim(SeparateRight(su, ' ')); - if Pos('CHUNKED', s) > 0 then - FTransferEncoding := TE_CHUNKED; - end; - if UsingProxy then - begin - if Pos('PROXY-CONNECTION:', su) = 1 then - if Pos('CLOSE', s) > 0 then - ToClose := True; - end - else - begin - if Pos('CONNECTION:', su) = 1 then - if Pos('CLOSE', s) > 0 then - ToClose := True; - end; - until FSock.LastError <> 0; + finally + l.free; + end; + end; + Result := FSock.LastError = 0; if not Result then Exit; diff --git a/mimepart.pas b/mimepart.pas index 97ccbc6..5c29aaf 100644 --- a/mimepart.pas +++ b/mimepart.pas @@ -1,5 +1,5 @@ {==============================================================================| -| Project : Ararat Synapse | 002.007.009 | +| Project : Ararat Synapse | 002.008.000 | |==============================================================================| | Content: MIME support procedures and functions | |==============================================================================| @@ -347,42 +347,11 @@ const ('ZIP', 'application', 'ZIP') ); -{:Read header from "Value" stringlist beginning at "Index" position. If header - is Splitted into multiple lines, then this procedure de-split it into one line.} -function NormalizeHeader(Value: TStrings; var Index: Integer): string; - {:Generates a unique boundary string.} function GenerateBoundary: string; implementation -function NormalizeHeader(Value: TStrings; var Index: Integer): string; -var - s, t: string; - n: Integer; -begin - s := Value[Index]; - Inc(Index); - if s <> '' then - while (Value.Count - 1) > Index do - begin - t := Value[Index]; - if t = '' then - Break; - for n := 1 to Length(t) do - if t[n] = #9 then - t[n] := ' '; - if not(t[1] in [' ', '"', ':', '=']) then - Break - else - begin - s := s + ' ' + Trim(t); - Inc(Index); - end; - end; - Result := TrimRight(s); -end; - {==============================================================================} constructor TMIMEPart.Create; diff --git a/synautil.pas b/synautil.pas index dfa970d..625c45f 100644 --- a/synautil.pas +++ b/synautil.pas @@ -1,9 +1,9 @@ {==============================================================================| -| Project : Ararat Synapse | 004.011.003 | +| Project : Ararat Synapse | 004.012.000 | |==============================================================================| | Content: support procedures and functions | |==============================================================================| -| Copyright (c)1999-2005, Lukas Gebauer | +| Copyright (c)1999-2008, Lukas Gebauer | | All rights reserved. | | | | Redistribution and use in source and binary forms, with or without | @@ -33,7 +33,7 @@ | DAMAGE. | |==============================================================================| | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| -| Portions created by Lukas Gebauer are Copyright (c) 1999-2005. | +| Portions created by Lukas Gebauer are Copyright (c) 1999-2008. | | Portions created by Hernan Sanchez are Copyright (c) 2000. | | All Rights Reserved. | |==============================================================================| @@ -306,6 +306,10 @@ function GetTempFile(const Dir, prefix: AnsiString): AnsiString; smaller, string is padded by Pad character.} function PadString(const Value: AnsiString; len: integer; Pad: AnsiChar): AnsiString; +{:Read header from "Value" stringlist beginning at "Index" position. If header + is Splitted into multiple lines, then this procedure de-split it into one line.} +function NormalizeHeader(Value: TStrings; var Index: Integer): string; + var {:can be used for your own months strings for @link(getmonthnumber)} CustomMonthNames: array[1..12] of string; @@ -1757,6 +1761,35 @@ begin Result := Value + StringOfChar(Pad, len - length(value)); end; +{==============================================================================} + +function NormalizeHeader(Value: TStrings; var Index: Integer): string; +var + s, t: string; + n: Integer; +begin + s := Value[Index]; + Inc(Index); + if s <> '' then + while (Value.Count - 1) > Index do + begin + t := Value[Index]; + if t = '' then + Break; + for n := 1 to Length(t) do + if t[n] = #9 then + t[n] := ' '; + if not(t[1] in [' ', '"', ':', '=']) then + Break + else + begin + s := s + ' ' + Trim(t); + Inc(Index); + end; + end; + Result := TrimRight(s); +end; + {==============================================================================} var n: integer;