Why do perl dancer pages render slowly (while I'm not connected to internet)? - perl

I'm running Dancer and found it slow -- pages took a long time to render.
This is the example code from Dancer::Introduction:
#!/usr/bin/perl
# make this script a webapp
use Dancer;
# declare routes/actions
get '/' => sub {
"Hello World";
};
get '/hello/:name' => sub {
"Hello ".param('name');
};
# run the webserver
Dancer->dance;
It takes my browser 10 seconds to get&render the response( using firebug in firefox ).
And Dancer message:
[20734] core #0.000228> request: GET / from 192.168.1.101 in /usr/lib/perl5/site_perl/5.8.8/Dancer/Handler.pm l. 57
[20734] core #0.000809> [hit #44]trying to match `/' against /^\/$/ in /usr/lib/perl5/site_perl/5.8.8/Dancer/Route.pm l. 84
[20734] core #0.000953> [hit #44] --> got 1 in /usr/lib/perl5/site_perl/5.8.8/Dancer/Route.pm l. 101
[20734] core #0.001645> [hit #44]response: 200 in /usr/lib/perl5/site_perl/5.8.8/Dancer/Handler.pm l. 175
[20734] core #0.000135> request: GET /favicon.ico from 192.168.1.101 in /usr/lib/perl5/site_perl/5.8.8/Dancer/Handler.pm l. 57
[20734] core #0.000873> [hit #45]response: 200 in /usr/lib/perl5/site_perl/5.8.8/Dancer/Handler.pm l. 175
Why is Dancer so slow? Did I miss something?

Is the computer connected to internet? I got the same problem when testing from a computer not connected to internet; fixed it by deleting
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>;
from main.tt

As you can see from the debugging log, it took Dancer 0.6ms to serve the request. The problem is somewhere else in the stack. A frequent culprit is reverse DNS — the webserver tries to reverse-lookup the remote IP address for access logging purposes, and if your DNS is misconfigured, that can take quite a while (sometimes 30 or 60 seconds) before it fails.

Use Dancer::Plugin::NYTProf to profile your application. From the documentation:
By simply loading this plugin, you'll have the detailed, helpful
profiling provided by Devel::NYTProf.
Each individual request to your app is profiled. Going to the URL
/nytprof in your app will present a list of profiles.
Or, if it's a browser-side issue, you can use an extension like Firebug to see what part of a page load is slow.

Related

Pjsip/pjsua timeout errors and resolve errors calling phone numbers after registering with voip.ms from Raspberry Pi

The Goal
I'm trying to make a call to a telephone number. I'd like to be able to make a call from the raspberry pi, and also make a call to my voip.ms phone number and be able to answer or auto-answer and play some generic .wav file.
My current understanding of things
This maybe should be titled "My current misunderstanding of things". I'm new to sip and pjsip, and I think I must be missing some part of the process I don't understand. I was under the impression that, if I register with voip.ms, when I make a call it would route to voip.ms and they would do a lookup on the number/address, and then respond with an address that I would then begin to communicate with.
What I've done so far
Compiled
I've compiled Pjsip on a Raspberry Pi 3B+ properly, for what I can tell. I can include pjsua2.hpp in my c++ applications. I've roughly followed this tutorial
Tested compilation with pjsua binary && demo.cpp
I'm running into identical problems running a modified pjsua2_demo.cpp and the binary included in the pjsip build. For the sake of simplicity, I'll ask about the binary located (for me) at <project-path>/pjproject-2.8/pjsip-apps/bin/pjsua-armv7l-unknown-linux-gnueabihf.
Successfully registered with voip.ms
I have an account and phone number with Voip.ms and can become registered with voip.ms by executing the following script:
call_and_auto_answer.sh
./pjsua2-cpp/pjproject-2.8/pjsip-apps/bin/pjsua-armv7l-unknown-linux-gnueabihf \
--play-file ~/CantinaBand60.wav \
--local-port=5060 \
--auto-answer 200 \
--auto-play \
--auto-loop \
--max-calls 5 \
--config-file ./sip.cfg
Where the config looks like:
sip.cfg
#
# Logging options:
#
--log-level 5
--app-log-level 4
#
# Account 0:
#
--id sip:<my-subaccount-username>#sip.voip.ms
--registrar sip:<server-location>.voip.ms
--reg-timeout 300
--realm *
--username <my-subaccount-username>
--password <my-subaccount-password>
--use-timer 1
#
# Network settings:
#
--local-port 5060
#
# Media settings:
#
--srtp-keying 0
--auto-play
--auto-loop
--play-file /home/pi/CantinaBand60.wav
--snd-auto-close 1
#using default --clock-rate 16000
#using default --quality 8
#using default --ec-tail 200
#using default --ilbc-mode 30
--rtp-port 4000
#
# User agent:
#
--auto-answer 200
--max-calls 5
#
# SIP extensions:
#
--use-timer 1
When I enter the cli, I see for my account list:
Account list:
[ 0] <sip:192.168.1.49:5060>: does not register
Online status: Online
[ 1] <sip:192.168.1.49:5060;transport=TCP>: does not register
Online status: Online
*[ 2] sip:<my-subaccount-username>#sip.voip.ms: 200/OK (expires=285)
Online status: Online
Buddy list:
-none-
Voip.ms shows I've registered on their website.
The problem
I'm trying to call my personal cell phone from my pi (I assume using the registered voip.ms phone number), and call my pi from my personal cell phone. While calling out I'm typically getting either 408 Request Timeout errors or 502 gethostbyname errors.
Different destinations, different errors
Depending on the destination for my call from the pi, I get one of two different errors most of the time
Timeout Error
I get an error that says,
18:19:19.757 pjsua_app.c ....Call 4 is DISCONNECTED [reason=408 (Request Timeout)]
18:19:19.757 pjsua_app_comm ....
[DISCONNCTD] To: <destination-sip-address>
where is any of the following:
sip:
sip:
sip:thetestcall#sip2sip.info
sip:thetestcall#iptel.org
sip:201#ideasip.com
and the phone numbers are formatted like: 3035551234, though I've tried prepending a 1 and a +1 just to check.
Lookup Error
I get an error that says,
19:09:45.435 sip_resolve.c ....Failed to resolve '<destination-sip-address>'. Err=70018 (gethostbyname() has returned error (PJ_ERESOLVE))
19:09:45.435 tsx0x18520dc ....Failed to send Request msg INVITE/cseq=10722 (tdta0x185012c)! err=70018 (gethostbyname() has returned error (PJ_ERESOLVE))
19:09:45.435 pjsua_app.c .......Call 4 is DISCONNECTED [reason=502 (gethostbyname() has returned error (PJ_ERESOLVE))]
19:09:45.435 pjsua_app_comm .......
[DISCONNCTD] To: sip:<destination-sip-address>
where is any of the following:
sip:
sip:
sip:abcd1234
Possible Successes
I'm getting what looks like a success while calling:
sip:**12340#ideasip.com
It confirms the call and has a bunch of messages, notable including:
19:16:17.550 pjsua_core.c ....TX 1300 bytes Request msg INVITE/cseq=13899 (tdta0x15c263c) to UDP 208.97.25.11:5060:
...
19:16:17.551 pjsua_app.c .......Call 4 state changed to CALLING
...
>>> 19:16:17.606 pjsua_core.c .RX 575 bytes Response msg 100/INVITE/cseq=13899 (rdata0x6d7008a4) from UDP 208.97.25.11:5060:
...
19:16:17.609 pjsua_core.c .RX 946 bytes Response msg 200/INVITE/cseq=13899 (rdata0x6d7008a4) from UDP 208.97.25.11:5060:
...
19:16:17.609 pjsua_app.c .....Call 4 state changed to CONNECTING
...
19:16:17.610 pjsua_app.c .....Call 4 state changed to CONFIRMED
...
19:16:17.676 pjsua_core.c .RX 594 bytes Response msg 100/INVITE/cseq=13900 (rdata0x6d7008a4) from UDP 208.97.25.11:5060:
...
19:16:17.678 conference.c ......Port 5 (sip:**12340#ideasip.com) transmitting to port 5 (sip:**12340#ideasip.com)
...
19:16:17.678 conference.c ......Port 1 (/home/pi/CantinaBand60.wav) transmitting to port 5 (sip:**12340#ideasip.com)
...
19:16:36.931 pjsua_app.c ......Call 4 is DISCONNECTED [reason=200 (Normal call clearing)]
Same Network
Additionally, if I set up a second pjsip client on the same network, I can call it from pi1 and answer the call on pi2.
Incoming calls
When I register with voip.ms, then try to call my voip.ms phone number from my personal cell phone, the call fails with a message on my iPhone that says, User Busy. This makes me think I'm messing something up with the registration, or that I'm missing some component, like a subscribe or link with that voip.ms account.
Final thoughts
I'm not sure what I'm missing here. I've read through a ton of the pjsip and pjsua docs, and I can't find anything I'm missing. Does anybody have insight into how to make a call to a phone number and allow for incoming calls? This has been quite a few days of solid work.
So I figured out the answer to my question. Here's the skinny:
Voip.ms registration
My registration with voip.ms wasn't configured properly. I was given credentials by a coworker, but upon further inspection of the sip endpoint, I found that the DiD number purchased for the account wasn't associated with the subaccount my coworker created for me. So, depending on the recipient's phone carrier, I was given different errors. Additionally, when I was testing inbound calls and receiving the error, User Busy, this was because the account I registered wasn't associated with the phone number.
To fix this, on voip.ms I associated the DiD number to my subaccount, and then went to my subaccount information and set the callerId number to be my DiD number, though I think you can override this value via pjsip.
Outbound sip calls
Secondly, to call a phone number, outbound calls should follow the following format:
sip:<phoneNumber>#<endpoint>
So for me, this looked very much like:
sip:5551234567#newyork.voip.ms

LWP Won't Run in CGI Script

I have a CGI script to load publications from BibBase:
#!/usr/bin/perl
use LWP::UserAgent;
my $url = 'https://bibbase.org/show?bib=http://www.example.com/pubs.bib';
my $ua = LWP::UserAgent->new;
my $can_accept = HTTP::Message::decodable;
my $response = $ua->get($url, 'Accept-Encoding' => $can_accept);
print "Content-type: text/html\n\n";
print $response->decoded_content;
(This is copied from BibBase with the exception that the URL is hard-coded.)
I have three webservers running RHEL7 and Apache 2.4 that are configured the same way by Puppet. On all three I can run the script on the command line and get the expected results:
[root#server1 cgi-bin]# ./bibbase_proxy2.cgi | head
Content-type: text/html
<img src="//bibbase.org/img/ajax-loader.gif" id="spinner" style="display: none;" alt="Loading.." />
<div id="bibbase">
<script type="text/javascript">
var bibbase = {
params: {"bib":"http://www.example.com/pubs.bib","host":"bibbase.org"},
When I try to run the script with CGI, I get three different results:
Server1
Unrecognised protocol tcp at /usr/share/perl5/LWP/Protocol/http.pm line 31.
Server2
Can't connect to bibbase.org:443 System error at /usr/share/perl5/LWP/Protocol/http.pm line 51.
Server3
No http output and the error log says AH01215: Out of memory!.
I can't find anything different between the three servers and I can't figure out why the script works fine on the command line and doesn't work when run as a CGI.
I have selinux in permissive mode and it is logging the outgoing request, so I know the script gets that far:
type=AVC msg=audit(1532465859.921:331235): avc: denied { name_connect } for pid=161178 comm="perl" dest=80 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket
For testing, I have set selinux to disabled and restarted the server.
SE-Linux denied the TCP connection.
avc: denied { name_connect }
The default access controls for networking by SELinux are based on the labels assigned to TCP and UDP ports and sockets. For instance, the TCP port 80 is labeled with http_port_t (and class tcp_socket). Access towards this port is then governed through SELinux access controls, such as name_connect and name_bind.
When an application is connecting to a port, the name_connect permission is checked. However, when an application binds to the port, the name_bind permission is checked.
Permissive mode or not, Perl is acting like it was denied a TCP connection. Unrecognised protocol tcp means getprotobyname("tcp") failed inside IO::Socket::IP. That's very, very unusual. One of the ways that can happen is via exactly that SELinux denial.
I'm no SELinux expert, but according to RedHat and Gentoo some SELinux aware applications will ignore the global permissive setting and go it alone. RHEL 7 Apache appears to be one of them. It appears to have its own domain which must be set permissive.
On all three I can run the script on the command line and get the expected results:
There's two reasons for that, and they both have to do with users.
When you run the program you're running as your own user with your own configuration, permissions, and environment variables. In fact, you ran it as root which usually bypasses restrictions. When it runs on the server it runs as a different user, probably the web server user with severe restrictions.
In order to do a realistic test, you need to run it as the same user the web server will. You can use sudo -u for this. For example, if the user is apache...
sudo -u apache ./bibbase_proxy2.cgi
BTW Do not test software as root! Not only is it not going to give you sensible results, but if there's a bug in the software there are no safeguards preventing it from wrecking your system.
The second problem is #!/usr/bin/env perl. That means to run whatever perl is in your PATH. PATH will be different for different users. Running ./bibbase_proxy2.cgi may run with one Perl on the command line and a different one via the web server.
In a server environment, use a hard coded path to Perl like #!/usr/bin/perl.
We tested by rewriting the same script in Python and PHP. Both of them showed error which pointed us in the right direction.
Python urllib2 produced the error
<class 'urllib2.URLError'>: <urlopen error [Errno 16] Device or resource busy>
args = (error(16, 'Device or resource busy'),)
errno = None
filename = None
message = ''
reason = error(16, 'Device or resource busy')
strerror = None
PHP (run as CGI) wouldn't even start:
[Wed Jul 25 15:24:52.988582 2018] [cgi:error] [pid 10369] [client 172.28.6.200:44387] AH01215: PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/curl.so' - libssh2.so.1: failed to map segment from shared object: Cannot allocate memory in Unknown on line 0
[Wed Jul 25 15:24:52.988980 2018] [cgi:error] [pid 10369] [client 172.28.6.200:44387] AH01215: PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/dba.so' - libtokyocabinet.so.9: failed to map segment from shared object: Cannot allocate memory in Unknown on line 0
---- Similar lines for all extensions. ----
It appears that RLimitMEM blocks access to shared memory and that is required for opening sockets. I can't find any documentation, but removing that line makes it work.

why `wget` can not get redirection for certain website?

wget hangs there while it accesses the following website. But when I use a browser to access it, it will be redirected to https://nyulangone.org. Does anybody know why wget can not get redirected in this case? Thanks.
$ wget http://nyumc.org
--2018-02-20 20:27:05-- http://nyumc.org/
Resolving nyumc.org (nyumc.org)... 216.165.125.106
Connecting to nyumc.org (nyumc.org)|216.165.125.106|:80...
When I used wget on the site you mentioned, this is what I get:
--2018-02-21 21:16:38-- http://www.nyumc.org/
Resolving www.nyumc.org (www.nyumc.org)... 216.165.125.112
Connecting to www.nyumc.org (www.nyumc.org)|216.165.125.112|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 179 [text/html]
Saving to: ‘index.html’
index.html 100%[==================================>] 179 --.-KB/s in 0s
2018-02-21 21:16:38 (8.16 MB/s) - ‘index.html’ saved [179/179]
In the index.html file, which bears the logo of NYU Langone Medical Center, it says: "The following URL has been rejected for security concerns. If you believe you have received this message in error, please summit an incident with our helpdesk at 212-263-6868..." So, it may not redirect because the website can detect that you are a bot and not a browser. You could attempt to change the user agent string and other HTTP headers to avoid detection, but I'm not sure why you wouldn't just turn wget on https://nyulangone.org. Judging from information on archive.org, nyumc.org has been redirecting to other sites for at least the last 5 years. It was redirecting to http://www.med.nyu.edu until 2016, at which point it started redirecting to https://www.nyulangone.org.
I hope that helps.

How to make browser stop caching GWT nocache.js

I'm developing a web app using GWT and am seeing a crazy problem with caching of the app.nocache.js file in the browser even though the web server sent a new copy of the file!
I am using Eclipse to compile the app, which works in dev mode. To test production mode, I have a virtual machine (Oracle VirtualBox) with a Ubuntu guest OS running on my host machine (Windows 7). I'm running lighttpd web server in the VM. The VM is sharing my project's war directory, and the web server is serving this dir.
I'm using Chrome as the browser, but the same thing happens in Firefox.
Here's the scenario:
The web page for the app is blank. Accorind to Chrome's "Inspect Element" tool, it's because it is trying fetch 6E89D5C912DD8F3F806083C8AA626B83.cache.html, which doesn't exist (404 not found).
I check the war directory, and sure enough, that file doesn't exist.
The app.nocache.js on the browser WAS RELOADED from the web server (200 OK), because the file on the server was newer than the browser cache. I verified that file size and timestamp for the new file returned by the server were correct. (This is info Chrome reports about the server's HTTP response)
However, if I open the app.nocache.js on the browser, the javascript is referring to 6E89D5C912DD8F3F806083C8AA626B83.cache.html!!! That is, even though the web server sent a new app.nocache.js, the browser seems to have ignored that and kept using its cached copy!
Goto Google->GWT Compile in Eclipse. Recompile the whole thing.
Verify in the war directory that the app.nocache.js was overwritten and has a new timestamp.
Reload the page from Chrome and verify once again that the server sent a 200 OK response to the app.nocache.js.
The browser once again tries to load 6E89D5C912DD8F3F806083C8AA626B83.cache.html and fails. The browser is still using the old cached copy of app.nocache.js.
Made absolutely certain in the war directory that nothing is referring to 6E89D5C912DD8F3F806083C8AA626B83.cache.html (via find and grep)
What is going wrong? Why is the browser caching this nocache.js file even when the server is sending it a new copy?
Here is a copy of the HTTP request/response headers when clicking reload in the browser. In this trace, the server content hasn't been recompiled since the last GET (but note that the cached version of nocache.js is still wrong!):
Request URL:http://192.168.2.4/xbts_ui/xbts_ui.nocache.js
Request Method:GET
Status Code:304 Not Modified
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:192.168.2.4
If-Modified-Since:Thu, 25 Oct 2012 17:55:26 GMT
If-None-Match:"2881105249"
Referer:http://192.168.2.4/XBTS_ui.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
Response Headersview source
Accept-Ranges:bytes
Content-Type:text/javascript
Date:Thu, 25 Oct 2012 20:27:55 GMT
ETag:"2881105249"
Last-Modified:Thu, 25 Oct 2012 17:55:26 GMT
Server:lighttpd/1.4.31
The best way to avoid browser caching is set the expiration time to now and add the max-age=0 and the must-revalidate controls.
This is the configuration I use with apache-httpd
ExpiresActive on
<LocationMatch "nocache">
ExpiresDefault "now"
Header set Cache-Control "public, max-age=0, must-revalidate"
</LocationMatch>
<LocationMatch "\.cache\.">
ExpiresDefault "now plus 1 year"
</LocationMatch>
your configuration for lighthttpd should be
server.modules = (
"mod_expire",
"mod_setenv",
)
...
$HTTP["url"] =~ "\.nocache\." {
setenv.add-response-header = ( "Cache-Control" => "public, max-age=0, must-revalidate" )
expire.url = ( "" => "access plus 0 days" )
}
$HTTP["url"] =~ "\.cache\." {
expire.url = ( "" => "access plus 1 years" )
}
We had a similar issue. We found out that timestamp of the nocache.js was not updated with gwt compile so had to touch the file on build. And then we also applied the fix from #Manolo Carrasco Moñino. I wrote a blog about this issue. http://programtalk.com/java/gwt-nocachejs-cached-by-browser/
We are using version 2.7 of GWT as the comment also points out.
There are two straightforward solutions (second is modified version of first one though)
1) Rename your *.html file which has a reference to *.nocache.js to i.e. MyProject.html to MyProject.jsp
Now search the location of you *.nocache.js script in MyProject.html
<script language="javascript" src="MyProject/MyProject.nocache.js"></script>
add a dynamic variable as a parameter for the JS file, this will make sure actual contents are being returned from the server every time. Following is example
<script language="javascript" src="MyProject/MyProject.nocache.jsp?dummyParam=<%= "" + new java.util.Date().getTime() %>"></script>
Explanation: dummyParam will be of no use BUT will get us our intended results i.e. will return us 200 code instead of 304
Note: If you will use this technique then you will need to make sure that you are pointing to right jsp file for loading your application (Before this change you was loading your app using HTML file).
2) If you dont want to use JSP solution and want to stick with your html file then you will need java script to dynamically add the unique parameter value on the client side when loading the nocache file. I am assuming that should not be a big deal now for you given the solution above.
I have used first technique successfully, hope this will help.
The app.nocache.js on the browser WAS RELOADED from the web server (200 OK), because the file on the server was newer than the browser cache. I verified that file size and timestamp for the new file returned by the server were correct. (This is info Chrome reports about the server's HTTP response)
I wouldn't rely on this. I've seen a bit of strange behaviour in Chrome's dev tools with the network tab in combination with caching (at least, it's not 100% transparent for me). In case of doubt, I usually still consult Firebug.
So probably Chrome still uses the old version. It may have decided long ago, that it will never have to reload the resource again. Clearing the cache should resolve this. And then make sure to set the correct caching headers before reloading the page, see e.g. Ideal HTTP cache control headers for different types of resources.
Open the page in cognito mode just to get-rid of cache issue and unblock yourself.
You need to configure cache time as mentioned in others comments.
After unsuccessfully preventing caching via Apache I created a bash script that root runs every minute in a cron job on my Linux Tomcat server.
#!/bin/bash
#
# Touches GWT nocache.js files in the Tomcat web app directory to prevent caching.
# Execute this script every minute in a root cron job.
#
cd /var/lib/tomcat7/webapps
find . -name '*nocache.js' | while read file; do
logger "Touching file '$file'"
touch "$file"
done

Streaming Example From "Sinatra: Up and Running" Not Working

I am trying to run this example from the book Sinatra: Up and Running p. 46, but can't get it to work. Here's the program code:
require 'sinatra'
before do
content_type :txt
end
connections = []
get '/consume' do
stream(:keep_open) do |out|
# store connection for later on
connections << out
# remove connection when closed properly
out.callback { connections.delete(out) }
# remove connection when closed due to an error
out.errback do
logger.warn 'we just lost a connection!'
connections.delete(out)
end
end
end
get '/broadcast/:message' do
connections.each do |out|
out << "#{Time.now} -> #{params[:message]}" << "\n"
end
"Sent #{params[:message]} to all clients."
end
The instructions for testing the code are as follows:
It’s a little tricky to demonstrate the behavior in text, but a good demonstration would
be to start the application, then open a web browser and navigate to http://localhost:
4567/consume. Next, open a terminal and use cURL to send messages to the server.
$ curl http://localhost:4567/broadcast/hello
Sent hello to all clients.
If you look back at the web browser, you should see that the content of the page has
been updated with a time stamp and the message that you sent via the terminal. The
connection remains open, and the client continues to wait for further information from
the server.
When I follow these instruction, I get no errors, but the message "hello" does not appear in the browser. I am running Sinatra on with Webrick. Why is it not working?
Thanks!
UPDATE (Konstantin's Thin Suggestion)
I now start thin and perform the two steps described in the book and the OP. You can see that thin does indeed receive both requests. However, I am still not seeeing the output "hello" in the browser.
>rackup
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:9292, CTRL+C to stop
127.0.0.1 - - [13/Aug/2012 12:48:03] "GET /consume HTTP/1.1" 200 - 0.0900
127.0.0.1 - - [13/Aug/2012 12:48:03] "GET /favicon.ico HTTP/1.1" 404 447 0.0000
127.0.0.1 - - [13/Aug/2012 12:49:02] "GET /broadcast/hello HTTP/1.1" 200 26 0.00
00
127.0.0.1 - - [13/Aug/2012 12:57:00] "GET /consume HTTP/1.1" 200 - 0.0000
Perhaps the mistake is in my configu.ru file:
require './streaming.rb'
run Sinatra::Application
Run Sinatra on Thin. :keep_open is not supported on Webrick. Make sure you're running Sinatra 1.3.3 or later.
I had the same problem. To speed up the response, I used
before do
content_type 'text/event-stream'
end
The second route has to be a POST:
post '/broadcast/:message' do
connections.each do |out|
out << "#{Time.now} -> #{params[:message]}" << "\n"
end
"Sent #{params[:message]} to all clients."
end
After that, you will also have to POST your message to the server:
curl -vX POST 127.0.0.1:4567/broadcast/hello