可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Hello,
I am currently writing a client to access a Microsoft Exchange server and read contacts, appointments etc. from it.
Through days of searching I've been able to connect to the EWS via PHP's Soap client and a custom HTTPS Stream wrapper. This website helped me greatly at this point.
Everything worked fine on my Windows 7 machine using XAMPP
Now I uploaded my project to a Debian 6.0 Squeeze development machine that has exactly the same configuration as my Windows machine regarding the web-server, php settings, mysql settings etc. but it just wont work anymore
The debian machine can resolve and ping the exchange server without problems
I nailed the actual problem down to a point, where cURL isn't able to retrieve the WSDL file of the EWS
It always receives an empty response and a 401 (Unauthorized) status code
The credentials I use are correct, the same credentials work on my windows machine
I extracted the faulty piece of code and tried running it stand-alone, it looks like this:
echo "Trying to get https://".$cfg[ 'Exchange.Server' ]."/EWS/Services.wsdl
"; $curl = curl_init( 'https://'.$cfg[ 'Exchange.Server' ].'/EWS/Services.wsdl' ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 ); curl_setopt( $curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM ); curl_setopt( $curl, CURLOPT_USERPWD, $cfg[ 'Exchange.User' ].':'.$cfg[ 'Exchange.Password' ] ); curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false ); echo ''; $response = curl_exec( $curl ); $info = curl_getinfo( $curl ); var_dump( $info ); var_dump( $response ); curl_close( $curl );
The result I receive here is the mentioned 401 status code and an empty response When I call the same url in my browser or with the same code on my windows machine, I get the WSDL file I want
Actually I can't even tell if this is a linux-based problem or if I do something wrong at some point, I'm struggling with this for 2 days now.
Is there someone that may be able to find my mistake or tell me the reason why it doesn't work?
I may provide any further needed information on demand
回答1:
If you initialize your soap client properly, you should be able to preform any requests requests this way:
$curl = curl_init($location); //'https://'.$server_address.'/EWS/Exchange.asmx' curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //valid soap headers with keep-alive curl_setopt($ch, CURLOPT_POST, true ); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password); $response = curl_exec($curl);
As to your code, try commenting out following line:
curl_setopt( $curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
Also take a look wherever this wrapper works on your setup: http://ewswrapper.lafiel.net/ If it does, take a look at SOAP classes used there - it uses php built-in as base.
Why can't you store wsdl file locally anyways?
UPDATE:
Ok, I played around with this in my Debian box and this works for me flawlessly:
$domain = 'xxxxxx'; $user = 'xxxxxx'; $password = 'xxxxxx'; $ch = curl_init('https://'.$domain.'/EWS/Services.wsdl'); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password); $response = curl_exec($ch); $info = curl_getinfo( $ch ); $error = curl_error ($ch); print_r(array($response,$info,$error));
returns
Array ( [0] => [1] => Array ( [url] => xxxxx/EWS/Services.wsdl [content_type] => text/xml [http_code] => 200 [header_size] => 250 [request_size] => 147 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.60574 [namelookup_time] => 0.165249 [connect_time] => 0.268173 [pretransfer_time] => 0.474009 [size_upload] => 0 [size_download] => 55607 [speed_download] => 91800 [speed_upload] => 0 [download_content_length] => 55607 [upload_content_length] => 0 [starttransfer_time] => 0.580931 [redirect_time] => 0 [certinfo] => Array ( ) [redirect_url] => ) [2] => )
回答2:
Your first check should not use any complex scripting. Instead try opening the WDSL from a simple browser window on the Debian machine like so: https://your.exchange-server.com/EWS/Services.wsdl
If that does not work there are probably access restrictions in place that depend on the client IP or client network (e.g. your development machine being in a trusted network, your Debian not). The fact that you get a 401 ("Unauthorized" - request requires user authentication) suggests that there is no problem with contacting the server but with authentication.
Another check I suggest is that you have a look into your phpinfo() to make sure your PHP installation on Debian is capable of handling HTTP*S* requests. Make sure, OpenSSL is installed!
回答3:
This article helped point me in the right direction. One thing to keep in mind is that your PHP installation may not be sharing your system's cURL / libcurl setup.
http://blog.ianty.com/ubuntu/exchange-web-services-ews-ntlmv2-and-linux/