How to detect if request came from mobile device - mobile

On server side is there any way to detect that particular request to API came from mobile device (from mobile app)?
I know about user agent sniffing but I dont like this aproach from few enough reasons not to implement it.
I also know I could add some flag to request when it comes from my mobile app, but this seems bit dirty as well.
Are there actually any 'proper' ways to do it?
I guess it doesn't change much but my backend is in node.js.
Greetings, thanks!
Tom

The general answer is no. You get a header / message from a device. All you know about the device is in the header and the device can write what it wants in it. If you are talking about http requests (which is indicated by agent lookup) you can look at a header here:
All you can do "reliable" is to look for the user agent. In my case it is Mozilla Firefox on Linux. But I could fake it if I want.
Host: somesite.org
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://somesite.org/index.php?page=2
Cookie: rteStatus=rte;
Cache-Control: max-age=0
Maybe you can get some informations from the referer if it is some chromium-mobile site or you can have a look at Accept and Accept-Enconding, maybe some mobile browsers accept different stuff. But there is no reliable way to determine the device but by its user Agent via header.
An other approach is to look if the request comes from an IP known as 3G or 4G pool. But this would just work if the requests is not coming via WLAN / WIFI. And I am not sure if a list of 3G / 4G IP address pools exists.

You can use UserAgent string for detecting. Below code in C#.
public bool IsMobileDevice(HttpRequest r){
String userAgetnt = r.UserAgent;
String deviceName = "Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini";
return Regex.IsMatch (r.UserAgent, deviceName);
}

To detect if request came from mobile app, you must pass Accept:application/json in each request, then in your controller detect if request expects or wants json, if request expects json then return json response otherwise do what you want.

Related

Alexa skill hosted on Web Service using ngrok : This combination of host and port requires TLS

I am trying to host alexa skill on my webservice.
For testing purpose, I am using ngrok to generate https webservice url.
I have added the URL into alexa configuration.
When I try to test the service, I can see my local ngrok server is receiving the request as below.
GET /alexa/service/processrequest
Summary
Headers
Raw
Binary
GET /alexa/service/processrequest HTTP/1.1
Host: 9286ef9a.ngrok.io
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
X-Forwarded-Proto: https
X-Forwarded-For: 49.248.168.79
However, its not reaching to my webservice/skill code which I am debugging through eclipse remote breakpoints.
In ngrok, I can see an error below:
HTTP/1.1 400
Content-Type: text/plain;charset=ISO-8859-1
Connection: close
Bad Request
This combination of host and port requires TLS.
I have configured spring-boot to run on https port 443 by generating a self signed certificate. The same certificate is uploaded to alexa developer console.
If I hit my webservice url in google chrome using ngrok url, it gives same error:
But if i use localhost in my url, then chrome is able to detect the https as below:
I am not able to locate the root cause.
Can anyone here please help me ?
I have found answer to my question and I am posting it so that it can help others to understand what to do in above scenario.
Spring-boot was creating https endpoint for my webservice on port 443.
In chrome, if I hit this port with https url, it was working but if i hit this port with http url, the error was coming as in above screenshot.
So, overall, spring-boot was saying that a request is coming to an http endpoint when it was supposed to be received at https endpoint.
The culprit was NGROK. :-(
Though, ngrok was creating an https endpoint for public access, it was not creating https tunnel from ngrok client (running on my pc) to tomcat server.
Using -tls option, ngrok supports https/tls tunneling but that happens only in paid plans of ngrok.
Similar to ngrok, I also explored localtunnel, but it too has the same problem of tls tunneling.
The workaround
Since, I was doing all this to debug skill development on my local machine, I tried other option of certificate provision mentioned at point 2 here.
This option allows me to use local web server as http only which now can be well supported by ngrok or localtunnel. :-)
So, following steps I had taken to enable debugging Alexa Skill during developemnt:
Use 2nd option of SSL Provisioning in Alexa Web Console.
Removed local SSL endpoints and run tomcat on plain http instead of https.
Used ngrok https endpoint in Alexa web console.
we can sign up on ngrok and set the authtoken (Steps on https://dashboard.ngrok.com/get-started/your-authtoken)
Then use ngrok http https://localhost:8081, then ngrok forwards it to https

How to get the custom header values in the angular application when application open

I have Angular application A, that will open by other application B, while opening application by B, they will send one attribute in the request header, how can i accesses, that custom header in my angular application when its opening, the custom header i can seen tcpdump.
Below is the header, i want accesses 'acbd' value
Connection: keep-alive
Referer:
User-Agent: Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Desire Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Accept-Encoding: gzip,deflate
Accept-Language: en-US
Accept-Charset: utf-8, iso-8859-1, utf-16, *;q=0.7
Cookie: NG_TRANSLATE_LANG_KEY=%22en%22
**abcd: 13223223**
Http headers are not accesible via Javascript (only http-referer and http-user-agent via object properties, and http-cookie). If you need to pass some value from one application to another, you can use cookies and retrieve value parsing document.cookie variable.
Edit: Headers can be accessed via XmlHttpRequest object when using Ajax requests, but only restricted to simple response headers, and additional restrictions by CORS if your request is cross-domain. Some cookies marked as Http-only cannot be accessed via Javascript.

POST with JSON has intermitent WebAPI resolution issue

This error has perplexed me. I have been working on this application for a year now and one of the most original parts of it just started failing for no apparent reason. I haven't made any configuration changes or changes in and around the area which is failing, so it is baffling me.
Requirement
In my SPA, click on a button and the JSON model associated to that button is sent to the server to be saved.
Implementation
return $resource('/api/audits/:auditId/auditAnswers', { auditId: auditId, auditAnswer: auditAnswer }).save(auditAnswer);
This in turn is handled by WebAPI 2.0
[Route("api/audits/{auditId}/auditAnswers")]
[HttpPost]
public ServiceResult SaveAuditAnswerByAudit(HttpRequestMessage request, Guid auditId, [FromBody]AuditAnswerModel auditAnswer)
{ ... }
Issue
This worked for a good year without issue. Now when I test in Firefox 46.0.1 hosted in IIS Express, only about 1 in 5 attempts actually reaches the WebAPI method. No other post seems to reach WebAPI at all.
The error occurs as soon as I attempt the post, so it does not seem like it's timing out, either.
Firefox reports
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length 348
Content-Type application/json;charset=utf-8
Host localhost:61032
Referer http://localhost:61032/QAT/Audits/f3fa490d-6324-4227-b8fa-a6be4d33dd82
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Also, no HTTP status code is reported.
The error Callback for $resource is called and the response object contains:
data null
status 0
statusText ""
I have come across this once already and fixed it by not posting the entire JSON to WebAPI, but there are times I need to do this and consider it the correct way to do so.
Thinking it may be browser related I have restarted the browser, computer, cleared cached, and none of these methods resolved the issue. However, using a different browser such as Chrome does not encounter this issue (yet).
The fact that it works "eventually" (after about 5 attempt) is most concerning to me.
Question
Is this a known issue? Is it my fault? Is there something I can do to fix it?

Rebuild request header from HTTP proxy server to Remote Server in C

I need to develop an HTTP proxy server. My proxy server is able to retrieve the HTTP request from web brownser. And I also able to connect to the server. I am not able to understand how to move further:
It how send the request to the Remote Server from proxy server.
I have following queries:
The format of request header to be send from HTTP proxy server to Remote Server
Is it the same header I received from the web brownser for GET,HEAD and POST methods.
I have tried sending the entire header:
GET http://www.gmail.com/ HTTP/1.1
Accept: text/html, application/xhtml+xml, /
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: www.gmail.com
Or:
GET / HTTP/1.1
Host:www.gmail.com:80
The fundamental transformation you need to do from a proxy request to an HTTP server request is to change the first line:
GET http://www.gmail.com/ HTTP/1.1
to
GET / HTTP/1.1
The full URL is required when the browser sends the request to the proxy, so that the proxy can make the further connection to the real server. However, an HTTP request to the server must not contain the protocol and hostname parts on the GET line.
However, this may not be the only thing you need to do. An HTTP proxy is a fairly complex application, due to things like different protocol version numbers and connection options on the browser-proxy connection versus the proxy-server connection.
RFC 2616 contains a considerable amount of information regarding the correct behaviour of HTTP proxy applications.

How to live stream video using C program. What should be the HTTP reply ? How can I use chunked encoding if possible?

(the actual question has been edited because I was successful doing live streaming, BUT NOW I DO NOT UNDERSTAND THE COMMUNICATION between client and my C code.)
Okay I finally did live streaming using my C code. BUT I COULD NOT UNDERSTAND HOW "HTTP" IS WORKING HERE.
I studied the communication b/w my browser and the server at the link http://www.flumotion.com/demosite/webm/ using wireshark.
I found that the client first sends this GET request
GET /ahiasfhsasfsafsgfg.webm HTTP/1.1
Host: localhost
Connection: keep-alive
Referer: file:///home/anirudh/Desktop/anitom.html
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.98 Safari/534.13
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Range: bytes=0-1024
to this get request the server responds by sending this reply
HTTP/1.0 200 OK
Date: Tue, 01 Mar 2011 06:14:58 GMT
Connection: close
Cache-control: private
Content-type: video/webm
Server: FlumotionHTTPServer/0.7.0.1
and then the server sends the data until the client disconnects. The client disconnects when it receives a certain amount of data. The CLIENT then connects to the server on a new port and the same GET request is sent to the server. The server again gives the same reply but this time the client does not disconnect but continuously reads the packets until the server disconnects. I wrote a C code which in which I have a server socket which replicates the above behavior. (thanks to wireshark, flumotion and stackoverflow)
BUT BUT BUT, I could not understand why does the client need to send two requests and why does it resets on the first request and again send the same request on a new port and this time it listens to the data as if its getting live streamed.
Also I do not know how I can live stream using chunked encoding.
The same thing in detail is available here : http://systemsdaemon.blogspot.com/2011/03/live-streaming-video-tutorial-for.html
and here http://systemsdaemon.blogspot.com/2011/03/http-streaming-video-using-program-in-c.html
Please help me out. Thanks in advance.
The first request is limited to 1024 bytes in order to test that the stream is actually a valid video source and not say a 600MB Windows executable.

Resources