PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Socket -> Website auslesen -> Problem mit Virtual Hosts



Morfio
01-02-2005, 11:23
Hallo,

ich programmiere gerade eine Klasse, die eine Website auslesen soll (browserähnlich) und den Quelltext herunterlädt. Das funktioniert soweit auch schon ganz gut, allerdings gibt es mit VirtualHosts ein Problem und zwar wird anhand der Domain nur die IP ausgelesen und diese dann an Apache geschickt, der dann nur die erste definierte Seite ausliest. Gibt es eine Möglichkeit, die richtige Website zu bekommen? Hier die Codes (die sind aus dem Internet, ich habe nur versucht, sie in eine Klassenstruktur zu packen):

Header

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h> // für write
#include <fstream.h>
#include <arpa/inet.h>

#define BUFFER_SIZE 100;

class rokiWebGet {

public:
rokiWebGet();
~rokiWebGet();
void setHost(char *_Host = "localhost");
void setPort(int _Port = 80);
void setQuery(char *_Query = "GET /index.html HTTP/1.0\n\n");
bool createConnection();
bool closeConnection();
char getHTML();

private:
char *Host;
char *Query;
int Port;
int sCon;
int err;
hostent *Entity;
struct in_addr IP;
struct sockaddr_in Dest;


};

Implementation:

#include "rokiwebget.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fstream.h>
#include <arpa/inet.h>
#include <cstdlib>

// Nur zum Überprüfen. Muss nachher noch raus!!
#include <iostream>
#include <cstdlib>

using namespace std;
// Ende raus!!

rokiWebGet::rokiWebGet() {
}

rokiWebGet::~rokiWebGet(){
}

void rokiWebGet::setHost(char *_Host) {
Host = _Host;
}

void rokiWebGet::setPort(int _Port) {
Port = _Port;
}

void rokiWebGet::setQuery(char *_Query) {
Query = _Query;
}

char rokiWebGet::getHTML() {
err = write(sCon, Query, strlen(Query));
if(err != sizeof(Query)) {
char buffer[100];
int i = 0;

do {
i = read(sCon, buffer, sizeof(buffer));
cout << buffer;
} while(i != 0);
}
}

bool rokiWebGet::createConnection() {
// Socket oeffnen
sCon = socket(AF_INET, SOCK_STREAM, 0);
if(sCon < 0) return false;
else {
Entity = gethostbyname(Host);

// Abfang, falls es den Host nicht gibt!
if(Entity == NULL) return false;
IP = *(struct in_addr*) Entity->h_addr;

Dest.sin_family = AF_INET;
Dest.sin_port = htons(80);
Dest.sin_addr = IP;

err = connect(sCon,(struct sockaddr*) &Dest, sizeof(sockaddr_in));
if(err < 0) return false;
else return true;
}
}

bool rokiWebGet::closeConnection() {
err = close(sCon);
if(err < 0) return false;
else return true;
}

Test:

#include "rokiwebget.h"

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[]) {

rokiWebGet rwg;
rwg.setHost("www.aceto-essig-oel.de");

if(rwg.createConnection()) cout << "jo";
else cout << "nope";

rwg.setQuery("GET /shop HTTP/1.0\n\n");
rwg.getHTML();

if(rwg.closeConnection()) cout << "jo";
else cout << "nope";

return EXIT_SUCCESS;
}

Vielen Dank,

Morfio ...

RapidMax
01-02-2005, 18:26
Wenn du im RFC 2616 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23) nachgelesen hättest, würdest du wissen, dass zusätzlich zur Request-Methode auch noch ein "Host"-Headerfield angegeben werden muss (MUST) ;)

Gruss, Andy

Morfio
01-02-2005, 18:55
Hi,

ja, das liebe Nachlesen, hast ja Recht. Ich muss aber ehrlich gestehen, ich war verzweifelt (: ... ich werde es mir aber zu Herzen nehmen. Vielen Dank für den Denkanstoss, ich werde das morgen direkt ausprobieren.

Vielen vielen Dank nochmal,

Morfio ...

Morfio
02-02-2005, 17:26
Hat super funktioniert.

Vielen Dank ... Morfio ...