Solved

Emulate Submit Button After Server-Side Form Validation to Redirect Page to External SSL Site

Posted on 2007-04-09
7
235 Views
Last Modified: 2010-05-18
I've been having a tough time figuring out this problem and could really use some help. I've got a page that verifies user form input server side, but then I need to submit the entire page, including the verified form data as a POST to an external SSL page to which I have no access. Basically, after checking the entered form data I want to 'resubmit' the page to an external site. Can anyone help me?

I've pasted my code to date below, but the below code only posts the header data, not the page itself AND the form data.

Example: http://www.ericcovarrubias.com/validation6.php 


<?


// Here is the function with SSL and header redirection properly set up!  (fully commented for those who are unaccustomed to this stuff)
// You can add the $dataStream aurgument back into the function, but if you do, change "$_POST" to "$dataStream" in the first foreach line.
// I took $dataStream out because I always use the $_POST data

function post_it($url)
{
  $saveurl = $url;  // Here we save the original $url because it will be altered in the next line and we wouldn't be able to use it like we need to later
 
  $url  = preg_replace("@^https://@i", "", $url);  // $url getting altered here so we saved it in the previous line
  $host = substr($url, 0, strpos($url, "/"));
  $uri  = strstr($url, "/");
            
  $reqbody = "";
 
  foreach($_POST as $key=>$val)  {  // change "$_POST" to "$dataStream" if you still want to send the data to the function instead, but $_POST is fine since its global already

    if (is_array($val)) {      //don't url encode an array (added by an austute person on this site); you don't need to worry about it
      if (!empty($reqbody)) $reqbody .= "&";
      $reqbody .= $key . "=" . $val;
    }
    else {if (!empty($reqbody)) $reqbody .= "&"; $reqbody .= $key . "=" . urlencode($val);}      // "if (!is_empty.." should be changed to if (!empty...", it is here already!
  }

  $reqlength = strlen($reqbody);

  // here we change "HTTP/1.1" to "HTTP/1.0" or you may get "chunked" data with funny stuff on the end of your post data when its passed
  // a missing "\r" was added to the line "Host: $host (it only had a "\n" before and caused some problems I believe)
  $reqheader = "POST $uri HTTP/1.0\r\n".
                      "Host: $host\r\n" . "User-Agent: PostIt\r\n".
                      "Content-Type: application/x-www-form-urlencoded\r\n".
                      "Content-Length: $reqlength\r\n\r\n".
                      "$reqbody\r\n";
 
  // THIS IS THE LINE you add that enables the browser to redirect itself properly (you will see the right url in the address window now!)
  // Here you can see the "$saveurl variable we stored from "$url" at the top of the function
  // $saveurl must contain "https://www.yoursite.com/pageyourgoingto.php"
  header("Location: $saveurl");

  // "ssl://" added for SSL and "80" changed to "443" (thanks to another astute person on this thread)
  $socket = fsockopen("ssl://" . $host, 443, $errno, $errstr);

  if (!$socket) {$result["errno"] = $errno; $result["errstr"] = $errstr; return $result;}
  fputs($socket, $reqheader);
  while (!feof($socket)) {$result[] = fgets($socket, 4096);}
  fclose($socket);
      
  return $result;
}

    $isvalidated       = 1;
      $emailerror          = "";
    $emailclass       = "basictext1";
      $emailpattern       = '/^[[:alnum:]_\.\-]+@([[:alnum:]_\.\-]+\.)+[[:alpha:]]{2,4}$/';
    $fullnamerror       = "";
      $fullnameclass      = "basictext1";
      $fullnamepattern= '/[a-zA-Z ]{1,}/';
      $phoneerror            = "";
      $phoneclass            = "basictext1";
      $phonepattern      = '/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/';
      $phone                  = "";

    if ($_POST['process'] == 1) {
       
            if (preg_match($emailpattern, $_POST['email']) < 1) {
            $emailerror          = "Please enter a valid email address.";
                  $emailclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $email = $_POST['email'];
            }
            
            if (preg_match($fullnamepattern, $_POST['name']) < 1) {
            $fullnameerror          = "Please enter your name.";
                  $fullnameclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $name = $_POST['name'];
            }
            
            if (preg_match($phonepattern, $_POST['phone']) < 1) {
            $phoneerror          = "Please enter your phone number.";
                  $phoneclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $phone = $_POST['phone'];
            }
            
            if ($isvalidated == 1) {
            
            $url = "https://www480.ssldomain.com/ericcovarrubias/verified.cfm";
            
            post_it($url);

            }
            
    }
?>

<html>
<style>
.basictext1 {
    font: Arial, Helvetica, sans-serif 12px;
}
.errortext {
    font: Arial, Helvetica, sans-serif 12px bold;
    color:#CC0000;
}
</style>
<body>
<form action="validation6.php" method="post">

      <div>
      <label for="name" class="<? print $fullnameclass; ?>">Name:</label>
      <input name="name" type="text" class="textbox" id="name" value="<? print $name; ?>" />
      <? if ($fullnameerror != "") {
            print '<br /><span class="errortext">'.
                  $fullnameerror."</span>\n";
      }
      ?>
      </div>                  
      <div>
      <label for="email" class="<? print $emailclass; ?>">E-mail Address:</label>
      <input name="email" type="text" id="email" value="<? print $email; ?>" />
      <? if ($emailerror != "") {
            print '<br /><span class="errortext">'.
                  $emailerror."</span>\n";
      }
      ?>
      </div>
      <div>
      <label for="phone" class="<? print $phoneclass; ?>">Phone Number:</label>
      <input name="phone" type="text" id="phone" value="<? print $phone; ?>" />
                                          <? if ($phoneerror != "") {
                                                print '<br /><span class="errortext">'.
                                                      $phoneerror."</span>\n";
                                          }
                                          ?>
      </div>
      <input type="hidden" name="process" value="1">
      <input type="hidden" name="oid" value="xxx">
      <input type="hidden" name="retURL" value="verified.php">
      <input name="Submit" type="submit" value="Submit" class="buttons" />
</form>
</body>
</html>
0
Comment
Question by:ecovarrubias
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 29

Expert Comment

by:rdivilbiss
ID: 18878489
>>but the below code only posts the header data, not the page itself AND the form data.


You are posting:

POSTDATA=name=example&email=example%40example.com&phone=222-222-2222&process=1&oid=xxx&retURL=verified.php&Submit=Submit

To the cfm form okay.  (Get the Tamper Data plugin for FireFox and see for yourself.

Look in verified.cfm to see what field names and values it is expecting.
0
 
LVL 29

Expert Comment

by:rdivilbiss
ID: 18878575
See for yourself:  http://www.rodsdot.com/ee/Q_22499376.php

An exact copy of your code posting to https://www.rodsdot.com/ee/verified6.php.

Which is:

<?PHP
foreach($_POST as $key=>$val) {
    echo $key . "=" . $val . "<br>";
}
?>


Your PHP is working.  Either the cfm page is expecting other data or has a problem.
Q_22499376.php

<?


// Here is the function with SSL and header redirection properly set up!  (fully commented for those who are unaccustomed to this stuff)
// You can add the $dataStream aurgument back into the function, but if you do, change "$_POST" to "$dataStream" in the first foreach line.
// I took $dataStream out because I always use the $_POST data

function post_it($url)
{
  $saveurl = $url;  // Here we save the original $url because it will be altered in the next line and we wouldn't be able to use it like we need to later
 
  $url  = preg_replace("@^https://@i", "", $url);  // $url getting altered here so we saved it in the previous line
  $host = substr($url, 0, strpos($url, "/"));
  $uri  = strstr($url, "/");
            
  $reqbody = "";
 
  foreach($_POST as $key=>$val)  {  // change "$_POST" to "$dataStream" if you still want to send the data to the function instead, but $_POST is fine since its global already

    if (is_array($val)) {      //don't url encode an array (added by an austute person on this site); you don't need to worry about it
      if (!empty($reqbody)) $reqbody .= "&";
      $reqbody .= $key . "=" . $val;
    }
    else {if (!empty($reqbody)) $reqbody .= "&"; $reqbody .= $key . "=" . urlencode($val);}      // "if (!is_empty.." should be changed to if (!empty...", it is here already!
  }

  $reqlength = strlen($reqbody);

  // here we change "HTTP/1.1" to "HTTP/1.0" or you may get "chunked" data with funny stuff on the end of your post data when its passed
  // a missing "\r" was added to the line "Host: $host (it only had a "\n" before and caused some problems I believe)
  $reqheader = "POST $uri HTTP/1.0\r\n".
                      "Host: $host\r\n" . "User-Agent: PostIt\r\n".
                      "Content-Type: application/x-www-form-urlencoded\r\n".
                      "Content-Length: $reqlength\r\n\r\n".
                      "$reqbody\r\n";
 
  // THIS IS THE LINE you add that enables the browser to redirect itself properly (you will see the right url in the address window now!)
  // Here you can see the "$saveurl variable we stored from "$url" at the top of the function
  // $saveurl must contain "https://www.yoursite.com/pageyourgoingto.php"
  header("Location: $saveurl");

  // "ssl://" added for SSL and "80" changed to "443" (thanks to another astute person on this thread)
  $socket = fsockopen("ssl://" . $host, 443, $errno, $errstr);

  if (!$socket) {$result["errno"] = $errno; $result["errstr"] = $errstr; return $result;}
  fputs($socket, $reqheader);
  while (!feof($socket)) {$result[] = fgets($socket, 4096);}
  fclose($socket);
      
  return $result;
}

    $isvalidated       = 1;
      $emailerror          = "";
    $emailclass       = "basictext1";
      $emailpattern       = '/^[[:alnum:]_\.\-]+@([[:alnum:]_\.\-]+\.)+[[:alpha:]]{2,4}$/';
    $fullnamerror       = "";
      $fullnameclass      = "basictext1";
      $fullnamepattern= '/[a-zA-Z ]{1,}/';
      $phoneerror            = "";
      $phoneclass            = "basictext1";
      $phonepattern      = '/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/';
      $phone                  = "";

    if ($_POST['process'] == 1) {
       
            if (preg_match($emailpattern, $_POST['email']) < 1) {
            $emailerror          = "Please enter a valid email address.";
                  $emailclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $email = $_POST['email'];
            }
            
            if (preg_match($fullnamepattern, $_POST['name']) < 1) {
            $fullnameerror          = "Please enter your name.";
                  $fullnameclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $name = $_POST['name'];
            }
            
            if (preg_match($phonepattern, $_POST['phone']) < 1) {
            $phoneerror          = "Please enter your phone number.";
                  $phoneclass       = "errortext";
                  $isvalidated      = 0;
        }else{
                  $phone = $_POST['phone'];
            }
            
            if ($isvalidated == 1) {
            
            $url = "https://www.rodsdot.com/ee/verified6.php";
            
            post_it($url);

            }
            
    }
?>

<html>
<style>
.basictext1 {
    font: Arial, Helvetica, sans-serif 12px;
}
.errortext {
    font: Arial, Helvetica, sans-serif 12px bold;
    color:#CC0000;
}
</style>
<body>
<form action="Q_22499376.php" method="post">

      <div>
      <label for="name" class="<? print $fullnameclass; ?>">Name:</label>
      <input name="name" type="text" class="textbox" id="name" value="<? print $name; ?>" />
      <? if ($fullnameerror != "") {
            print '<br /><span class="errortext">'.
                  $fullnameerror."</span>\n";
      }
      ?>
      </div>                  
      <div>
      <label for="email" class="<? print $emailclass; ?>">E-mail Address:</label>
      <input name="email" type="text" id="email" value="<? print $email; ?>" />
      <? if ($emailerror != "") {
            print '<br /><span class="errortext">'.
                  $emailerror."</span>\n";
      }
      ?>
      </div>
      <div>
      <label for="phone" class="<? print $phoneclass; ?>">Phone Number:</label>
      <input name="phone" type="text" id="phone" value="<? print $phone; ?>" />
                                          <? if ($phoneerror != "") {
                                                print '<br /><span class="errortext">'.
                                                      $phoneerror."</span>\n";
                                          }
                                          ?>
      </div>
      <input type="hidden" name="process" value="1">
      <input type="hidden" name="oid" value="xxx">
      <input type="hidden" name="retURL" value="verified.php">
      <input name="Submit" type="submit" value="Submit" class="buttons" />
</form>
</body>
</html>

verified6.php
<?PHP
foreach($_POST as $key=>$val) {
    echo "POST: " . $key . "=" . $val . "<br>";
}

echo "SERVER: ALL_HTTP = " . $_SERVER["ALL_HTTP"] . "<br>";
echo "SERVER: HTTPS = " . $_SERVER["HTTPS"] . "<br>";
echo "SERVER: REMOTE_ADDR = " . $_SERVER["REMOTE_ADDR"] . "<br>";
echo "SERVER: REQUEST_METHOD = " . $_SERVER["REQUEST_METHOD"] . "<br>";
echo "SERVER: REFERER = " . $_SERVER["HTTP_REFERER"] . "<br>";
?>

Open in new window

0
 

Author Comment

by:ecovarrubias
ID: 18879346
I actually have tamper data and see it being passed in headers, but what I need is for the entire page to post to a given external URL (not just the headers and not just the page after the fact.) So the form action would submit to $url with the post data all at once - does that make sense?
0
Secure Your WordPress Site: 5 Essential Approaches

WordPress is the web's most popular CMS, but its dominance also makes it a target for attackers. Our eBook will show you how to:

Prevent costly exploits of core and plugin vulnerabilities
Repel automated attacks
Lock down your dashboard, secure your code, and protect your users

 
LVL 29

Expert Comment

by:rdivilbiss
ID: 18879549
But it does...change in your code on your server

$url = "https://www480.ssldomain.com/ericcovarrubias/verified.cfm";

to

$url = "http://www.rodsdot.com/ee/Q_22499376_verified6.php";

and you'll see you ARE posting your form data.

Rod
0
 

Author Comment

by:ecovarrubias
ID: 18941666
Yes I see the form data posting fine using tamper data, but the entire page must post - just as if there was no form validation. The form action must be the page that contains the form (so all validation fields are tested) but the $URL is an external domain. AFTER validating the page must post not just the form fields but the entire page to the $URL location. Basically the data and the visitor should end up at $URL despite the form action being the processing page and NOT $URL.
0
 
LVL 29

Accepted Solution

by:
rdivilbiss earned 500 total points
ID: 18950126
The  whole page is never sent to any page ona POST, just the headers containing among other things the postdata.

What may be causing you an issue is that the https://www480.ssldomain.com/ericcovarrubias/verified.cfm page may be expecting the original pages URL as the HTTP_REFERER and you second page is intercepting this and probably submitting its own URL as the HTTP_REFERER.

If that is the case, you can rename your first page something else, and name your second page to the URL expected by https://www480.ssldomain.com/ericcovarrubias/verified.cfm.

If that is not the case, the only way we can help you more is to see the source of https://www480.ssldomain.com/ericcovarrubias/verified.cfm so we can figure out what it expects.
0
 

Author Comment

by:ecovarrubias
ID: 18952403
Ignore https://www480.ssldomain.com/ericcovarrubias/verified.cfm. It doesn't matter. If https://www480.ssldomain.com/ericcovarrubias/verified.cfm is a 404 thats fine. Perhaps 'whole page' is confusing you. If the action (target) of the form was an external page the browser window would end up on that page after a user clicks submit, right? So thats what I need. The headers AND the browser sent to an external site all in one action.

So far the headers are making it to 'any external page' using the above code, but the browser window does NOT - it remains on the page with the form. A simple redirect won't work as the external site will redirect submissions based on entered data.
0

Featured Post

Secure Your WordPress Site: 5 Essential Approaches

WordPress is the web's most popular CMS, but its dominance also makes it a target for attackers. Our eBook will show you how to:

Prevent costly exploits of core and plugin vulnerabilities
Repel automated attacks
Lock down your dashboard, secure your code, and protect your users

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question