I try to send a xml file to a web service, but it's not working. The web service supplier has no idea.
If you read the error message, it looks like there is a wrong soap version used, but the supplier tried it with the same xml file and he had no problems with this file. I have no idea what's wrong.
The code:
#Declaration
host = "bar.foo.nl";
path = "/services/setu.asmx";
port = 443;
username = "xxx"
password = "yyy";
ssl = true;
#Create connection
req = Net::HTTP::Post.new(path)
req.basic_auth(username, password)
http = Net::HTTP.new(host, port)
http.use_ssl = ssl
#send file
res = http.request(req, 'D:/test.xml')
#show result
puts res.code
puts res.body
EDIT: The xml file: XML FILE
The error (500 code):
Possible SOAP version mismatch: Envelope namespace
http://ns.hr-xml.org/2007-04-15 was unexpected. Expecting
http://schemas.xmlsoap.org/soap/envelope/.
I don't see any soap declarations in the file you've uploaded, and it looks like the service you're contacting requires it.
Start with http://www.w3schools.com/xml/xml_soap.asp and rework your content to be wrapped in a soap envelope.
Related
I was using the HTTP Request Plugin to make an API call to my Bitbucket server.
The following call returns the desired result:
def my-url = "http://my-username:my-password#my-bitbucket-server.com:7990/rest/api/1.0/my-project/pull-request-10"
def response = http_request my-url
However, I had an issue with the HTTP Request Plugin, because it prints my password in plain text in the logs.
Therefore, I tried doing the same call from a groovy script:
def response = new URL(my-url).getText()
But for this I am getting a 401 server response.
Any idea why this time, the call fails?
You're trying to apply Basic auth using almost plain Java. You have to generate your auth key and attach it to the request headers. Try:
String addr = 'my-bitbucket-server.com:7990/rest/api/1.0/my-project/pull-request-10'
String authString = 'my-username:my-password'.getBytes().encodeBase64().toString()
def conn = addr.toURL().openConnection()
conn.setRequestProperty( "Authorization", "Basic ${authString}" )
def feed = new XmlSlurper().parseText( conn.content.text )
Hope this would help!
I am working on a project whereby we have sites (developed with ruby on rails) hosted on an Ubuntu server using tomcat. We want these sites to make HTTP calls to a service developed using Nancy. We have this working locally whereby the service is hosted on a machine that we can call within our network. We cannot however get it working when live. Here is an example call:
def get_call(routePath)
started_at = Time.now
enc_url = URI.encode("#{settings.service_endpoint}#{routePath}")
uri = URI.parse(enc_url)
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Get.new(uri.request_uri)
resp = http.request(req)
logger.bench 'SERVICE - GET', started_at, routePath
return resp if response_ok?(resp)
end
When working locally the settings are as follows:
settings.service_endpoint = http://10.10.10.27:7820
routePath = /Customers
When we upload it to the server we use the following:
settings.service_endpoint = http://127.0.0.1:24099
routePath = /Customers
We currently get the following error:
SocketError at /register
initialize: name or service not know
with the following line being highlighted:
resp = http.request(req)
Are we completely wrong with the IP being called. Should it be 127.0.0.1, localhost. 10.10.10.27 or something entirely different? The strange thing is we can do a GET call via telnet in our Ubuntu server (telnet 127.0.0.1 24099) so that must mean the server can make the calls but the site hosted on the server cannot. Do we need to include a HTTP proxy (have read some reference to that but dont really know if its needed).
Apologies if its obvious but we have never tried anything like this before so its all very perplexing. Any further information required just let me know.
We changed the service_endpoint to localhost and it worked. Not sure if this is because it didnt like "http://" or some other reason. Any explanation as to why this is the case would be much appreciated, just so we know. Thanks!
I am working on rails environment. I am using Net::HTTP module for calling an external API and getting the response. This is working fine in my local host. But in staging it throwing an Net::HTTPBadResponse error. My staging is SSL enabled. This is the difference. Providing the code snippet and error below.
parameters = {'VirtualNumber' => '09845xxxxxx','Number[]' => "09878xxxxxx" }
x = Net::HTTP.post_form(URI.parse("https://example.com"), parameters)
Error:
Net::HTTPBadResponse (wrong status line: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">")
The successful result will be in XML format. Can any one help me to solve this.
Thank You,
Regards
The issue was calling the API from ssl enabled site. So while calling the API we need to enable the ssl. And along with that need to provide basic authentication.
parameters = {'VirtualNumber' => '09845xxxxxx','Number[]' => "09878xxxxxx" }
url = URI.parse("https://example.com")
request = Net::HTTP::Post.new(url.path)
request.basic_auth "user", "pass"
request.set_form_data(parameters)
sock = Net::HTTP.new(url.host, url.port)
if url.scheme == 'https'
sock.use_ssl = true
end
response = sock.start {|http| http.request(request) }
I'm trying to use Microsoft's Translator API in my Rails app. Unfortunately and mostly unexpected, the server answers always with an internal server error. I also tried it manually with Poster[1] and I get the same results.
In more detail, what am I doing? I'm creating an XML string which goes into the body of the request. I used the C# Example of the API documentation. Well, and then I'm just invoking the RESTservice.
My code looks like this:
xmlns1 = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"
xmlns2 = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"
xml_builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.TranslateArrayRequest("xmlns:ms" => xmlns1, "xmlns:arr" => xmlns2) {
xml.AppId token #using temporary token instead of appId
xml.From source
xml.To target
xml.Options {
xml["ms"].ContentType {
xml.text "text/html"
}
}
xml.Texts {
translate.each do |key,val|
xml["arr"].string {
xml.text CGI::unescape(val)
}
end
}
}
end
headers = {
'Content-Type' => 'text/xml'
}
uri = URI.parse(##msTranslatorBase + "/TranslateArray" + "?appId=" + token)
req = Net::HTTP::Post.new(uri.path, headers)
req.body = xml_builder.to_xml
response = Net::HTTP.start(uri.host, uri.port) { |http| http.request(req) }
# [...]
The xml_builder produces something like the following XML. Differently to the example from the API page, I'm defining two namespaces instead of referencing them on the certain tags (mainly because I wanted to reduces the overhead) -- but this doesn't seem to be a problem, when I do it like the docu-example I also get an internal server error.
<?xml version="1.0" encoding="UTF-8"?>
<TranslateArrayRequest xmlns:ms="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<AppId>TX83NVx0MmIxxCzHjPwo2_HgYN7lmWIBqyjruYm7YzCpwnkZL5wtS5oucxqlEFKw9</AppId>
<From>de</From>
<To>en</To>
<Options>
<ms:ContentType>text/html</ms:ContentType>
</Options>
<Texts>
<arr:string>Bitte übersetze diesen Text.</arr:string>
<arr:string>Das hier muss auch noch übersetzt werden.</arr:string>
</Texts>
</TranslateArrayRequest>
Every time I request the service it answers with
#<Net::HTTPInternalServerError 500 The server encountered an error processing the request. Please see the server logs for more details.>
... except I do some unspecified things, like using GET instead of POST, then it answers with something like "method not allowed".
I thought it might be something wrong with the XML stuff, because I can request an AppIdToken and invoke the Translate method without problems. But to me, the XML looks just fine. The documentation states that there is a schema for the expected XML:
The request body is a xml string generated according to the schema specified at http:// api.microsofttranslator.com/v2/Http.svc/help
Unfortunately, I cannot find anything on that.
So now my question(s): Am I doing something wrong? Maybe someone experienced similar situations and can report on solutions or work-arounds?
[1] Poster FF plugin > addons.mozilla.org/en-US/firefox/addon/poster/
Well, after lot's of trial-and-error I think I made it. So in case someone has similar problems, here is how I fixed this:
Apparently, the API is kind of fussy with the incoming XML. But since there is no schema (or at least I couldn't find the one specified in the documentation) it's kind of hard to do it the right way: the ordering of the tags is crucial!
<TranslateArrayRequest>
<AppId/>
<From/>
<Options />
<Texts/>
<To/>
</TranslateArrayRequest>
When the XML has this ordering it works. Otherwise you'll only see the useless internal server error response. Furthermore, I read a couple of times that the API also breaks if the XML contains improper UTF-8. One can force untrusted UTF-8 (e.g. coming from a user form) this way:
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
valid_string = ic.iconv(untrusted_string + ' ')[0..-2]
I want to autodetect the pingback-url of remote websites, so I need to parse the HTTP response headers sent by the remote server. I don't need and don't want the contents of the remote website, I'm only looking for something like this:
X-Pingback: http://www.techcrunch.com/xmlrpc.php
Similar to using curl:
curl -I "your url"
Is there a way to do this with rails? When using open-uri I can only get the contents but not the headers.
Thank you!
Ole
This is not a Rails specific question, but it can be solved with the core Ruby API.
require 'net/http'
url = URI.parse('http://www.google.ca/')
req = Net::HTTP::Head.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts res['X-Pingback']
> "http://www.techcrunch.com/xmlrpc.php"
If you don't mind using a gem, you might try Patron, which is a ruby wrapper for the libcurl library. Usage might look something like this:
sess = Patron::Session.new
sess.timeout = 10
sess.base_url = "http://myserver.com:9900"
resp = sess.get( "your url" )
headers = resp.headers