PDA

Visualizza la versione completa : [C++] POST via socket a pagina PHP


a145
16-04-2018, 16:34
Salve sto provando ad inviare dati ad uno script php

la creazione della socket e la connessione col server funziona,
il problema sono i dati che invio, perche come risposta ottengo:


HTTP/1.1 400 Bad RequestDate: Mon, 16 Apr 2018 14:03:37 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1


<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>


qui i dati che invio


string pHeader;
string varPHP1 = "user-name=name";
string varPHP2 = "&user-password=pass";
string FormAction = "/folder/file.php";
int ContentLength = varPHP1.length() + varPHP2.length();
pHeader += "POST / HTTP/1.1\r\n";
pHeader += FormAction + "\r\n";
pHeader += varPHP1 + varPHP2 + "\r\n";
pHeader += "Host: " + host + "\r\n";
pHeader += "Content-Type: application/x-www-form-urlencoded\r\n";
pHeader += "User-Agent: test\r\n";
pHeader += "Content-Length: " + to_string(ContentLength) + "\r\n\r\n";


qualcuno sa dirmi dov' che sbaglio?

a145
16-04-2018, 22:46
col metodo GET ci sono riuscito ed essendo mia la pagina php che vado a visitare ho cambiato POST in GET pero vorrei riuscire a farlo anche col POST metto il codice che sto usando per chi interessato, l'ho provato su window 7 e su debian e urka come vuorka :)

tcpclient.h


#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#endif
#include <iostream>
#include <string>

class tcpClient {
private:
int sock;
std::string address;
int port;
struct sockaddr_in server;

public:
tcpClient();
~tcpClient();
bool conn(std::string, int);
bool send_data(std::string);
std::string receive(int);
std::string get(std::string, std::string);
//std::string post(std::string, std::string);
};

#endif



tcpclient.cpp


#include "tcpclient.h"

tcpClient::tcpClient() {
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
return;
}
#endif
sock = -1;
port = 0;
address = "";
}

tcpClient::~tcpClient() {
#ifdef _WIN32
WSACleanup();
#endif
}

bool tcpClient::conn(std::string address , int port) {
if(sock == -1) {
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1) {
return false;
}
}
if(inet_addr(address.c_str()) == -1) {
struct hostent *he;
struct in_addr **addr_list;
if ( (he = gethostbyname( address.c_str() ) ) == NULL) {
return false;
}
addr_list = (struct in_addr **) he->h_addr_list;

for(int i = 0; addr_list[i] != NULL; i++) {
server.sin_addr = *addr_list[i];
break;
}
} else {
server.sin_addr.s_addr = inet_addr( address.c_str() );
}
server.sin_family = AF_INET;
server.sin_port = htons( port );
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) {
return false;
}
return true;
}

bool tcpClient::send_data(std::string data) {
if( send(sock , data.c_str() , strlen( data.c_str() ) , 0) > 0) {
return true;
}
}

std::string tcpClient::receive(int bSize=512) {
char buffer[bSize];
std::string reply;
if( recv(sock , buffer , sizeof(buffer) , 0) > 0) {
reply = buffer;
return reply;
}
}

std::string extract_body(std::string str) {
int pos = str.find_last_of("\r\n\r\n");
return str.substr(pos);
}

std::string tcpClient::get(std::string url, std::string page) {
std::string pHeader;
pHeader += "GET /" + page + " HTTP/1.1\r\n";
pHeader += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
pHeader += "Accept-Encoding: gzip, deflate\r\n";
pHeader += "Accept-Language: en-US,en;q=0.5";
pHeader += "Connection: keep-alive\r\n";
pHeader += "Host: " + url +"\r\n";
pHeader += "Upgrade-Insecure-Requests: 1\r\n";
pHeader += "User-Agent: test\r\n\r\n";
if (conn(url, 80) && (send_data(pHeader))) {
return extract_body(receive(1024));
}
}




main.cpp


#include "tcpclient.h"
#include <iostream>
#include <string>

int main() {
tcpClient c;
std::string host = "www.sito.it";
std::string request = "prova.php?user-name=nome&user-password=pass";
std::cout << c.get(host, request);
return 0;
}



su window solo serve -lws2_32


>g++ tcpclient.cpp main.cpp -lws2_32 -o nomefile



sul debian invece mi da problemi strlen ho dovuto aggiungere anche string.h


>g++ tcpclient.cpp main.cpp -o nomefile



spero che qualcuno pratico si faccia avanti e mi spiega come fare per il metodo POST e magari anche qualche consiglio su come l'avrebbe impostata lui questa classe
ad esempio extract_body una funzione friend se cosi la vogliamo chiamare.. non l'ho messa nella classe o forse dovevo metterla tra i metodi privati..

prova.php per completezza


<?php
$browser = $_SERVER['HTTP_USER_AGENT'];
if(preg_match('/PersonalAgent/i',$browser)) {
if (count($_GET) > 0) {
$userName = trim(filter_var($_GET['user-name'], FILTER_SANITIZE_STRING));
$userPassword = trim(filter_var($_GET['user-password'], FILTER_SANITIZE_STRING));


echo $userName . ", " . $userPassword;
} else { echo "no get"; }
} else { echo "no agent"; }
?>



P.S.: ho postato tutto quanto anche per presentarmi e per dirvi che non sono uno di quelli che rompe le scatole che vuole che le cose glie le facciate voi.. se chiedo aiuto vuol dire che ho googlato fino allo stremo

linoma
17-04-2018, 10:23
sbagliata il formato della richiesta HTTP i dati vanno dopo la richiesta.

a145
18-04-2018, 13:24
e al contentLength va aggiunto +1 perche ci mette il carattere di fine stringa, pero ancora non va..
ho trovato questo https://github.com/shihyu/Linux_Programming/blob/master/books/UNIX%20Network%20Programming(Volume1%2C3rd).pdf
mo me lo studio poi tornero a metterci le mani..

Loading