Добрый день. Подскажите как можно сделать кеширующий http прокси на основе IndyHttpProxyServer. Чтобы кешировались к примеру тока картинки,флешки,js и html страницы на определенном сайте. Если сайт не тот что указан в настройках кеширование не производить.
Готовые решения не интересуют. Надо именно свое. Чтобы пользователь поставил и мог уже пользоваться. А не заморачиваться с настройками.
Не подскажите как сохранять подгружаемый файл через IdHttpProxyServer и как на лету подменить часть страницы?
В общем осталась одна проблема. Подскажите как сохранить файл на диск который проходит через IndyHTTPProxyServer
Пробую Code: if(Pos('.gif',ADocument)>0) then begin Stream2 := TFileStream.Create('1.gif', fmOpenWrite); Stream2.Seek(0, soFromEnd); Stream2.CopyFrom(VStream, VStream.Size); Stream2.Free; end; Ничего не записывается... Никак не могу понять как записать файл на диск.
Я так понимаю, что VStream - это поток (stream)? Тогда делай Code: VStream.SaveToFile('C:\имя_файла.gif'); Также перед этим можешь сделать Code: VStream.Position := 0; но не обязательно, по моему, не помню точно и немогу сейчас проверить. По поводу твоего кода из предыдущего поста. Если перед Code: Stream2.CopyFrom(VStream, VStream.Size); добавить Code: VStream.Position := 0; то также все норм должно быть. Строчка Code: Stream2.Seek(0, soFromEnd); не нужна. А зачем?
1) var VStream: TStream; там нету свойства SaveToFile это первым делом смотрелось ) 2) Тоже не сработало
Поскольку TStream - абстрактный класс, то объекты можно создавать только от наследников этого класса. То есть VStream - может быть объектом типа TMemoryStream, TStringStream и т. д., нужно смотреть по коду... Так вот если VStream - объект типа TMemoryStream, например, тогда можно записывать так: Code: TMemoryStream(VStream).SaveToFile('C:\имя_файла.gif'); Если нет - тогда ошибка будет на этапе работы программы (нужно смотреть по коду).
Спасибо что помогаете после долго молчания всех в данной теме. Файл создался размером 35 байт. При попытке открыть его через тот же Paint ничего не показывает. Через текстовый редактор пробую открыть. Говорит что мол файл бинарный. Жму далее а в нем GIF89a и все )
Понятно. Нужно немного больше кода. Может быть где то поток перезаписывается, или не все данные в него загружаются, хотя не факт.
Да собственно перезаписи нигде нет. Пробую этот же код где больше ничего нет кроме как самого idhttpproxyserver.Все равно тоже самое. Сейчас вешаю это дело на событии OnHttpDocument. Code: procedure TForm1.test(ASender: TIdHTTPProxyServer; const ADocument: String; var VStream: TStream; const AHeaders: TIdHeaderList); var Stream2: TFileStream; IntBuf: array[0..9] of Integer; begin if(Pos('.gif',ADocument)>0) then begin TMemoryStream(VStream).SaveToFile('2.gif'); end; end;
OnHttpDocument возникает скорее всего не тогда, когда все данные прочитаны, а когда прочитана хотя бы какая то часть. То есть получается, что все данные нужно накапливать в дополнительно потоке и потом его записывать один раз в файл или же постоянно открывать файл и дописывать данные в конец. Узнать полный размер тела документа можно из заголовков (Content-length: ). Также в Google можно найти информацию об этом событии и еще кое-что о поле TransferMode и значении tmFullDocument. Это скорее всего именно то, что нужно. Code: http://www.delphimaster.net/view/6-1239173060
В общем кое что начинает получаться. Единственное но. Файл то записывает то нет. Не могу понять в чем проблема. Code: function PosR2L(): String; function InvertS(const S: string): string; var i, Len: Integer; begin Len := Length(S); SetLength(Result, Len); for i := 1 to Len do Result[i] := S[Len - i + 1]; end; var ps: Integer; begin ps := Pos(InvertS('/'), InvertS(b)); if ps <> 0 then begin ps:=Length(b) - Length('/') - ps + 3; Result := Copy(b,ps,Length(b)); Delete(b, ps, Length(Result) + 1); end else Result := '0'; end; procedure TForm1.test(ASender: TIdHTTPProxyServer; const ADocument: String; var VStream: TStream; const AHeaders: TIdHeaderList); var FS : TFileStream; i:String; begin if(Pos('.gif',ADocument)>0) or (Pos('.jpg',ADocument)>0) or (Pos('.swf',ADocument)>0) or (Pos('.js',ADocument)>0) or (Pos('.css',ADocument)>0) or (Pos('.png',ADocument)>0) or (Pos('.xml',ADocument)>0) then begin b:=ADocument; i := PosR2L(); b:=StringReplace(b, '/', '\',[rfReplaceAll]); mmo1.Lines.Add('C:\Users\carlson\Desktop\1'+b+i); if not DirectoryExists('C:\Users\carlson\Desktop\1'+b) then ForceDirectories('C:\Users\carlson\Desktop\1'+b); if not FileExists('C:\Users\carlson\Desktop\1'+b+i) then begin if (VStream.Size > 100000) then Begin ShowMessage('1'); FS := TFileStream.Create('C:\Users\carlson\Desktop\1'+b+i, fmCreate); FS.CopyFrom(VStream, VStream.Size); FS.Free; End; end; end; end;
Угу проблема была не в этом. А в том что заходил я на сайт через прокси тогда, когда до этого там уже был. А так как браузеры все почти кешируют данные и повторно их не загружают с инета из-за чего они через прокси не проходили ))) Сейчас все хорошо работает кроме одного. В инете нашел измененный файл IndyHtppProxyServer который позволял в случае если подгружаемый файл существует на диске то брать его с диска. Посмотрел что там было изменено. Нашел что было добавлено. Code: procedure CommandFILE(ASender: TIdCommand); with CommandHandlers.Add do begin Command := 'FILE'; {do not localize} OnCommand := CommandFILE; ParseParams := True; Disconnect := true; end; procedure TIdHTTPProxyServer.CommandFILE( ASender: TIdCommand ); begin ASender.Context.Connection.IOHandler.WriteFile(URLDecode(ASender.Params.Strings[ 0])); end; procedure TIdHTTPProxyServer.CommandHEAD( ASender: TIdCommand ) ; begin end; Встроил все это в новый Indy. Подмена прекрасно работает. Правда перед этим надо прогнать путь где лежит файл через UrlEncode. Файл подмениваю вот так AData := 'FILE '+URLEncode(path, false)+' HTTP/1.1' в событии OnBeforeCommandHandler. Но появилась одна проблема. Делалось собственно говоря это чтобы сто раз не подгружать тяжелые флешки и картинки. Но как оказалось на многие флешки передают параметры к примеру index.swf?set_backgroud=000000, а так же картинки на многих страницах имеют примерно такой вид 1.gif?45333... Но когда я пробую так же подгрузить флешку с диска с параметрами говорит что файла нет, а без параметров флешка грузиться но не срабатывает как надо потому что нету параметров. Подскажите как быть?
Здесь скорее всего проблема в том, что в имени файла не может быть некоторых символов (например того же знака "?". Полный список символов: ~#%&*{}\:<>?/+|"). придумай как сохранять без этих символов, и как загружать потом файл, если в его имени встретился запретный знак