C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Принять файл по HTTP, через проксу
Konstantine
Отправлено: 25.07.2005, 14:59


Мастер участка

Группа: Модератор
Сообщений: 545



Как принять файл (URL известен) через проксу. прокса имеет идентификацию Юзера...
GIZMO
Отправлено: 25.07.2005, 18:20


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Konstantine @ 25/07/2005, 14:59)
Как принять файл (URL известен) через проксу. прокса имеет идентификацию Юзера...

Если через WinInet, то:
- прокси можно задать в InternetOpen
hSession = InternetOpen("WinInet Example",
INTERNET_OPEN_TYPE_PROXY,"proxy","ms*", 0);
или через InternetSetOption.
Пароль и имя юзера через InternetSetOption или можно передать напр. в InternetOpenUrl(hSession,
"http://USER@PASSWORD/Host/file.html",
NULL, 0,0, 0);
Konstantine
Отправлено: 26.07.2005, 13:48


Мастер участка

Группа: Модератор
Сообщений: 545



GIZMO, если можно — поподробнее...
GIZMO
Отправлено: 26.07.2005, 18:28


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Konstantine @ 26/07/2005, 13:48)
GIZMO, если можно — поподробнее...

1. Открыть Интернет-сессию ф-ей InternetOpen:
CODE

HINTERNET  hInternet = InternetOpen(
 LPCTSTR lpszAgent,              //любое
 DWORD dwAccessType,        //тип доступа у тебя INTERNET_OPEN_TYPE_PROXY
 LPCTSTR lpszProxyName,     //твой прокси
 LPCTSTR lpszProxyBypass,   //какие адреса идут в обход прокси
 DWORD dwFlags                  //0
);

2. Далее открыть ресурс ф-ей InternetOpenUrl:
CODE

HINTERNET hFile = InternetOpenUrl(
 HINTERNET hInternet,         //рез-т работы 1
 LPCTSTR lpszUrl,                 //твой URL, но после протокола надо вставить имя_юзера и пароль в таком порядке "http://name@password/www.cbulder.ru"
 LPCTSTR lpszHeaders,        //NULL
 DWORD dwHeadersLength,//0
 DWORD dwFlags,                //0
 DWORD_PTR dwContext     //0
);

3. Читать файл функцией InternetReadFile:
CODE

BOOL InternetReadFile(
 HINTERNET hFile,               // рез-т работы 2
 LPVOID lpBuffer,                //указатель на буфер
 DWORD dwNumberOfBytesToRead, //сколько надо считать
 LPDWORD lpdwNumberOfBytesRead//сколько считано, реально
);

читать нужно в цикле пока невозвратит false или не скажет, что прочитано 0 (4-ый параметр).
Konstantine
Отправлено: 28.07.2005, 16:38


Мастер участка

Группа: Модератор
Сообщений: 545



возвращает что прочитано 0 байт sad.gif
GIZMO
Отправлено: 29.07.2005, 09:25


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Konstantine @ 28/07/2005, 16:38)
возвращает что прочитано 0 байт sad.gif

CODE

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::GetBtnClick(TObject *Sender)
{
   TFileStream* fs;

   int ReadByte=0;
   int ReadBlock=0;
   int NewReadBlock=ReadBlockEd->Text.ToInt();
   bool Done=false;

   String File=FileEd->Text;
   String URL = URLEd->Text;

   IdHTTP1->Request->ProxyPassword = PasswordEd->Text;
   IdHTTP1->Request->ProxyServer = "ps.company.ru";
   IdHTTP1->Request->ProxyPort = 3128;
   IdHTTP1->Request->ProxyUsername = UserEd->Text;

   //если файл ранее уже закачивался...
   if(ini->SectionExists(URL)) {
       ReadByte = ini->ReadInteger(URL, "ReadByte", 0);
       Done = ini->ReadBool(URL, "Done", true);
       if(Done) {
           ShowMessage(String("Файл закачен полностью. Размер — ") + ReadByte + String(" байт."));
           return;
       }
       ReadBlock = ini->ReadInteger(URL, "ReadBlock", 0);
       ReadBlock = (ReadBlock == NewReadBlock)? ReadBlock:NewReadBlock;
       File      = ini->ReadString(URL, "File", 0);

       TFileStream* fs = new TFileStream(File, fmOpenWrite);
       fs->Position = ReadByte;
       IdHTTP1->Request->ContentRangeStart = ReadByte;
       IdHTTP1->Request->ContentRangeEnd = ReadByte + ReadBlock;
       IdHTTP1->Get(URL, fs);

       if(IdHTTP1->Request->ContentRangeEnd > IdHTTP1->Response->ContentRangeEnd) {
           ini->WriteInteger(URL, "ReadByte", IdHTTP1->Response->ContentLength + IdHTTP1->Response->ContentRangeStart);
           ini->WriteInteger(URL, "ReadBlock", ReadBlock);
           //ini->WriteString(URL, "File", File);
           ini->WriteInteger(URL, "Done", true);
       }
       else {
           ini->WriteInteger(URL, "ReadByte", ReadByte + ReadBlock);
           ini->WriteInteger(URL, "ReadBlock", ReadBlock);
           //ini->WriteString(URL, "File", File);
           ini->WriteInteger(URL, "Done", false);
       }

       delete fs;
   }
   else {
       TFileStream* fs = new TFileStream(File, fmCreate);

       fs->Position = ReadByte;
       IdHTTP1->Request->ContentRangeStart = ReadByte;
       IdHTTP1->Request->ContentRangeEnd = ReadByte + NewReadBlock;
       IdHTTP1->Get(URL, fs);

       if(IdHTTP1->Request->ContentRangeEnd > IdHTTP1->Response->ContentRangeEnd) {
           ini->WriteInteger(URL, "ReadByte", IdHTTP1->Response->ContentLength + IdHTTP1->Response->ContentRangeStart);
           ini->WriteInteger(URL, "ReadBlock", NewReadBlock);
           ini->WriteString(URL, "File", File);
           ini->WriteInteger(URL, "Done", true);
       }
       else {
           ini->WriteInteger(URL, "ReadByte", ReadByte + NewReadBlock);
           ini->WriteInteger(URL, "ReadBlock", NewReadBlock);
           ini->WriteString(URL, "File", File);
           ini->WriteInteger(URL, "Done", false);
       }

       delete fs;
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
   ini = new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
   delete ini;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::IdHTTP1Work(TObject *Sender, TWorkMode AWorkMode,
     const int AWorkCount)
{
   Memo1->Lines->Add(String("Скачано — ") + IntToStr(AWorkCount));
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::IdHTTP1Status(TObject *axSender,
     const TIdStatus axStatus, const AnsiString asStatusText)
{
   Memo1->Lines->Add(asStatusText);
}
//---------------------------------------------------------------------------


Вот так простенько Я качаю через прокси к тому же кусочками т.к. у меня ограничение по объему в неделю (зато на халяву), но если есть переадресация — качать не будет и если эта ссылка скрипт- тоже не будет. Дорабатывать уже тебе придется или бери меня на работу smile.gif. Вообще удобней WinInet юзать с ним вроде разобрался, но готового ничего нет показать и времени накидать чего-нибудь тоже нет (напрягают на основной работе). Так то... ну пока.

Konstantine
Отправлено: 29.07.2005, 14:17


Мастер участка

Группа: Модератор
Сообщений: 545



IdHTTP1 — это как раз то, что нужно.
GIZMO, спасибо

Вернуться в Вопросы программирования в C++Builder