How to recover from webusb response status: "babble" - javascript

I was testing the new webusb api (https://wicg.github.io/webusb/) on Chrome and was testing sending (transferOut) and receiving(transferIn) from a USB device.
It worked fine, but I tried reading less data than expected (2 bytes instead of the 3, where the length of the message is actually represented in the two first bytes).
The problem is that when I read less bytes than expected, the USB api returns the status "babble". How do I ensure normal communication after that? I can still send data, but receiving data always returns the error "DOMException: A transfer error has occured."
I tried running device.clearHalt("in", 1) (direction "in" and endpoint 1) but it also doesn't work (throws "DOMException: Unable to clear endpoint.").
Has anyone had this problem yet?
(I'm using Chrome 65.0.3325.181 on OSX)

As mentioned above I'm still investigating the the best ways to recover from the babble error but regardless the easiest way to solve this problem is to avoid calling transferIn() with a length that isn't a multiple of the endpoint's maximum packet size. It's much easier to handle the extra data in software than try to recover from a hardware protocol error.

Related

Why is my google API key breaking after 100 requests

I'm validating addresses to make sure they exist. I'm using the google API to do this. I have a google API key and it works great.... until I go over 100. At request 110 I get this
{
candidates: [],
error_message: 'You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account',
status: 'REQUEST_DENIED'
}
All I'm doing is looping through a list of addresses. It works perfectly up until then. And it's always at the exact same point.
I've tried slowing it down (thinking i'm making too many requests too quickly) by wrapping it in a while loop and only doing 50 at a time, but all that does it slow it down but still crashes at exactly 110.
Any ideas why or how or how to fix it? It is an unpaid API key if that helps (wondering if they have a request limit, I can't find anything saying they do)
While it seems most likely that you have reached the quota allowed on an non-billing account, the status code should read "OVER_QUERY_LIMIT" which indicates that you are over your quota, rather than "REQUEST_DENIED", which you are getting.
https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
Further down, on the same page you have a suggestion as to the likely cause:
"REQUEST_DENIED" indicates that the request was denied. Possibly because the >request includes a result_type or location_type parameter but does not include an >API key or client ID.
You have to set up a billing account.
Turned out to be one of the parameters I was sending to it had a special character that was breaking it. I printed out the URL before sending it to see what was going on.
TLDR had to use encodeURIComponent on the addresses I was sending, before sending them

Tomcat, service unavailable 503

My webapp uses JSP / JavaScript/ google visualization, and runs on Tomcat 7 on a 64bit windows server with enough resources dedicated to this app.It is still under testing, so, I have control over the load.
The problem is when I work from device at same network of the server, everything works fine. But when I work from device from different network with a request took a long time (more than 6 minutes) I get Service Unavailable [503] message after 6 minutes of waiting while processing in the server is going on and completed successfully. I checked the Tomcat logs but i couldn't find any thing every thing seems to be work fine. I tried different solutions but non of them worked with me:
Increase Tomcat's connector timeout.
Increase the Tomcat RAM.
Disable the server firewall
Try different browsers
Adjust the request timeout from the browser.
I experimented by setting Tomcat's Connector properties in conf/server.xml. I played around with all combinations and ranges of connectionTimeout and keepAliveTimeout.
The final configuration is:
<Connector port="80" protocol="HTTP/1.1"
address="0.0.0.0"
connectionTimeout="3600000"
redirectPort="8443" />
I'm wondering if anybody else has run into such a problem, and how they solved it.
I think you server.xml is having wrong data . Change connector port from 80 to 8080 it always allow four digit and start from 8080 not sure . please update as below
<Connector port="8080" protocol="HTTP/1.1"
address="0.0.0.0"
connectionTimeout="3600000"
redirectPort="8443" />
503 Service Unavailable
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
Note: The existence of the 503 status code does not imply that a
server must use it when becoming overloaded. Some servers may wish
to simply refuse the connection.click here for more information
let me know if you face any issue

Differentiate between different error types on image load

I'm playing around with implementing a JavaScript server ping tool based on the accepted answer given on this question: Is it possible to ping a server from Javascript?. This essentially works by assuming the pinged server is down if no response has been given after n milliseconds.
That's great, and it's a pretty cool way of doing it, however there are two rather large pitfalls:
Not all servers do respond within the allocated time.
Sometimes an ERR_CONNECTION_TIMED_OUT error is thrown before our timeout timer has finished.
Both of these things cause incorrect results. The former suggests that the server is offline when it's possibly online and responding slowly, and the latter suggests the server is online when it's (likely) offline.
In an ideal world this code would capture what type of error thrown was thrown and handle this appropriately. After all, if the error thrown is a 404 Not Found error, this counter-intuitively means the server is online and has responded.
If we log the image error event, the only thing we see surrounding the error is:
Event {
...
type: "error"
}
There's no message or anything hinting at what the error thrown was, and both the 404 and ERR_CONNECTION_TIMED_OUT errors give identical information.
What can I do to capture the ERR_CONNECTION_TIMED_OUT error I see in Chrome's JavaScript console, rather than relying on a fixed-speed timer?
Update
The best way I can replicate this issue is by altering Trante's JSFiddle demo (as linked to in the question I've linked above) to use a 30000ms timer rather than a 1500ms timer:
this.timer = setTimeout(function () {
if (_that.inUse) {
_that.inUse = false;
_that.callback('timeout');
}
}, 30000);
The 'unknown' server should obviously not respond, but instead we see this:
In Chrome's console, the following error has been thrown:
Failed to load resource: net::ERR_NAME_NOT_RESOLVED
As the Image's onerror function has been fired with the generic error as given above, the function believes this to mean that 1. 'unknown' exists, and 2. it's online. The ERR_NAME_NOT_RESOLVED error appears to be something which only Chrome is aware of, and isn't passed through to the error event at all.
Update 2
Today I tried doing this with web sockets instead of images and unfortunately these suffer from the same problem. The only data surrounding the error returned is type: "error" - no information about what the error actually was.

Is there a maximum HTTP status code message length?

I'm working on a project where I'm building the frontend and someone else is building an API. I was proposing the following structure for all requests, sent as JSON:
{
"success": true, // true/false
"message": null, // a string if success==false indicating the error
"data": {} // The actual data in the response
}
They are more interested in making the API more RESTful, and instead of a "message" field they are proposing sending a message back in the status code message, in the HTTP headers, such as:
HTTP/1.1 401 Authentication Failed for john.smith#example.com. Please log in again.
and the frontend would display "Authentication Failed for john.smith#example.com. Please log in again." in a popup or something.
I'm worried about length restrictions, but I couldn't find anything indicating no maximum length. Should we ensure we keep those messages to a minimum length? Is there a good reason to not do this, and instead send it back as content (JSON or plain text)?
A little testing will go a long way, but you should be okay to do this and in fact the RFC says specifically:
The reason phrases listed here are only recommendations -- they MAY be replaced by local equivalents without affecting the protocol.
The only possible concern you may have is header size (some servers may have limitations, but I think they are all relatively large) and how some older browsers may react to this. Frankly I think it makes more sense to use the response body since it's easier to interpret and clear, but there shouldn't be anything wrong with your approach.
I want to add, although there might be no limit in the specification, there is a real chance of implementations to truncate the status message, as I discovered, when I was trying something similar as the OP with Jetty 9.4.14 .
It took me some time to find the reason for the truncated message - there is a hard coded, not configurable limit of 1024 characters [see method getReasonBytes(String)].
(could not post this as comment due to lack of reputation)

Websocket: Browser dosn't seem to receive data from python server

I'm working on creating a websocket server via python (I'm kinda new to python) and I've made a significant progress, but I am unable to send data to the web browser. I can establish a connection and receive data from the browser, but I cannot send back data. The browser just ignores it. I would assume that if the browser received a package that didn't follow the specifications, it would terminate the connection, but the connection stays active.
Here is the method I am using to encode the data into the frame:
def encode_message(data):
frame = "\x81"
size = len(data)
if size * 8 <= 125:
frame += chr(size)
else:
raise Exception("Uh, oh. Strings larger than 125 bits are not supported")
return frame + data
I am sending the data using sock.sendall(framed_data). What could be the problem? The data for a message like "yo" ends up being 10000001 00000010 01111001 01101111 (spaces added for improved readability). Why doesn't the browser accept a message like this? Doesn't it follow the guidelines outlined in the specification? I am trying to support the most recent websocket version which I believe to be version 13. I am using python version 2.7.3.
I have tried to look at python websocket libraries' source code, but all of them seem to implement a deprecated version of the websocket protocol that has been shown to have vulnerabilities.
Here is the code that calls the function above:
def send(data):
frame = encode_message(data)
print "Sending all..."
sock.sendall(frame) #Socket that handles all communications with client
print "Frame sent :)"
return
I also downloaded wireshark to sniff the packages sent between the server and the socket. The packages sent by my server are identical to those sent from a server that is accepted by the browser. I couldn't see any difference at all. (I looked directly at the hex source)
The second byte of your transmitted message (and the length check in your code) looks wrong. The length of a message is in bytes, not bits.
From RFC6455 ยง5.2 (my emphasis)
Payload length: 7 bits, 7+16 bits, or 7+64 bits
The length of the "Payload data", in bytes: if 0-125, that is the
payload length.
The reason that nothing is received in the browser is that your message claims to have a 16 byte body. The browser will read the 2 additional bytes you send then block waiting for another 14 bytes that it expects but you don't send.
If you change the second byte to the number of bytes in the message - 0x2 or 00000010 binary - then things should work.
I finally figured out the problem! It took hours of unfun debugging and messing with my code. After closely examining the packages sent back and forth between the server and client I finally realized that there was a problem with my server's connection upgrade response. Whenever it computed a hash, it also added a \n to the end of it. That resulted in a \n\r\n at the end of one of the lines. The client interpreted that as the end of that transmission and everything that followed was parsed using WebSocket protocol. I had another line after that in the header, so it totally messed up my communications with the client. I could still read from the client, but if I tried to write to the client, the data would get messed up.

Categories