|
제 답변은 아니지만, 예제가 있어서 올려드립니다.
Hi,
I created a class TIndyHttp that handles cookies
in a simple way. It doesn't worry about expiration.
The time of the cookie is the life of the instance.
It doesn't check for the server it is accessing so
you need a separate instance for each server that
uses cookies.
Below is the code.
Frank
file://---------------------------------------------------------------------
------
#include <vcl.h>
#pragma hdrstop
#include "IndyHttp1.h"
file://#include "WebAuctionProperties.h"
file://---------------------------------------------------------------------
------
#pragma package(smart_init)
file://#pragma link "HttpProt"
file://#pragma resource "*.dfm"
TIndyHttp *YahooIndyHttp;
TIndyHttp *IndyHttp;
file://---------------------------------------------------------------------
------
__fastcall TIndyHttp::TIndyHttp(void)
{
Timer = new TTimer(Application);
Timer->Enabled = false;
Timer->OnTimer = TimerTimer;
Http = NULL;
CreateHttp();
SSL = new TIdConnectionInterceptOpenSSL(Application);
CookieList = new TStringList();
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::CreateHttp(void)
{
if(Http)
{
delete Http;
}
Http = new TIdHTTP(Application);
Http->OnWork = HttpWork;
Http->OnWorkBegin = HttpWorkBegin;
Http->OnWorkEnd = HttpWorkEnd;
Http->OnStatus = HttpStatus;
Http->OnRedirect = HttpRedirect;
Http->OnConnected = HttpConnected;
Http->OnDisconnected = HttpDisconnected;
Http->HandleRedirects = true;
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::GetCookie(void)
{
TStringList *list = new TStringList();
Http->Response->ExtraHeaders->Extract("Set-Cookie", list);
for(int i = 0 ; i < list->Count; i++)
{
AddCookie(list->Strings[i]);
}
delete list;
}
file://---------------------------------------------------------------------
------
String __fastcall TIndyHttp::SetCookie(void)
{
String cookie;
for(int index = 0; index < CookieList->Count; index++)
{
if(!cookie.IsEmpty())
cookie += "&";
cookie += CookieList->Strings[index];
}
Http->Request->ExtraHeaders->Clear();
if(!cookie.IsEmpty())
{
Http->Request->ExtraHeaders->Add("Cookie: " + cookie);
}
return cookie;
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::SetSSL(const String& url)
{
if(url.UpperCase().Pos("HTTPS") > 0)
{
Http->Intercept = SSL;
}
else
{
Http->Intercept = NULL;
}
}
file://---------------------------------------------------------------------
------
String __fastcall TIndyHttp::Get(
const String& url)
{
// CreateHttp();
String error;
SetCookie();
SetSSL(url);
HttpReset(NULL);
Timer->Interval = 10000;
Timer->Enabled = true;
try
{
DataIn = Http->Get(url);
GetCookie();
}
catch(Exception& E)
{
error = E.Message;
}
Timer->Enabled = false;
// delete Http;
return error;
}
file://---------------------------------------------------------------------
------
String __fastcall TIndyHttp::Post(
const String& url,
const String& data)
{
// CreateHttp();
String error;
SetCookie();
TStringStream *response = new TStringStream("");
TStringList *dataList;
LoadDataList(data, dataList);
HttpReset(NULL);
try
{
Http->Post(url, dataList, response);
DataIn = response->DataString;
}
catch(Exception& E)
{
error = E.Message;
}
Timer->Enabled = false;
delete response;
delete dataList;
return error;
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::LoadDataList(
const String& data,
TStringList *dataList)
{
dataList->Add(data);
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::AddCookie(const String& Data)
{
char cookie[2000];
char *p;
int index;
int pos = Data.Pos(";");
HttpReset(NULL);
strcpy(cookie,Data.SubString(1, pos - 1).c_str());
// Replace all '&' with ';'
for(;;)
{
p = strchr(cookie, '&');
if(!p)
break;
*p = ';';
}
String NewCookie, data, var, thing, match;
bool found;
char *q, *next;
// Go through and get each cookie
p = strtok(cookie, ";\0");
while(p)
{
// Find the '='
q = strrchr(p, '=');
if(!q)
break;
// Get the data part of the cookie
data = q + 1;
// Put an NULL after the last '='
*(q + 1) = NULL;
// Go through and pull off all the variable names
for(;;)
{
// Find the next '='
next = strchr(p, '=');
if(!next)
break;
*next = NULL;
// Pull off the variable name
var = p;
// Create the cookie
thing = var + "=" + data;
match = var + "=";
// Seach to see if we already have this variable
found = false;
for(index = 0; index < CookieList->Count; index++)
{
if(CookieList->Strings[index].Pos(match) > 0)
{
// Variable found, replace data
found = true;
CookieList->Delete(index);
CookieList->Insert(index, thing);
break;
}
}
if(!found)
{
// Variable not found, add it
CookieList->Add(thing);
}
// Move to search for the next variable
file://todo - Can this go beyond the last one to search????
p = next + 1;
}
// Get the next cookie
p = strtok(NULL, ";\0");
}
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::TimerTimer(TObject *Sender)
{
// Finished = true;
Http->DisconnectSocket();
Timer->Enabled = false;
// ShowMessage("Abort");
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpRedirect(TObject *Sender,
const AnsiString dest, int &NumRedirect, bool &Handled)
{
GetCookie();
SetCookie();
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpReset(TObject *Sender)
{
Timer->Enabled = false;
// Timer->Interval = atoi(Properties->Timeout->Text.c_str()) * 1000;
// Timer->Interval = 1;
Timer->Enabled = true;
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpConnected(TObject *Sender)
{
HttpReset(NULL);
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpDisconnected(TObject *Sender)
{
HttpReset(NULL);
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpStatus(TObject *axSender,
const TIdStatus axStatus, const AnsiString asStatusText)
{
//
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpWork(TComponent *Sender, TWorkMode AWorkMode,
const int AWorkCount)
{
HttpReset(NULL);
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpWorkBegin(TComponent *Sender,
TWorkMode AWorkMode, const int AWorkCountMax)
{
HttpReset(NULL);
}
file://---------------------------------------------------------------------
------
void __fastcall TIndyHttp::HttpWorkEnd(TComponent *Sender,
TWorkMode AWorkMode)
{
HttpReset(NULL);
}
file://---------------------------------------------------------------------
------
*************************************
file://---------------------------------------------------------------------
------
#ifndef IndyHttp1H
#define IndyHttp1H
file://---------------------------------------------------------------------
------
#include "IdBaseComponent.hpp"
#include "IdComponent.hpp"
#include "IdHTTP.hpp"
#include "IdTCPClient.hpp"
#include "IdTCPConnection.hpp"
#include "IdSSLOpenSSL.hpp"
file://#include <Buttons.hpp>
file://#include <ExtCtrls.hpp>
#include "IdHTTPServer.hpp"
#include "IdMessageClient.hpp"
#include "IdSMTP.hpp"
#include "IdTCPServer.hpp"
#include "IdTime.hpp"
file://---------------------------------------------------------------------
------
class TIndyHttp
{
private: // User declarations
void __fastcall TIndyHttp::CreateHttp(void);
void __fastcall TIndyHttp::GetCookie(void);
void __fastcall TIndyHttp::AddCookie(const String& Data);
void __fastcall TIndyHttp::SetSSL(const String& url);
void __fastcall TIndyHttp::HttpRedirect(TObject *Sender,
const AnsiString dest, int &NumRedirect, bool &Handled);
void __fastcall TIndyHttp::HttpReset(TObject *Sender);
void __fastcall TIndyHttp::TimerTimer(TObject *Sender);
void __fastcall TIndyHttp::HttpWorkEnd(TComponent *Sender,
TWorkMode AWorkMode);
void __fastcall TIndyHttp::HttpWorkBegin(TComponent *Sender,
TWorkMode AWorkMode, const int AWorkCountMax);
void __fastcall TIndyHttp::HttpWork(TComponent *Sender, TWorkMode
AWorkMode,
const int AWorkCount);
void __fastcall TIndyHttp::HttpStatus(TObject *axSender,
const TIdStatus axStatus, const AnsiString asStatusText);
void __fastcall TIndyHttp::HttpConnected(TObject *Sender);
void __fastcall TIndyHttp::HttpDisconnected(TObject *Sender);
void __fastcall TIndyHttp::LoadDataList(
const String& data,
TStringList *dataList);
TIdHTTP *Http;
TIdConnectionInterceptOpenSSL *SSL;
TTimer *Timer;
bool Finished;
public: // User declarations
__fastcall TIndyHttp(void);
String __fastcall TIndyHttp::Get(
const String& url);
String __fastcall TIndyHttp::Post(
const String& url,
const String& data);
String __fastcall TIndyHttp::SetCookie(void);
TStringList *CookieList;
String Cookie;
TStringStream *DataInStream;
String DataIn;
};
file://---------------------------------------------------------------------
------
extern PACKAGE TIndyHttp *IndyHttp;
extern TIndyHttp *YahooIndyHttp;
file://---------------------------------------------------------------------
------
#endif
김병훈 님이 쓰신 글 :
: 볼랜드 빌더를 거의 처음 사용해보는 초보입니다.
:
: 현재 회사에서 볼랜드 C++Builder를 사용해서 dll 파일을 작성하고 있는데요.
:
: 로그인 부분을 작성할려고 하는데 현재 쿠기 설정에서 엄청 헤매고 있습니다.
:
: 대충 Help를 뒤져보니까, Response하구, Request에서 어떻게 하면 될것 같은데...잘 안되네요.
:
: 쿠키를 설정하는 부분, 읽어오는 부분 그리고 해지하는 부분...좀 가르쳐 주세요
:
: 고수님들 부탁드립니다.
|