将PHP-CURL上传到Windows WCF之前和之后的文件大小差异

时间:2014-12-26 10:20:05

标签: php web-services wcf file-upload filesize

我正在尝试使用PHP上传文件。不是那个凝灰岩吗?好吧,我需要通过Webservices WCF来实现。现在,我坚持最后一部分。当我上传文件时它是:892599(这是Windows和Linux在文件系统上告诉我的。还有PHP告诉我的。但是,当它到达现场时(Windows Server,WCF)它只有891400

这必须与编码或操作系统差异有关,但我不知道现在在哪里看。下面是我的PHP代码。

正如你在代码中看到的那样,我尝试了不同的方法,但都有相同的结果。归档差异。源文件(我尝试上传的文件是text / plain us_ascii编码文件)

try{
    header("Content-type: text/plain; charset=utf-8", true);

    $filename = "ahstray.obj";
    $file_content = file_get_contents($filename);
    $file_hash = hash_file('sha512', $filename, false);
    $bits = pack("H*", $file_hash);
    $file_hash = base64_encode($bits);        
    $filesize = strlen($file_content); //filesize($filename); //strlen(file_get_contents($filename));

    $boundary = "uuid:".uniqid();        
    $headers = array(
        'MIME-Version: 1.0',
        'Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="'.$boundary.'";start-info="text/xml"',
        'SOAPAction: "'.$action.'"',
        'Host: www.url.com',
        'Content-length: '.$filesize,
        'Accept-Encoding: gzip, deflate',
        'User-Agent: PHP-Post-FileUpload'
    );
    $post_data = "\r\n\r\n\r\n--{$boundary}\r\n";
    $post_data .= "Content-ID: <http://tempuri.org/0>\r\n";
    $post_data .= "Content-Transfer-Encoding: 8bit\r\n";
    $post_data .= 'Content-Type: application/xop+xml;charset=utf-8;type="text/xml"';
    $post_data .= "\r\n\r\n";

    $post_data .= '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">';
        $post_data .= '<s:Header>';
            $post_data .= '<h:FileHash xmlns:h="http://www.materialise.be/eRP">'.$file_hash.'</h:FileHash>';
            $post_data .= '<h:FileName xmlns:h="http://www.materialise.be/eRP">'.$filename.'</h:FileName>';
            $post_data .= '<h:FileSize xmlns:h="http://www.materialise.be/eRP">'.$filesize.'</h:FileSize>';
            $post_data .= '<h:UserDomain xmlns:h="http://www.materialise.be/eRP">'.$domain.'</h:UserDomain>';
            $post_data .= '<h:UserName xmlns:h="http://www.materialise.be/eRP">'.$gebruiker.'</h:UserName>';
            $post_data .= '<h:UserPassword xmlns:h="http://www.materialise.be/eRP">'.$encrypted_password.'</h:UserPassword>';
        $post_data .= '</s:Header>';
        $post_data .= '<s:Body>';
            $post_data .= '<UploadFileDTO xmlns="http://www.url.com/eRP">';
                    $post_data .= '<FileStream>';
                        $post_data .= '<xop:Include href="cid:http://tempuri.org/1/635551016730489495" xmlns:xop="http://www.w3.org/2004/08/xop/include" />';
                    $post_data .= '</FileStream>';
            $post_data .= '</UploadFileDTO>';
        $post_data .= '</s:Body>';
    $post_data .= '</s:Envelope>';

    $post_data .= "\r\n--{$boundary}\r\n";
    $post_data .= "Content-ID: <http://tempuri.org/1/635551016730489495>\r\n";
    $post_data .= "Content-Transfer-Encoding: binary\r\n";
    $post_data .= "Content-Type: application/octet-stream\r\n\r\n";

    $post_data .= $file_content.$file_content;        
    $post_data .= "--{$boundary}\r\n";


    $sock = fsockopen("ssl://www.url.com", 443, $errorno, $error, 30) or die($error);
    $data = "POST https://www.url.com/FilesTransfer.svc HTTP/1.1\r\n";
    $data .= implode("\r\n", $headers);
    $data .= $post_data;

    if($sock){                        
        fwrite($sock, $data);
        echo fread($sock, strlen($data));
        fflush($sock);
        fclose($sock);
    }        

    /*
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    $error = curl_error($ch);

        print_r_pre($response);
        print_r_pre($error);
        curl_close($ch);
        */

} catch (Exception $e){
    print('<pre>');
    print_r($e);
    print('</pre>');
}

1 个答案:

答案 0 :(得分:0)

因此解决这个问题的方法很简单。这是一个部分请求,这意味着当您设置'Content-length'时,您应该计算请求的完整大小。因此,XML部分和您尝试上传的文件的大小。

请求现在看起来像这样:

try{

        $file_content = utf8_encode(file_get_contents($filename));
        $hash = hash('sha512', $file_content, false);
        $bits = pack("H*", $hash);
        $file_hash = base64_encode($bits);       
        $filesize = filesize($filename); //filesize($filename); //strlen(file_get_contents($filename));

        $boundary = "uuid:".uniqid();     

         $xml_request = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">';
            $xml_request .= '<s:Header>';
                $xml_request .= '<h:FileHash xmlns:h="http://www.materialise.be/eRP">'.$file_hash.'</h:FileHash>';
                $xml_request .= '<h:FileName xmlns:h="http://www.materialise.be/eRP">'.$filename.'</h:FileName>';
                $xml_request .= '<h:FileSize xmlns:h="http://www.materialise.be/eRP">'.$filesize.'</h:FileSize>';
                $xml_request .= '<h:UserDomain xmlns:h="http://www.materialise.be/eRP">'.$this->domain.'</h:UserDomain>';
                $xml_request .= '<h:UserName xmlns:h="http://www.materialise.be/eRP">'.$this->gebruiker.'</h:UserName>';
                $xml_request .= '<h:UserPassword xmlns:h="http://www.materialise.be/eRP">'.$this->encrypted_password.'</h:UserPassword>';
            $xml_request .= '</s:Header>';
            $xml_request .= '<s:Body>';
                $xml_request .= '<UploadFileDTO xmlns="http://www.url.com/eRP">';
                        $xml_request .= '<FileStream>';
                            $xml_request .= '<xop:Include href="cid:http://tempuri.org/1/635551016730489495" xmlns:xop="http://www.w3.org/2004/08/xop/include" />';
                        $xml_request .= '</FileStream>';
                $xml_request .= '</UploadFileDTO>';
            $xml_request .= '</s:Body>';
        $xml_request .= '</s:Envelope>';

        $headers = array(
            'MIME-Version: 1.0',
            'Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="'.$boundary.'";start-info="text/xml"',
            'SOAPAction: "http://www.url.com/UploadFile"',
            'Host: www.url.com',
            'Accept-Encoding: gzip, deflate',
            'Connection: Keep-Alive'
        );

        $post_data = "--{$boundary}\r\n";
        $post_data .= "Content-ID: <http://tempuri.org/0>\r\n";
        $post_data .= "Content-Transfer-Encoding: 8bit\r\n";
        $post_data .= 'Content-Type: application/xop+xml;charset=utf-8;type="text/xml"';
        $post_data .= "\r\n\r\n";

        $post_data .= $xml_request;

        $post_data .= "\r\n--{$boundary}\r\n";
        $post_data .= "Content-ID: <http://tempuri.org/1/635551016730489495>\r\n";
        $post_data .= "Content-Transfer-Encoding: binary\r\n";
        $post_data .= "Content-Type: application/octet-stream\r\n\r\n";

        $headers[] = "Content-length: ".($filesize+strlen($post_data));

        $post_data .= $file_content;       
        $post_data .= "--{$boundary}\r\n";

        $ch = curl_init($this->wsdl_url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_VERBOSE, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $response = curl_exec($ch);
        $error = curl_error($ch);