I am trying to send data from a winsock application to a PHP script. I have already tried various header types without any success and I can't seem to find enough information.
Data is sent, but the PHP script is not printing any results, so I think the error is headers types.
C Winsock code
int main()
{
SOCKADDR_IN sock;
SOCKET s;
WSADATA wsa;
int lengthofrequest = 0;
char httprequest[180] =
"POST /test.php?name=alex&password=secret HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"Pragma: no-cache\r\n"
"Content-type: text/html\r\n"
"Connection: close\r\n"
"Content-Length: 25\r\n"
"\r\n";
lengthofrequest = strlen(httprequest);
// init winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return WSASYSNOTREADY;
sock.sin_addr.s_addr = inet_addr("127.0.0.1");
sock.sin_family = AF_INET;
sock.sin_port = htons(80);
// create socket
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
return 1;
// connect to the http panel
int conn = connect(s, (SOCKADDR*)&sock, sizeof(sock));
if (conn < 0)
return 1;
// send http header
send(s, httprequest, lengthofrequest, 0);
// close socket
closesocket(s);
WSACleanup();
return 0;
}
PHP script
<?php
if(isset($_POST['name'], $_POST['password']))
{
echo $_POST['name'];
echo $_POST['password'];
}
?>
I would appreciate any help or guidance. Thanks.
You are mixing post and get
Use $_GET to access your data because your data is appended to the url
Try this:
<?php
if(isset($_GET['name'], $_GET['password']))
{
echo $_GET['name'];
echo $_GET['password'];
}
this should work but you should consider changing your request type to GET in the C code as well to make your code clear and simple
What you are doin here is ambiguous:
"POST /test.php?name=alex&password=secret HTTP/1.1\r\n"
Because you are sending get parameters using post and the post body is actually empty.
Also you should omit ?> at the end of your php script.
Related
While I'm trying to send a GET request to an address with php I receive HTTP 400 BAD REQUEST message and I can't figure out why.
Here's my code:
function redirect($url)
{
error_reporting(E_ERROR | E_PARSE);
$components = parse_url($url);
$port = $components["port"];
$ip = $components["host"];
$path = $components["path"];
//create and connect socket with the parameters entered by the user
//$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
echo "Establishing connection to the given adress...\n";
//Connection timeout limit is set to 10 seconds...
if(!isset($port))
{
$port = 80;
}
$sock = fsockopen($ip, $port,$errno, $errstr, 10) or die("Unable to connect...");
$request = "GET $path HTTP/1.1" . "\r\n\r\n";
fwrite($sock, $request);
while ($header = stream_get_line($sock, 1024, "\r\n")) {
$response.= $header . "\n";
}
echo $response;
$loc = "";
if (preg_match("/Location:\'(.*)\\n/", $response, $results))
$loc = $results[1];
echo $loc;
}
Any suggestions?
A GET request also contains a header wich include things like the useragent oder the encoding, you should have a look at what you need to send and what's optional
For this specific problem I've found a solution. If you want to get the headers from the request that I sent in the question above, you can use php's get_headers($url) method. It retrieves the headers that I was looking for. I'm really new to protocols and web-services and also to php (1 or 1.5 weeks), therefore I may have asked a silly question and not have been specific enough. Anyways thank you very much for your answers.
Have a nice day!
I'm new to php and I need to receive data from a socket in order to parse the song title from a given IP. In order to learn and test sockets I first tried to connect and receive data from the given IP.
Here's my code:
#!/usr/bin/php -q
<?php
//$sock = fsockopen('205.164.35.5:80');
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
$result = socket_connect($sock, "205.164.35.5", 80);
$request = "GET / HTTP/1.1\r\n";
$request .= "Icy-MetaData: 1\r\n";
socket_write($sock,$request,strlen($request));
echo "OK";
$out = " ";
while($out = socket_read($sock,2048)){
echo $out;
}
socket_close($sock);
?>
When I run it from the terminal it does not generate any errors, however it displays nothing. I tried to connect to that ip with "telnet" command and sent the same request and on the terminal I had a response. Any kind of help would be really appreciated.
Thank you...
You should terminate the request with two CRLFs:
- $request .= "Icy-MetaData: 1\r\n";
+ $request .= "Icy-MetaData: 1\r\n\r\n";
Hope it helps.
I tried to create a Websocket Server in PHP which uses the current WebSocket Protocol 13.
I implemented the header creation according to the RFC but in Google Chrome (Version 31) it still fails with the Error message Error during WebSocket handshake: Sec-WebSocket-Accept mismatch. Firefox shows at least the response but it also doesn't fire the clientside onOpen Event.
Below is a minimal testserver in PHP with the code I use to create the header:
<?php
$srv = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($srv, '0.0.0.0', 50500);
socket_listen($srv, 10);
for(;;){
$sock = socket_accept($srv);
// get header
$header = socket_read($sock, 1024);
// extract key
$keys = array();
preg_match_all("/Sec-WebSocket-Key:\s*(.*)\s*/", $header, $keys);
if(count($keys) < 1){
// Not a valid Websocket Handshake
socket_close($sock);
continue;
}
// create hash according to RFC
$key = $keys[1][0];
$accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
// create header
$h = "HTTP/1.1 101 Switching Protocols\r\n";
$h .= "Upgrade: websocket\r\n";
$h .= "Connection: Upgrade\r\n";
$h .= "Sec-WebSocket-Accept: $accept\r\n";
$h .= "Sec-WebSocket-Protocol: 13\r\n\r\n";
echo $h;
// send header to client
socket_write($sock,$h,strlen($h));
}
?>
Am I missing something here?
Thanks in advance!
The regexp /Sec-WebSocket-Key:\s*(.*)\s*/ will include the \r characters in the matched content (the . matches \r but not \n) so your $key variable will have the wrong value. You need to figure out a regexp that matches everything but the \r\n sequence at the end.
Also, the server should only include the Sec-WebSocket-Protocol attribute if the client included it in the request, and the value must be one of the protocols requested in the client Sec-WebSocket-Protocol attribute. Otherwise the client will give an error, see RFC 6455.
I am trying to convert this code snippet from PHP to Python (programming newbie) and am finding difficulty in doing so:
The PHP that I am trying to convert is as follows:
$fp = fsockopen($whmcsurl, 80, $errno, $errstr, 5);
if ($fp) {
$querystring = "";
foreach ($postfields AS $k=>$v) {
$querystring .= "$k=".urlencode($v)."&";
}
$header="POST ".$whmcsurl."modules/servers/licensing/verify.php HTTP/1.0\r\n";
$header.="Host: ".$whmcsurl."\r\n";
$header.="Content-type: application/x-www-form-urlencoded\r\n";
$header.="Content-length: ".#strlen($querystring)."\r\n";
$header.="Connection: close\r\n\r\n";
$header.=$querystring;
$data="";
#stream_set_timeout($fp, 20);
#fputs($fp, $header);
$status = #socket_get_status($fp);
while (!#feof($fp)&&$status) {
$data .= #fgets($fp, 1024);
$status = #socket_get_status($fp);
}
#fclose ($fp);
}
It corresponding Python code that I wrote is as follows:
fp = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
fp.connect(("my ip", 80))
if (fp):
querystring = ""
#print postfields
for key in postfields:
querystring = querystring+key+"="+urllib.quote(str(postfields[key]))+"&"
header = "POST "+whmcsurl+"modules/servers/licensing/verify.php HTTP/1.0\r\n"
header+="Content-type: application/x-www-form-urlencoded\r\n"
header+="Content-length: "+str(len(querystring))+"\r\n"
header+="Connection: close\r\n\r\n"
#header+=querystring
data=""
request = urllib2.Request(whmcsurl,querystring,header)
response = urllib2.urlopen(request)
data = response.read()
Here, I am faced with the following error:
request = urllib2.Request(whmcsurl,querystring,header)
File "/usr/lib64/python2.6/urllib2.py", line 200, in __init__
for key, value in headers.items():
AttributeError: 'str' object has no attribute 'items'
So I am guessing that Python is expecting a dictionary for the header. But the PHP sends it as a string.
May I know how to solve this issue?
Thanks in advance
You are overcomplicating things, by quite some distance. Python takes care of most of this for you. There is no need to open a socket yourself, nor do you need to build headers and the HTTP opening line.
Use the urllib.request and urllib.parse modules to do the work for you:
from urllib.parse import urlopen
from urllib.request import urlopen
params = urlencode(postfields)
url = whmcsurl + 'modules/servers/licensing/verify.php'
response = urlopen(url, params)
data = response.read()
urlopen() takes a second parameter, the data to be sent in a POST request; the library takes care of calculating the length of the body, and sets the appropriate headers. Most of all, under the hood it uses another library, httplib, to take care of the socket connection and producing valid headers and a HTTP request line.
The POST body is encoded using urllib.parse.urlencode(), which also takes care of proper quoting for you.
You may also want to look into the external requests library, which provides an easier-to-use API still:
import requests
response = requests.post(whmcsurl + 'modules/servers/licensing/verify.php', params=params)
data = response.content # or response.text for decoded content, or response.json(), etc.
your headers should look like this
headers = { "Content-type" : "application/x-www-form-urlencoded" };
I am kinda new to PHP however I used JSP a lot before (I have quite information) and everything was easier with Java classes.
So, now, I want to perform a POST request on a HTTPS page (not HTTP) and need to get returned cookies and past it to another GET request and return the final result. Aim is to make a heavy page for mobile phones more compatible to view in a mobile browser by bypassing the login page and directly taking to the pages which are also served in an ajax user interface.
I am stuck, my code does not work, it says it is Bad Request.
Bad Request
Your browser sent a request that this
server could not understand. Reason:
You're speaking plain HTTP to an
SSL-enabled server port. Instead use
the HTTPS scheme to access this URL,
please.
<?php
$content = '';
$flag = false;
$post_query = 'SOME QUERY'; // name-value pairs
$post_query = urlencode($post_query) . "\r\n";
$host = 'HOST';
$path = 'PATH';
$fp = fsockopen($host, '443');
if ($fp) {
fputs($fp, "POST $path HTTP/1.0\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-length: ". strlen($post_query) ."\r\n\r\n");
fputs($fp, $post_query);
while (!feof($fp)) {
$line = fgets($fp, 10240);
if ($flag) {
$content .= $line;
} else {
$headers .= $line;
if (strlen(trim($line)) == 0) {
$flag = true;
}
}
}
fclose($fp);
}
echo $headers;
echo $content;
?>
From past experience, I've never used PHP's internal functions like fsocketopen() for external data posting. The best way to do these actions are using CURL, which gives much more ease and is massively more powerful for developers to leverage.
for example, look at these functions
http://php.net/curl_setopt
and look at the one with URL, POST, POSTDATA, and COOKIESFILES which is for .JAR, which you get then retrieve and that you can use file_get_contents() to send the data using GET.