#define CHUNK 16384 //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "THTTPdownloader.h" #include "TZlib\GZipHelper.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" THTTPdownloader *HTTPdownloader; //--------------------------------------------------------------------------- __fastcall THTTPdownloader::THTTPdownloader(TComponent* Owner) : TForm(Owner) { headers = new TList(); } //--------------------------------------------------------------------------- int __fastcall THTTPdownloader::descargarHTML(char *host, char *request, TStream *out) { TMemoryStream* in = new TMemoryStream(); char buffer[4096]; int pos,readed; int currSize,lastSize; AnsiString line, Location; HTTPheaders_list HeaderStruct; httpResult->Clear(); for (int i = 0; i < headers->Count; i++) { HeaderStruct = (HTTPheaders_list) headers->Items[i]; delete HeaderStruct; } headers->Clear(); TcpClient1->RemoteHost = AnsiString( host ); TcpClient1->RemotePort = 80; TcpClient1->Open(); if ( TcpClient1->Connected ) { statusBar->SelAttributes->Color = clGreen;statusBar->Lines->Add(AnsiString(Now())+AnsiString(" > ")+AnsiString("Conectado a: ")+AnsiString(host)); /* ¿ver que se envia? if ( Visible && debug->Checked ) ShowMessage("Cierre esta ventana para continuar"); */ TcpClient1->SendBuf(request,StrLen(request)); bool R,W,T; bool atStart = true; bool inHeaders = true; while (TcpClient1->Connected) { R=TcpClient1->WaitForData(20000); if (!TcpClient1->Connected || !R) break; if ( inHeaders ) line = TcpClient1->Receiveln(); else { readed = TcpClient1->ReceiveBuf(buffer,4096); if(readed<=0) break; } if ( atStart ) { atStart = false; //if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', line, m)) return false; httpResult->SelAttributes->Color = clGreen; httpResult->Paragraph->Numbering = nsBullet; httpResult->Lines->Add(line); if ( line.SubString(1,4)!="HTTP" ) return -1; continue; } if (inHeaders) { if ( line.Trim() == "" ) { inHeaders = false; continue; } pos = line.AnsiPos(":"); if (pos==0) { // Skip to the next header continue; } HeaderStruct = new THTTP_headers; HeaderStruct->key = line.SubString(1,pos-1).Trim().LowerCase(); HeaderStruct->value = line.SubString(pos+1,line.Length()).Trim(); headers->Add(HeaderStruct); httpResult->SelAttributes->Color = clRed; httpResult->Paragraph->Numbering = nsBullet; httpResult->Lines->Add(line); continue; } in->Write(buffer,readed); } TcpClient1->Close(); statusBar->Lines->Add(AnsiString(Now())+AnsiString(" > ")+AnsiString("Leidos: ")+AnsiString(readed)+"/"+AnsiString(in->Size)); bool gziped=false; for ( pos=0;posCount; pos++ ) { HeaderStruct = (HTTPheaders_list)headers->Items[pos]; if ( HeaderStruct->key=="content-encoding" ) { gziped= (HeaderStruct->value=="gzip"); break; } else if ( HeaderStruct->key=="location" ) { Location = HeaderStruct->value; } } httpResult->Paragraph->Numbering = nsNone; if ( gziped ) { in->Position=0; CGZIP2A plain((unsigned char *)in->Memory,(int)in->Size); out->Write(plain.psz,plain.Length);out->Write("",1); httpResult->Lines->Add(plain.psz); } else { in->Write("",1);in->Position = 0; out->Write(in->Memory,in->Size); httpResult->Lines->Add((char *)in->Memory); } if ( debug->Checked ) { DateSeparator = '-'; TimeSeparator = ';'; statusBar->Clear(); statusBar->SelAttributes->Color = clRed;statusBar->Lines->Add("RX: ------------------------------------------------------------------"); statusBar->Lines->Assign(httpResult->Lines); statusBar->SelAttributes->Color = clRed;statusBar->Lines->Add("TX: ------------------------------------------------------------------"); statusBar->Lines->Add(request); statusBar->Lines->SaveToFile( ExtractFilePath(Application->ExeName)+"log\\"+DateTimeToStr(Now())+".http.rtf" ); statusBar->SelAttributes->Color = clRed;statusBar->Lines->Add("EOT ------------------------------------------------------------------"); } delete in; } else { statusBar->SelAttributes->Color = clRed;statusBar->Lines->Add(AnsiString(Now())+AnsiString(" > ")+AnsiString("ERROR CONECTANDO a: ")+AnsiString(host)); return -1; } if ( !Location.IsEmpty() ) { AnsiString lrequest; lrequest = "GET "+Location; lrequest+=" HTTP/1.1\r\n"; lrequest+= "Host: "+AnsiString(host)+"\r\n"; lrequest+= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"; lrequest+= "Accept-Language: es-es,es;q=0.8\r\n"; lrequest+= "Accept-Encoding: gzip,deflate\r\n"; lrequest+= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"; lrequest+= "Keep-Alive: 300\r\n"; lrequest+= "Connection: keep-alive\r\n"; lrequest+= "\r\n"; return descargarHTML(host, lrequest.c_str(), out); } else return 0; } //--------------------------------------------------------------------------- void __fastcall THTTPdownloader::FormDestroy(TObject *Sender) { HTTPheaders_list HeaderStruct; // Clean up – must free memory for the items as well as the list for (int i = 0; i < headers->Count; i++) { HeaderStruct = (HTTPheaders_list) headers->Items[i]; delete HeaderStruct; } delete headers; } //---------------------------------------------------------------------------