I was surprised to find my ring app was not serving utf-8 properly. I pared this down to a simple test case, does anyone know how to ensure that this will always return utf-8 to the browser?
(ns utf8test.core)
(defn app
[request]
{:status 200 :body "ɮѪϴ"})
In project.clj (using the lein-ring plugin):
:ring {:handler utf8test.core/app}
In terminal:
> lein ring server
---> ɮѪϴ (this is wrong, should be ɮѪϴ)
Preferably a method that works for tomcat as well, since this is where the app is being deployed.
Thanks!
Without setting a Content-Type header, Jetty is probably sending a response indicating the platform-default encoding. Try using the content-type or charset response functions to add an appropriate header (e.g. (charset {:status 200 :body "..."} "UTF-8")).
Related
I was experimenting with the Ruby rest-client gem and ran into an "issue" so to speak. I noticed when I would hit a certain URL that should just return HTML, I would get a 404 error unless I specifically specified:
RestClient.get('http://www.example.com/path/path', accept: 'text/html')
However, pretty much any other page that I would hit without specifying the Accept header explicitly would return HTML just fine.
I looked at the source for the Request object located here and in the default_headers method around line 486 it appears that the default Accept header is */*. I also found the relevant pull request here.
I'm not quite sure why on a particular site (not all) I have to explicitly specify Accept: text/html when any other site that returns HTML by default does it without any extra work. I should note that other pages on this same site work fine when requesting the page without explicitly specifying text/html.
It's not a huge issue and I can easily work around it using text/html but I just thought it was a bit odd.
I should also note that when I use another REST client, such as IntelliJ's built-in one and specify Accept: */* it returns HTML no problem...
EDIT: Ok, this is a bit strange...when I do this:
RestClient.get('http://www.example.com/path/path', accept: '*/*')
Then it returns HTML as I expect it to but leaving off that accept: */* parameter doesn't work even though by default that header should be */* according to the source code...
I wonder if because my URL has /path/path in it, RestClient thinks it's an endpoint to some API so it tries to retrieve XML instead...
EDIT 2: Doing a bit more experimenting...I was able to pass a block to the GET request as follows:
RestClient.get('http://example.com/path/path') {
|response, request, result|
puts response.code
puts request.processed_headers
}
And I get a 404 error and the processed_headers returns:
{"Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate"}
The response body is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<errors>Not Found</errors>
</hash>
So, it is sending a */* header but for some reason it looks like the application/xml gets priority. Maybe this is just something on the server-side and out of my control? I guess I'm just not sure how that application/xml is even being added into the Accept header. I can't find anything skimming through the source code.
Found the "problem". It looks like the PR I mentioned in my original post wasn't actually released until rest-client2.0.0.rc1 which is still a release candidate so it isn't actually out yet or at least obtainable via my gem update rest-client.
I used the following command to install 2.0.0rc2:
gem install rest-client -v 2.0.0.rc2 --pre
Then referenced it in my code and it works now:
#request = RestClient::Request.new(:method => :get, :url => 'http://some/resource')
puts #request.default_headers[:accept]
Prints...
*/*
As expected now.
I'm using Rack::Static (or Rack::TryStatic) to serve some static HTML, Javascript, CSS and image files as part of a Rack application, but I see that the files served by Rack::Static do not have a Content-Type header, which causes warnings in some use cases and actually breaks the behavior of other use cases.
All the files have correct extensions, but the Content-Type header is actually missing from the HTTP response. I'm running Rack using Rackup which starts a WEBRick server.
How can I get Rack::Static to set up the correct content-type when sending files?
I know this is an old post, but I just had this same problem and I hoped that the solution might help someone. Try this:
use Rack::Static, urls: {'/my-doc' => '/public/my-doc'},
header_rules: [
['/public/my-doc', {'Content-Type' => 'application/json'}]
]
How do I configure Sinatra to omit the Date & Server HTTP response headers? I also want to omit the Content-Type & Content-Length headers when there's no response body. I'm building a REST API server for an iPhone app. My iPhone app doesn't use these headers, and I want to be as efficient as possible.
I tried adding the following after filter, but the headers are still included.
after do
response.headers.delete('Date')
response.headers.delete('Server')
end
A header can be effectively deleted from a Sinatra response by setting it to an empty string. (Not nil, but '') e.g.:
get '/myroute/nodate' do
response.headers['Date']=''
body="Hello, No Date header in my header!"
end # get
I'm new to Ruby coming from Java. I'm trying to make a http get request and I'm getting an http response code of 400. The service I'm calling over http is very particular and I'm pretty sure that my request isn't exactly correct. It'd be helpful to "look inside" the req object after I do the head request (below) to double check that the request_headers that are being sent are what I think I'm sending. Is there a way to print out the req object?
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true
res = req.head(pathWithScope, request_headers)
code = res.code.to_i
puts "Response code: #{code}"
I tried this: puts "Request Debug: #{req.inspect}" but it only prints this: #<Net::HTTP www.blah.com:443 open=false>
Use set_debug_output.
http = Net::HTTP.new(url.host, url.port)
http.set_debug_output($stdout) # Logger.new("foo.log") works too
That and more in http://github.com/augustl/net-http-cheat-sheet :)
If you want to see & debug exactly what your app is sending, not just see its log output, I've just released an open-source tool for exactly this: http://httptoolkit.tech/view/ruby/
It supports almost all Ruby HTTP libraries so it'll work perfectly for this case, but also many other tools & languages too (Python, Node, Chrome, Firefox, etc).
As noted in the other answer you can configure Net::HTTP to print its logs to work out what it's doing, but that only shows you what it's trying to do, it won't help you if you use any other HTTP libraries or tools (or use modules that do), and it requires you to change your actual application code (and remember to change it back).
With HTTP Toolkit you can just click a button to open a terminal, run your Ruby code from there as normal, and every HTTP request sent gets collected automatically.
I have a ruby script that goes and saves web pages from various sites, how do i make sure that it checks if the server can send gzipped files and saves them if available...
any help would be great!
One can send custom headers as hashes ...
custom_request = Net::HTTP::Get.new(url.path, {"Accept-Encoding" => "gzip"})
you can then check the response by defining a response object as :
response = Net::HTTP.new(url.host, url.port).start do |http|
http.request(custom_request)
end
p [response['Content-Encoding']
Thanks to those who responded...
You need to send the following header with your request:
Accept-Encoding: gzip,deflate
However, I am still reading how to code ruby and dont know how to do the header syntax in the net/http library (which I assume you are using to make the request)
Edit:
Actually, according to the ruby doc it appears the this header is part of the default header sent if you dont specify other 'accept-encoding' headers.
Then again, like I said in my original answer, I am still just reading the subject so I could be wrong.
For grabbing web pages and doing stuff with them, ScrubyIt is terrific.