Link to home
Start Free TrialLog in
Avatar of quad341
quad341

asked on

Error in POST request through fsocket

This really applies more to the POST request than actually php, but because the script is implemented in php, i believe you people are my best help.  Probably small syntax problem, thus low points, sorry.  also open source project = not too important, just fun.

Again, i am back with my mirror admin script, but this is to try to allow automated syncroization from a file upload to a separate php script that takes the file and moves it to a directory there.  to do this, i am trying to get the mirror_admin script to POST through an fsocket to the remote script.  

I would prefer not to use cURL if avoidable for i want this very generic.

This is the current POST request (line 830 in the code)
$content_string = "
POST $dir HTTP/1.0
Host: $host
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------265001916915724
Conteht-Length: $total_length
-----------------------------265001916915724
Content-Disposition: form-data; name=\"pass\"

$pass
-----------------------------265001916915724
Content-Disposition: form-data; name=\"filename\"

$filename
-----------------------------265001916915724
Content-Disposition: form-data; name=\"hash\"

$file_hash
-----------------------------265001916915724
Content-Disposition: form-data; name=\"file\"; filename=\"$local_file\"
Content-Length: $file_len
Content-Type: $file_mime

$file_contents
-----------------------------265001916915724--\r\n\r\n";

this is recieved by the following script (all vars set above):
if($_POST[pass]===$PASSWORD){
      // upload file
      $local_file=$_FILES[file][tmp_name];
      $filename = $_POST[filename];
      $hash = $_POST[hash];
      if($hash != md5_file($local_file)){
            // failed hash, error code 1
            die('1');
      }
      // you could check if this works and ouput if it does.  currently does not
      if(move_uploaded_file($local_file,$DIRECTORY.$filename)){
            if($CONFIRM_UPLOAD){
                  // admin must confirm, error code 3
                  mail($ADMIN_EMAIL,'File Uploaded',"File $filename was just uploaded, please verify and move to proper directory");
                  die('3');
            } else {
                  // all good, error code 0
                  die('0');
            }
      } else {
            // failed to move, error code 2
            die('2');
            if($ADMIN_EMAIL){
                  mail($ADMIN_EMAIL,'Failed Upload',"File $filename just failed to upload.  check permissions on $DIRECTORY.");
            }
      }
}

the full sourcecode of mirror_admin.php (first script) can be found @ http://quad341.com/mirror_v2/test.php and i'll update the archive of all the files if requested.

thanks again.  person who assists will get credit in readme file

Avatar of peyox
peyox
Flag of Poland image

At the first glance:

if($_POST[pass]===$PASSWORD){

should be:

if($_POST[pass]==$PASSWORD){
Avatar of alextr2003fr
alextr2003fr

review your $content_string construction, POST $dir HTTP/1.0 should be POST $dir HTTP/1.0\r\n, same for Host: $host wich should be Host: $host\r\n
do not forget \r\n (CRLF) on the end of your lines
Avatar of quad341

ASKER

peyox, === means exactly equal to.  it stops implicit conversions.

adding \r\n to every line made no difference. i'll mess with the link above to see why it's ignoring my period
I know what === operator means. The problem is, that === requires both variables to be in the same type. If they are not (this is possible problem I sugested) this comparison will fail.

Do you get anything in print_r($_POST); ? Does it triggers your script?
typo:
Conteht-Length: $total_length
      ----

Content, does it help?
ASKER CERTIFIED SOLUTION
Avatar of peyox
peyox
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of quad341

ASKER

good catch peyox for the typo, but no go.  i added a form to test it yesterday and sent it through a browser without a problem, so i know all the tests work.

when telnetting to the server on port 80, everything gets sent after the first \r\n\r\n (2 link feeds, end of headers) and it doesn't seem to listen to the rest of the transmission.  if i understood why this was, i could probably apply the same solution to this script.  the telnet session would generate error 400 from the server (local or remote) even when i sent the exact same query as the Live HTTP Headers extension in FireFox caught.

any ideas on this?  (peyox:  you will get some points for the typo find and credit in readme, but this is not completely working)

full system with all the current files (including the form in mirror_postscript.php) is available at http://quad341.com/projects/mirror_project.zip (the previous version i had posted is now at http://quad341.com/projects/mirrof_project_v.5.zip )
One more thing:

Server responds like this:
HTTP/1.1 404 Not Found

So this part of the code will give the letter "H" instead of first digit of error code (you have to change it):
$error_code=fread($socket,1);
Avatar of quad341

ASKER

didn't see peyox's last post before i commented.  tried code and had same result.  

zip updated to have his code in it though.  points increased to 100
This is my code (create two files getpost.php and test.php):

FILE: getpost.php
--------------------------------------------------------------------
<?
        print_r ($_REQUEST);
?>


FILE: test.php:
--------------------------------------------------------------------
<?
    $host = "localhost";
    $dir = "/ee/getpost.php";
    $filename="c:\\test.txt";
    $pass = "samplepassword";



    $pass_len = strlen($pass);
    $filename_len=strlen($filename);

    $local_file = $filename;
    // content for the password is constructed.
    // now try to send the file.  first will try to determine
    // mime type
    $file_mime = "text/plain";
    // now length
    $file_len = filesize($local_file);
    // hash the file
    $file_hash = md5_file($local_file);
    // need that length
    $hash_len = strlen($file_hash);
    // now read the file
    $file_handle = fopen($local_file,'r');
    $file_contents = fread($file_handle,$file_len);
    fclose($file_handle);
    // need total length
    $total_length = $pass_len + $filename_len + $hash_len + $file_len+300;
    // now build the header

    $headers  = "POST $dir HTTP/1.1\r\n";
    $headers .= "Accept: */*\r\n";
    $headers .= "Content-Type: multipart/form-data; boundary=---------------------------7d52521ec0a0a\r\n";
    $headers .= "Host: $host\r\n";
    $headers .= "Connection: Keep-Alive\r\n";


    $postVars  = "-----------------------------7d52521ec0a0a\r\n";
    $postVars .= "Content-Disposition: form-data; name=\"pass\"\r\n\r\n";
    $postVars .= $pass."\r\n";
    $postVars .= "-----------------------------7d52521ec0a0a\r\n";
    $postVars .= "Content-Disposition: form-data; name=\"filename\"\r\n\r\n";
    $postVars .= $filename."\r\n";
    $postVars .= "-----------------------------7d52521ec0a0a\r\n";
    $postVars .= "Content-Disposition: form-data; name=\"hash\"\r\n\r\n";
    $postVars .= $file_hash."\r\n";
    $postVars .= "-----------------------------7d52521ec0a0a\r\n";
    $postVars .= "Content-Disposition: form-data; name=\"file\"; filename=\"$local_file\"\r\n\r\n";
    $postVars .= "Content-Length: $file_len\r\n";
    $postVars .= "Content-Type: $file_mime\r\n\r\n";
    $postVars .= $file_contents."\r\n";
    $postVars .= "-----------------------------7d52521ec0a0a--\r\n\r\n";

    $total_length = strlen($postVars);
    $headers .= "Content-Length: $total_length\r\n\r\n";

    $content_string = $headers.$postVars;

    $socket = fsockopen($host, 80,$soc_err_no,$soc_err,5);

    print "<!-- $content_string -->";
    // now write this to the remote server
    fwrite($socket,$content_string);
    // get error code
    $error_code=fread($socket,1000);
    // close socket
    fclose($socket);



    // display the results
    echo "<pre>";
    echo "POST:<BR>".$content_string;
    echo "<br>";
    echo "Server response:<BR>".$error_code;
    echo "</pre>";
?>

OUTPUT:
--------------------------------------------------------------------
POST:
POST /ee/getpost.php HTTP/1.1
Accept: */*
Content-Type: multipart/form-data; boundary=---------------------------7d52521ec0a0a
Host: localhost
Connection: Keep-Alive
Content-Length: 564

-----------------------------7d52521ec0a0a
Content-Disposition: form-data; name="pass"

samplepassword
-----------------------------7d52521ec0a0a
Content-Disposition: form-data; name="filename"

c:\test.txt
-----------------------------7d52521ec0a0a
Content-Disposition: form-data; name="hash"

590a9d9ec06e39fdc57490cd9a119e6d
-----------------------------7d52521ec0a0a
Content-Disposition: form-data; name="file"; filename="c:\test.txt"

Content-Length: 11
Content-Type: text/plain

THIS A TEST
-----------------------------7d52521ec0a0a--

Server response:HTTP/1.1 200 OK
Date: Wed, 13 Apr 2005 02:44:50 GMT
Server: Apache/1.3.12 (Win32)
X-Powered-By: PHP/4.3.8
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

74
Array
(
    [pass] => samplepassword
    [filename] => c:\test.txt
    [hash] => 590a9d9ec06e39fdc57490cd9a119e6d
)

Avatar of quad341

ASKER

peyox has been an incredible help.

here's the final breakdown of what was wrong:  misspelling of content, miscalculation of length, misread of the response for the error code.

the error code is 1, meaning mis hash.  now here's my final question:  why would the file hash differently?  they both md5_file() the file, but come up with 2 different hashes.  did the file fail to transfer correctly or what?  it's supposed to protect against failed transfers, and it seems to be, but why is the transfer faileing (i'm testing with the readme file that is contained in the zip.  it's text and medium sized)
Avatar of quad341

ASKER

points updated.  they're going to peyox.  his help is amazing.

i found it:  the boundary is appended to the bottom of the file making the filesize and hash different.

how do i stop this?
Avatar of quad341

ASKER

found it.  there was an error after filename=\"[whatever]\"  in peyox's code:  he ends that line with \r\n\r\n when it should be \r\n because that is not the end of the headers.  it works perfect now.  thank you so much
You are right it should be single CRLF. My mistake.
Thanks for the points.