PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : HTTP-POST über socket



Giuly
06-11-2005, 17:26
Hi,
ich will etwas per POST an einen Server senden, allerdings bekomme ich immer einen BAD REQUEST-Error. Egal was ich mache.
Per wget gehts allerdings:

wget --post-data="a=b" http://foo.bar.com/index.php -O foo.html -o /dev/null

Kann mir jemand sagen, wie der Request dazu aussehen muss?

Hat ausserdem jemand eine urlencode-Funktion in C? Ich will dafür nicht eine ganze Lib benutzten.

MfG Giuly

So, ich hab mich jetzt dazu entschlossen cURL zu benutzten. kann mir aber mal jemand erklären, wie ich eine Seite in einen char* lesen kann? Bei den Examples hab ich da nichts brauchbares gefunden.

Das hab ich jetzt auch gelöst per http://cool.haxx.se/cvs.cgi/curl/docs/examples/getinmemory.c?rev=1.10&content-type=text/vnd.viewcvs-markup

Jetzt brauch ich nurnoch irgendwas um zu zählen wieoft ein string in einem anderem vorkommt, aber das kriege ich auch selber hin :) (Sonst wird hier nochmal editiert :)

Giuly
07-11-2005, 00:58
int strcnt(const char* haystack, char* needle) {
char* hays=malloc(sizeof(char)*strlen(haystack));
strcpy(haystack, hays);
int pos=-1, times=0;
while((pos=strstr(hays, needle)) != NULL) {
times++;
strncpy (hays,"",pos);
}
return times;
}

Das hab ich bis jetzt, funktioniert nur nicht.
Wie geht das richtig?

ninguno
07-11-2005, 07:00
also auf den ersten blick würd ich mal sagen, dass jedenfalls das strcpy falsch ist.
strcpy(haystack, hays);du kopierst vom (gerade allokierten und leeren) buffer hays in deinen parameter haystack, das sollte wohl umgekehrt laufen...

undefined
07-11-2005, 07:16
Ich habe hier noch eine Übungsaufgabe die ich mal für CGI Programmierung gemacht habe. Das hilft dir vielleicht weiter.



#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include <string.h>
#include <vector>

using namespace std;

struct ListElement
{
ListElement* naechstes;
string schluessel;
string wert;
// __construct
ListElement() : naechstes(0)
{}
// __construct erweitert
ListElement( const string& _schluessel, const string& _wert ) :
naechstes( 0 ),
schluessel( _schluessel ),
wert( _wert )
{}
}
;

class Liste
{
private:
ListElement* erstes;
ListElement* letztes;
int anzahl;
public:
Liste() : erstes( 0 ), letztes( 0 ), anzahl( 0 )
{}
virtual ~Liste();

bool empty() const
{
return ( anzahl == 0 );
}

int size() const
{
return anzahl;
}

void push_back( const string& schluessel, const string& wert );

void pop_front();

ListElement* front()
{
return erstes;
}
};

void Liste::push_back( const string& _schluessel, const string& _wert )
{
ListElement* tmp = new ListElement( _schluessel, _wert );

if ( letztes != 0 )
letztes->naechstes = tmp;
else
erstes = tmp;

letztes = tmp;
anzahl++;
}

void Liste::pop_front()
{
if ( anzahl == 0 )
return;

ListElement* tmp = erstes;
erstes = tmp->naechstes;

if ( erstes == 0 )
letztes == 0;

delete tmp;
anzahl--;
}

Liste::~ Liste()
{
while( anzahl != 0 )
pop_front();
}

bool Anfrage( Liste& _liste )
{
string request_method = getenv( "REQUEST_METHOD" );

// Puffer fuer uebergeben Daten
char* buffer = 0;
unsigned int len;

// Behandle Post Variablen
if ( request_method == "POST" ) {
len = atoi( getenv( "QUERY_STRING" ) );
buffer = new char[len + 1];
for ( unsigned int i = 0; i < len; i++ ) {
cin.get( buffer[i] );
}
}

// Behandle GET Variablen
if ( request_method == "GET" ) {
len = strlen( getenv( "QUERY_STRING" ) );
buffer = new char[len+1];
strcpy( buffer, getenv( "QUERY_STRING" ) );
}

// Terminieren
buffer[len] = 0;

// Kopiere Puffer in String
string eingabe = buffer;
delete[] buffer;

// Lokale Variablen zur Teilstring Suche
size_t pos = 0;
size_t old_pos = 0;

// Lese Werte Paare
while ( pos < len ) {
pos = eingabe.find( "&", old_pos );
// Ein oder mehrer parameter wurden uebergeben ?
if ( pos == string::npos )
pos = eingabe.length();

// Splitten
string paar = eingabe.substr( old_pos, pos-old_pos );
size_t eq_pos = paar.find("=");

string schluessel = paar.substr( 0, eq_pos );
// Funktion zum Konvertieren von Leerzeichen( schluessel );

string wert = paar.substr( eq_pos + 1 );
// Funktion zum Konvertieren von Leerzeichen( schluessel );

// Erstelle Liste
_liste.push_back( schluessel, wert );
old_pos = pos + 1;
}

}

void Antworte( Liste& _liste )
{
cout << "Content-Type: text/html" << endl;
cout << endl;
cout << "<html><title>C++ Beispiel CGI GET/POST Beispiel</title>" << endl;
cout << "<head>" << endl;
cout << "<body><h2>Ausgabe</h2>" << endl;

ListElement* tmp;
for( tmp = _liste.front(); tmp != 0; tmp = tmp->naechstes ) {
cout << "<p><b>" << tmp->schluessel << "</b>" << tmp->wert << "</p>" << endl;
}

cout << "</body>" << endl;
cout << "</head>" << endl;
cout << "</html>" << endl;
}


int main()
{
Liste liste;

if ( Anfrage( liste ) == false ) {
cout << "Content-Type: text/html" << endl;
cout << endl;
cout << "<html><title>C++ Beispiel CGI GET/POST Beispiel</title>" << endl;
cout << "</head><body>Keine Anfrage erhalten!" << endl;
cout << "</body>" << endl;
cout << "</head>" << endl;
cout << "</html>" << endl;
} else
Antworte( liste );

return EXIT_SUCCESS;
}

Giuly
07-11-2005, 13:48
Ich habe hier noch eine Übungsaufgabe die ich mal für CGI Programmierung gemacht habe. Das hilft dir vielleicht weiter.



#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include <string.h>
#include <vector>

using namespace std;

struct ListElement
{
ListElement* naechstes;
string schluessel;
string wert;
// __construct
ListElement() : naechstes(0)
{}
// __construct erweitert
ListElement( const string& _schluessel, const string& _wert ) :
naechstes( 0 ),
schluessel( _schluessel ),
wert( _wert )
{}
}
;

class Liste
{
private:
ListElement* erstes;
ListElement* letztes;
int anzahl;
public:
Liste() : erstes( 0 ), letztes( 0 ), anzahl( 0 )
{}
virtual ~Liste();

bool empty() const
{
return ( anzahl == 0 );
}

int size() const
{
return anzahl;
}

void push_back( const string& schluessel, const string& wert );

void pop_front();

ListElement* front()
{
return erstes;
}
};

void Liste::push_back( const string& _schluessel, const string& _wert )
{
ListElement* tmp = new ListElement( _schluessel, _wert );

if ( letztes != 0 )
letztes->naechstes = tmp;
else
erstes = tmp;

letztes = tmp;
anzahl++;
}

void Liste::pop_front()
{
if ( anzahl == 0 )
return;

ListElement* tmp = erstes;
erstes = tmp->naechstes;

if ( erstes == 0 )
letztes == 0;

delete tmp;
anzahl--;
}

Liste::~ Liste()
{
while( anzahl != 0 )
pop_front();
}

bool Anfrage( Liste& _liste )
{
string request_method = getenv( "REQUEST_METHOD" );

// Puffer fuer uebergeben Daten
char* buffer = 0;
unsigned int len;

// Behandle Post Variablen
if ( request_method == "POST" ) {
len = atoi( getenv( "QUERY_STRING" ) );
buffer = new char[len + 1];
for ( unsigned int i = 0; i < len; i++ ) {
cin.get( buffer[i] );
}
}

// Behandle GET Variablen
if ( request_method == "GET" ) {
len = strlen( getenv( "QUERY_STRING" ) );
buffer = new char[len+1];
strcpy( buffer, getenv( "QUERY_STRING" ) );
}

// Terminieren
buffer[len] = 0;

// Kopiere Puffer in String
string eingabe = buffer;
delete[] buffer;

// Lokale Variablen zur Teilstring Suche
size_t pos = 0;
size_t old_pos = 0;

// Lese Werte Paare
while ( pos < len ) {
pos = eingabe.find( "&", old_pos );
// Ein oder mehrer parameter wurden uebergeben ?
if ( pos == string::npos )
pos = eingabe.length();

// Splitten
string paar = eingabe.substr( old_pos, pos-old_pos );
size_t eq_pos = paar.find("=");

string schluessel = paar.substr( 0, eq_pos );
// Funktion zum Konvertieren von Leerzeichen( schluessel );

string wert = paar.substr( eq_pos + 1 );
// Funktion zum Konvertieren von Leerzeichen( schluessel );

// Erstelle Liste
_liste.push_back( schluessel, wert );
old_pos = pos + 1;
}

}

void Antworte( Liste& _liste )
{
cout << "Content-Type: text/html" << endl;
cout << endl;
cout << "<html><title>C++ Beispiel CGI GET/POST Beispiel</title>" << endl;
cout << "<head>" << endl;
cout << "<body><h2>Ausgabe</h2>" << endl;

ListElement* tmp;
for( tmp = _liste.front(); tmp != 0; tmp = tmp->naechstes ) {
cout << "<p><b>" << tmp->schluessel << "</b>" << tmp->wert << "</p>" << endl;
}

cout << "</body>" << endl;
cout << "</head>" << endl;
cout << "</html>" << endl;
}


int main()
{
Liste liste;

if ( Anfrage( liste ) == false ) {
cout << "Content-Type: text/html" << endl;
cout << endl;
cout << "<html><title>C++ Beispiel CGI GET/POST Beispiel</title>" << endl;
cout << "</head><body>Keine Anfrage erhalten!" << endl;
cout << "</body>" << endl;
cout << "</head>" << endl;
cout << "</html>" << endl;
} else
Antworte( liste );

return EXIT_SUCCESS;
}

In C++ hat man auch str.find(), etc.

int strcnt(const char* haystack, const char* needle)
{
std::string h(haystack);
std::string n(needle);
unsigned long plen = n.length();
unsigned long f = 0;
unsigned long found = 0;
while((f = h.find(n,f)) != std::string::npos) {
f = f + plen;
found++;
}
return found;
}

Ich will aber mehr C lernen, darum will ich das in C machen.

Gibts irgendwas was einen substring von Position 10 bis Position 20 z.B. holt? ich kenn nur das mit str[20]='\0';, aber ich brauch den string nicht von anfang an

Giuly
07-11-2005, 14:44
Das Problem lag garnicht bei der Funktion, die geht nun.

Ich muss jetzt nurnoch aus einer Datei eine Zeile in ein char* einlesen. fscanf(FILE*, "%s\n%s", char*, char*); geht nicht, wie macht mans richtig?

2xfgets und alles wird gut :)