send http requests in the same session with curl - php

I am developing my first application in PHP using Curl. The purpose of this application is to develop an HTTP client which sends data to the server.
The server listens to port 10000 on # 192.168.1.110.
This is the server code:
<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$address = '192.168.1.110';
$port = 10000;
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
echo "socket_create() falló: razón: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
echo "socket_bind() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
echo "socket_listen() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
}
//clients array
$clients = array();
do {
$read = array();
$read[] = $sock;
$write = NULL;
$except = NULL;
$read = array_merge($read,$clients);
// Set up a blocking call to socket_select
if(socket_select($read,$write, $except, $tv_sec = 5) < 1)
{
continue;
}
// Handle new Connections
if (in_array($sock, $read)) {
if (($msgsock = socket_accept($sock)) === false) {
echo "socket_accept() fail: " . socket_strerror(socket_last_error($sock)) . "\n";
break;
}
$clients[] = $msgsock;
$key = array_keys($clients, $msgsock);
/* Enviar instrucciones. */
$msg = "HTTP/1.1 100 Continue \n";
socket_write($msgsock, $msg, strlen($msg));
}
// Handle Input
foreach ($clients as $key => $client) { // for each client
if (in_array($client, $read)) {
if (false === ($buf = socket_read($client, 4096))) {
echo "socket_read() falló: razón: " . socket_strerror(socket_last_error($client)) . "\n";
break 2;
}
if (!$buf = trim($buf)) {
continue;
}
echo "$buf\n";
$talkback = "Client {$key}: msg '$buf'.\n";
socket_write($client, $talkback, strlen($talkback));
//echo "$buf\n";
}
}
} while (true);
socket_close($sock);
And this is the HTTP client's source code:
<?php
$url = 'http://192.168.1.110:10000';
$fields_string = "A";
$fields = array(
'SERIAL_NUMBER ' => urlencode('123456'),
'HARDWARE_ID ' => urlencode('455FFG'),
'CODE ' => urlencode('99'),
//field goes here
);
foreach($fields as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');
$ch = curl_init("http://192.168.1.110:10000");
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
crl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$output = curl_exec($ch);
echo $output;
curl_setopt($ch,CURLOPT_POSTFIELDS,'test second session !!!!!');
$output = curl_exec($ch);
echo $output;
curl_close($ch);
When I execute this application (client/server), I got this output:
HTTP/1.1 100 Continue
Client 16: msg 'POST / HTTP/1.1
Host: 192.168.1.110:10000
Accept: */*
Content-Length: 52
Content-Type: application/x-www-form-urlencoded
ASERIAL_NUMBER =123456&HARDWARE_ID =455FFG&CODE =99&1HTTP/1.1 100 Continue
Client 17: msg 'POST / HTTP/1.1
Host: 192.168.1.110:10000
Accept: */*
Content-Length: 25
Content-Type: application/x-www-form-urlencoded
test second session !!!!!
The problem is that the HTTP client doesn't send the data in the same session, the client number was incremented [Client 16, Client 17]!!
How to send the data in the same session using Curl?

The session is stored in the cookie of your browser:
When you make a server-side Curl request (like in your PHP code) that cookie isn't being replicated.
What you need to do is tell Curl to include a cookie header. You get the current cookie from the $_COOKIE array and place it into headers that you send along with the Curl request.
$headers = array();
// Add cookies to headers, if they're present
if( isset($_COOKIE) === true
&& is_array($_COOKIE) === true
&& sizeof($_COOKIE) > 0
) {
$cookie_header = "Cookie:";
// Concatenate each cookie key and value like "key=value"
foreach($_COOKIE as $k=>$v) {
$cookie_header .= " ".safestring($k)."=".safestring($v).";";
}
$headers[] = $cookie_header;
}
// Add headers to request, if they're present
if(sizeof($headers) > 0) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}

Related

(PHP) tcp socket over proxy

I connect to the Minecraft server via tcp, how do I use a proxy server
I know how to use a proxy for HTTP requests, but I don’t really understand how to do it for TCP
$data = "\x00";
$data .= makeVarInt($proto);
$data .= pack('c', strlen($ip)) . $ip;
$data .= pack('n', $port);
$data .= "\x02";
$handshake = pack('c', strlen($data)) . $data;
$nick = generateRandomString(5)."_RAGE_". generateRandomString(5);
//Create TCP socket
$socket = #stream_socket_client("tcp://$ip:$port", $errno, $errstr, 10);
//Check for errors
if ($errno > 0) {
echo "ERROR: " . $errstr . PHP_EOL;
continue;
}
//Send login handshake packet
fwrite($socket, $handshake);
//Make login start packet
$data = "\x00";
$data .= pack('c', strlen($nick)) . $nick;
$data = pack('c', strlen($data)) . $data;
//Send login start packet
fwrite($socket, $data);

Paypal ipn return 403 in the last month with php code

In the last month my patpal integration return error, i think that something change in the policy of paypal. this is the error:
[08/12/2021 11:59 AM] - FAIL: IPN Validation Failed.
IPN Response from Paypal Server:
HTTP/1.1 403 Forbidden
Content-Type: text/html
Content-Length: 38
Connection: close
DC: phx-origin-www-1.paypal.com
Strict-Transport-Security: max-age=31536000; includeSubDomains
<html><body>403 Forbidde</body></html>
its started in the last month.
this is the api url that i using:
https://api-3t.paypal.com/nvp
and this is the paypal class
<?php
class paypal_class {
var $last_error; // holds the last error encountered
var $ipn_log; // bool: log IPN results to text file?
var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN
var $fields = array(); // array holds the fields to submit to paypal
function __construct() {
// initialization constructor. Called when class is created.
$this->paypal_url = 'https://ipnpb.paypal.com/cgi-bin/webscr';
$this->api_url = 'https://api-3t.paypal.com/nvp';
$this->last_error = '';
$this->ipn_log_file = 'ipn_log.txt';
$this->ipn_log = true;
$this->ipn_response = '';
// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
// Return method = POST
$this->add_field('cmd', '_cart');
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function submit_paypal_post($type = false) {
// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the
// BODY element's onLoad attribute. We do this so that you can validate
// any POST vars from you custom form before submitting to paypal. So
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.
// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.
$form = array();
$output = "<html>\n";
$output .= "<head><title>טוען תשלום...</title></head>\n";
$output .= "<body onLoad=\"document.form.submit();\">\n";
$output .= "<form method=\"post\" name=\"form\" action=\"" . $this->paypal_url . "\">\n";
foreach ($this->fields as $name => $value) {
$output .= "<input type=\"hidden\" name=\"$name\" value=\"$value\">";
$form[] = array(
"name" => $name,
"value" => $value,
"type" => "hidden"
);
}
$output .= "</form>\n";
$output .= "</body></html>\n";
if ($type)
return array("form" => $form, "action" => $this->paypal_url);
return $output;
}
function validate_ipn() {
// parse the paypal URL
$url_parsed = parse_url($this->paypal_url);
// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = '';
foreach ($_POST as $field => $value) {
$this->ipn_data[$field] = $value;
$post_string .= $field . '=' . urlencode($value) . '&';
}
$post_string.="cmd=_notify-validate"; // append ipn command
// open the connection to paypal
$fp = fsockopen("ssl://" . $url_parsed["host"], 443, $err_num, $err_str, 30);
if (!$fp) {
$this->last_error = "fsockopen error no. $errnum: $errstr";
$this->log_ipn_results(false);
return false;
} else {
// Post the data back to paypal
fputs($fp, "POST {$url_parsed["path"]} HTTP/1.1\r\n");
fputs($fp, "Host: {$url_parsed["host"]}\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: " . strlen($post_string) . "\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");
// loop through the response from the server and append to variable
while (!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024);
}
fclose($fp); // close connection
}
if (preg_match("/VERIFIED/i", $this->ipn_response)) {
// Valid IPN transaction.
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log)
return; // is logging turned off?
// Timestamp
$text = '[' . date('m/d/Y g:i A') . '] - ';
// Success or failure being logged?
if ($success)
$text .= "SUCCESS!\n";
else
$text .= 'FAIL: ' . $this->last_error . "\n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key => $value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n " . $this->ipn_response;
// Write to log
$fp = fopen($this->ipn_log_file, 'a');
fwrite($fp, $text . "\n\n");
fclose($fp); // close file
}
function dump_fields() {
// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.
echo "<h3>paypal_class->dump_fields() Output:</h3>";
echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
<tr>
<td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
<td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>
</tr>";
ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "<tr><td>$key</td><td>" . urldecode($value) . " </td></tr>";
}
echo "</table><br>";
}
public function pay($username, $password, $signature, $email, $amount, $note = "Instant Payment") {
$version = urlencode("51.0");
$api = $this->api_url;
$type = urlencode("EmailAddress");
$currency = urlencode("USD");
$subject = urlencode("Instant Paypal Payment");
$string = "&EMAILSUBJECT=" . $subject . "&RECEIVERTYPE=" . $type . "&CURRENCYCODE=" . $currency;
$string .= "&L_EMAIL0=" . urlencode($email) . "&L_Amt0=" . urlencode($amount) . "&L_NOTE0=" . urlencode($note);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$request = "METHOD=MassPay&VERSION=" . $version . "&PWD=" . $password . "&USER=" . $username . "&SIGNATURE=" . $signature . "$string";
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
$httpResponse = curl_exec($ch);
if (!$httpResponse) {
exit("MassPay failed: " . curl_error($ch) . '(' . curl_errno($ch) . ')');
}
$httpResponseArray = explode("&", $httpResponse);
$httpParsedResponse = array();
foreach ($httpResponseArray as $i => $value) {
$tempArray = explode("=", $value);
if (sizeof($tempArray) > 1) {
$httpParsedResponse[$tempArray[0]] = $tempArray[1];
}
}
if ((0 == sizeof($httpParsedResponse)) || !array_key_exists('ACK', $httpParsedResponse)) {
exit("Invalid HTTP Response for POST request($request) to " . $api);
}
return $httpParsedResponse;
}
}
what can i do?
i tried to search in google any policy update but no luck.
tnx
As mentioned in the IPN Integration Guide, ensure you include a User-Agent: field in your request headers, with a value that's any string > 7 characters or so
For live IPN verification, you should also use the domain ipnpb.paypal.com rather than www.paypal.com

PHP Cache issue when posting data using fsockopen

I am using Mailchimp api 1.3 php wrapper. The problem is that a server where my customer hosts a site will cache response, it won't even make api call. The exact the same code works with me and other customers:
$api = new MCAPI($apiKey);
$doubleOptin = false;
$mergeVar = array(
'FNAME' => '',
'LNAME' => ''
);
$api->listSubscribe($listId, $email, $mergeVar, 'html', $doubleOptin);
print_r($api);
method listSubscribe() calls method callServer where I guess is the problem:
$payload = "POST " . $this->apiUrl["path"] . "?" . $this->apiUrl["query"] . "&method=" . $method . " HTTP/1.0\r\n";
$payload .= "Host: " . $host . "\r\n";
$payload .= "User-Agent: MCAPI/" . $this->version ."\r\n";
$payload .= "Content-type: application/x-www-form-urlencoded\r\n";
$payload .= "Content-length: " . strlen($post_vars) . "\r\n";
$payload .= "Connection: close \r\n\r\n";
$payload .= $post_vars;
ob_start();
if ($this->secure){
$sock = fsockopen("ssl://".$host, 443, $errno, $errstr, 30);
} else {
$sock = fsockopen($host, 80, $errno, $errstr, 30);
}
if(!$sock) {
$this->errorMessage = "Could not connect (ERR $errno: $errstr)";
$this->errorCode = "-99";
ob_end_clean();
return false;
}
$response = "";
fwrite($sock, $payload);
stream_set_timeout($sock, $this->timeout);
$info = stream_get_meta_data($sock);
while ((!feof($sock)) && (!$info["timed_out"])) {
$response .= fread($sock, $this->chunkSize);
$info = stream_get_meta_data($sock);
}
var_dump($response); exit;
Does anybody have any idea why fsockopen and fwrite never sends call to Mailchimp? Weird thing is that I can actually read $response, but it is always the same from cache.
If the code works for you and there is some query caching then you could try to add a timestamp to the request.
"&time=".time()
This way you always have a "fresh" request.

PayPal IPN Listener works inside sandbox but not outside

I am running this PayPal IPN listener written by tutsplus, it's modified a bit to suit my needs. Everything worked fine until I have moved from sandbox to live mode. I have went over the code, and don't quite understand if I need to switch anything or it is checking for sandbox/live itself.
<?php
class PayPal_IPN{
function infotuts_ipn($im_debut_ipn) {
define('SSL_P_URL', 'https://www.paypal.com/cgi-bin/webscr');
define('SSL_SAND_URL', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if (!preg_match('/paypal\.com$/', $hostname)) {
$ipn_status = 'Validation post isn\'t from PayPal';
if ($im_debut_ipn == true) {
// mail test
}
return false;
}
// parse the paypal URL
$paypal_url = ($_REQUEST['test_ipn'] == 1) ? SSL_SAND_URL : SSL_P_URL;
$url_parsed = parse_url($paypal_url);
$post_string = '';
foreach ($_REQUEST as $field => $value) {
$post_string .= $field . '=' . urlencode(stripslashes($value)) . '&';
}
$post_string.="cmd=_notify-validate"; // append ipn command
// get the correct paypal url to post request to
$paypal_mode_status = $im_debut_ipn; //get_option('im_sabdbox_mode');
if ($paypal_mode_status == true)
$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
else
$fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60);
$ipn_response = '';
if (!$fp) {
// could not open the connection. If loggin is on, the error message
// will be in the log.
$ipn_status = "fsockopen error no. $err_num: $err_str";
if ($im_debut_ipn == true) {
echo 'fsockopen fail';
}
return false;
} else {
// Post the data back to paypal
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
fputs($fp, "Host: $url_parsed[host]\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: " . strlen($post_string) . "\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");
// loop through the response from the server and append to variable
while (!feof($fp)) {
$ipn_response .= fgets($fp, 1024);
}
fclose($fp); // close connection
}
// Invalid IPN transaction. Check the $ipn_status and log for details.
if (!preg_match("/VERIFIED/s", $ipn_response)) {
$ipn_status = 'IPN Validation Failed';
if ($im_debut_ipn == true) {
echo 'Validation fail';
print_r($_REQUEST);
}
return false;
} else {
$ipn_status = "IPN VERIFIED";
if ($im_debut_ipn == true) {
echo 'SUCCESS';
}
return true;
}
}
function ipn_response($request){
mail("mssoad#gmail.com","My subject",print_r($request,true));
$im_debut_ipn=true;
if ($this->infotuts_ipn($im_debut_ipn)) {
// if paypal sends a response code back let's handle it
if ($im_debut_ipn == true) {
$sub = 'PayPal IPN Debug Email Main';
$msg = print_r($request, true);
$aname = 'infotuts';
//mail send
}
// process the membership since paypal gave us a valid +
$this->insert_data($request);
}
}
function issetCheck($post,$key){
if(isset($post[$key])){
$return=$post[$key];
}
else{
$return='';
}
return $return;
}
function insert_data($request){
require_once('dbconnect.php');
$post=$request;
$item_name=$this->issetCheck($post,'item_name');
$amount=$this->issetCheck($post,'mc_gross');
$currency=$this->issetCheck($post,'mc_currency');
$payer_email=$this->issetCheck($post,'payer_email');
$first_name=$this->issetCheck($post,'first_name');
$last_name=$this->issetCheck($post,'last_name');
$country=$this->issetCheck($post,'residence_country');
$txn_id=$this->issetCheck($post,'txn_id');
$txn_type=$this->issetCheck($post,'txn_type');
$payment_status=$this->issetCheck($post,'payment_status');
$payment_type=$this->issetCheck($post,'payment_type');
$payer_id=$this->issetCheck($post,'payer_id');
$date=$this->issetCheck($post,'custom');
$create_date=date('Y-m-d H:i:s');
$payment_date=date('Y-m-d H:i:s');
$firstLast = $first_name . $last_name;
$explode = explode('|', $item_name);
foreach($explode as $slot) {
if(strlen($slot) > 0) {
$query = "INSERT INTO bookings (date, start, name, email, phone, order_id) VALUES ('$date', '$slot', '$firstLast', '$payer_email', '$phone', '$orderid')";
$result = mysqli_query($con, $query) or die(mysqli_error($link));
} // Close if
} // Close foreach
mysqli_query($con,"INSERT INTO trans_tbl (item_name,ride_day,payer_email,first_name,last_name,amount,currency,country,txn_id,txn_type,payer_id,payment_status,payment_type,create_date,payment_date)
VALUES ('$item_name','$date','$payer_email','$first_name','$last_name','$amount','$currency','$country','$txn_id','$txn_type','$payer_id','$payment_status','$payment_type','$create_date','$payment_date')");
mysqli_close($con);
}
}
$obj = New PayPal_IPN();
$obj->ipn_response($_REQUEST);
?>
On the IPN History of the paypal website it is stuck at sent - resending.
I have setup IPN settings and notify URL in profile settings, and have a business account. My email is verified on the account as well.
Another thing to note, I have been doing simple $0.01 to test this outside sandbox mode, and the return page is working fine just not the ipn listener.
Any help is much appreciated, thanks.
$paypal_mode_status = $im_debut_ipn; //get_option('im_sabdbox_mode');
if ($paypal_mode_status == true)
$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
else
$fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60);
Could be incorrect, you should test to confirm, but I think it's because your $im_debut_ipn variable, when set to TRUE, is not only "debugging" but for some reason is also being used to determine the paypal url. It then sets the url to be paypals sandbox url (see above).
i.e, When
$im_debut_ipn = true
then,
$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60);
is also true.
Note that I think $im_debut_ipn is actually a typo and should be ..debug.., meaning a debug mode that lets error messages be shown.

How to send SMS on multiple numbers stored in database

This is my code and I am using as external file include in my code as external file. When new user post this code is run but not sent message on all numbers that stored in database:
Error is:
Warning: fsockopen() [function.fsockopen]: unable to connect to :0
(Failed to parse address "") in C:\xampp\htdocs\funsmss\location\sendsms.php
Failed to parse address "" (0)
Here's the code:
<?php
$sql = "select * from subscribe where type ='$cat' and city ='$city'";
$query = mysql_query($sql);
if ($query != null) {
while ($row = mysql_fetch_array($query)) {
$name = $row['name'];
$phoneNum = $row['fone'];
$message = "Hi ".$name.", now you can buy your product.";
ozekiSend($phoneNum, $message);
// for debugging, try the following line
//echo ozekiSend($phoneNum, $message, true);
}
}
########################################################
# Login information for the SMS Gateway
########################################################
$ozeki_user = "admin";
$ozeki_password = "abc123";
$ozeki_url = "http://127.0.0.1:9501/api?";
########################################################
# Functions used to send the SMS message
########################################################
function httpRequest($url)
{
$pattern = "/http...([0-9a-zA-Z-.]*).([0-9]*).(.*)/";
preg_match($pattern, $url, $args);
$in = "";
$fp = fsockopen("$args[1]", $args[2], $errno, $errstr, 30);
if (!$fp) {
return("$errstr ($errno)");
} else {
$out = "GET /$args[3] HTTP/1.1\r\n";
$out .= "Host: $args[1]:$args[2]\r\n";
$out .= "User-agent: Ozeki PHP client\r\n";
$out .= "Accept: */*\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
$in.=fgets($fp, 128);
}
}
fclose($fp);
return($in);
}
function ozekiSend($phone, $msg, $debug = false)
{
global $ozeki_user, $ozeki_password, $ozeki_url;
$url = 'username=' . $ozeki_user;
$url.= '&password=' . $ozeki_password;
$url.= '&action=sendmessage';
$url.= '&messagetype=SMS:TEXT';
$url.= '&recipient=' . urlencode($phone);
$url.= '&messagedata=' . urlencode($msg);
$urltouse = $ozeki_url . $url;
if ($debug === true) {
echo "Request: <br>$urltouse<br><br>";
}
//Open the URL to send the message
$response = httpRequest($urltouse);
if ($debug === true) {
echo "Response: <br><pre>" .
str_replace(array("<", ">"), array("<", ">"), $response) .
"</pre><br>";
}
return($response);
}
?>

Categories