Response 411 Length Required in Gatling - scala

I'm starting in Gatling. I have 411 status and don't understand why.
Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 411 Length Required
Connection: close
Date: Tue, 13 Feb 2018 16:07:51 GMT
Server: Kestrel
Content-Length: 0
19:07:53.083 [gatling-http-thread-1-2] DEBUG org.asynchttpclient.netty.channel.ChannelManager - Closing Channel [id: 0x5f14313e, L:/10.8.1.89:52767 - R:blabla.com:5000]
19:07:53.107 [gatling-http-thread-1-2] INFO io.gatling.commons.validation.package$ - Boon failed to parse into a valid AST: -1
java.lang.ArrayIndexOutOfBoundsException: -1
...
19:07:53.111 [gatling-http-thread-1-2] WARN io.gatling.http.ahc.ResponseProcessor - Request 'HTTP Request createCompany' failed: status.find.is(200), but actually found 411
19:07:53.116 [gatling-http-thread-1-2] DEBUG io.gatling.http.ahc.ResponseProcessor -
My code:
package load
import io.gatling.core.scenario.Simulation
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class LoadScript extends Simulation{
val httpConf = http
.baseURL("http://blabla.com:5000")
.authorizationHeader("Bearer 35dfd7a3c46f3f0bc7a2f06929399756029f47b9cc6d193ed638aeca1306d")
.acceptHeader("application/json, text/plain,")
.acceptEncodingHeader("gzip, deflate, br")
.acceptLanguageHeader("ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7")
.userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36")
val basicLoad = scenario("BASIC_LOAD").exec(BasicLoad.start)
setUp(
basicLoad.inject(rampUsers(1) over (1 minutes))
.protocols(httpConf))
}
object BasicLoad {
val start =
exec(
http("HTTP Request createCompany")
.post("/Companies/CreateCompanyAndStartTransaction")
.queryParam("inn","7733897761")
.queryParam("ogrn","5147746205041")
.check(status is 200, jsonPath("$.id").saveAs("idCompany"))
)
}

When you are not sending message-body you need to add
.header("Content-Length", "0") as workaround.
I have similar issue. I'm running my tests on two environments and a difference is in application infrastructure.
Tests are passing on Amazon AWS but getting HTTP 411 on Azure. So looks like the issue is not in Gatling itself.
This issue has been also well answered by Gatling team at the and of this chat:
https://groups.google.com/forum/#!topic/gatling/mAGzjzoMr1I

I've just upgraded Gatling from 2.3 to 3.0.2. They wrote their own HTTP client and it sends now content-length: 0 except one case described in this bug:
https://github.com/gatling/gatling/issues/3648
so if you avoid using httpRequest() with method type passed as string e.g:
exec(http("empty POST test").httpRequest("POST","https://gatling.io/"))
and use post() as you do:
exec(
http("HTTP Request createCompany")
.post("/Companies/CreateCompanyAndStartTransaction")...
or
exec(
http("HTTP Request createCompany")
.httpRequest(HttpMethod.POST, "/Companies/CreateCompanyAndStartTransaction")
then upgrade Gatling to 3.0.2 is enough. Otherwise you need to wait for Gatling 3.0.3

Related

Scala WSClient cannot connect to https with no httpProxy provided

I'm facing a little issue with Scala WSClient.
I'm working on a VM with a squid proxy, and I want to only allow HTTPS proxying (blocking HTTP).
I tried a java HTTPS connection (using URLConnection), and it works fine with https proxy and https url. If I try mixing configs (proxy and url), I get this :
HTTP with http proxy : 302 answer (redirection to https)
HTTP with https proxy : UnknownHostException
HTTP with https proxy and ip resolution in /etc/hosts: SocketTimeoutException
HTTPS with https proxy : 200
HTTPS with http proxy : UnknownHostException
So we have dns issues when url protocol and proxy opened route are not matching (not sure why), but if I use HTTPS with https proxy only, I'm fine : expected result.
I tried the same with a Scala object (called from java), using also a URLConnection.
Same result, works fine (same errors when mixing proxy and protocols).
#throws(classOf[java.io.IOException])
#throws(classOf[java.net.SocketTimeoutException])
def doHttps(url: String,
connectTimeout: Int = 5000,
readTimeout: Int = 5000,
requestMethod: String = "GET") = {
import java.net.URL
import javax.net.ssl.HttpsURLConnection
val connection = (new URL("https://"+url)).openConnection.asInstanceOf[HttpsURLConnection]
connection.setConnectTimeout(connectTimeout)
connection.setReadTimeout(readTimeout)
connection.setRequestMethod(requestMethod)
connection.connect()
val headers = connection.getHeaderFields
for ((k,v) <- headers.asScala) {
if (k == null) {
println(v)
} else {
println(s"$k: $v")
}
}
}
But I need to use scala's WSClient, so I tested with it (tried both AhcWSClient and StandaloneAhcWsClient, and a problem appears. With this tool, I cannot connect to an https endpoint (here test.salesforce.com) if I don't have httpProxy allowed.
Here is the code (both ws clients) :
def wsClientTest(clientKey: String) {
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
implicit val system: ActorSystem = ActorSystem("test", ConfigFactory.defaultReference())
implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(system))
implicit val ws: AhcWSClient = AhcWSClient(AhcWSClientConfig())
val tokenEndpoint: String = s"https://test.salesforce.com/services/oauth2/token"
val query = ws.url(tokenEndpoint).withRequestTimeout(Duration.apply(5L, TimeUnit.SECONDS))
.withRequestFilter(AhcCurlRequestLogger())
.post( Map("response_type" -> "device_code", "client_id" -> clientKey));
val results = Await.result(query, Duration.apply(5L, TimeUnit.SECONDS))
println(Json.parse(results.body))
ws.close()
}
def standaloneWSClientTest(clientKey: String) {
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
implicit val system: ActorSystem = ActorSystem("test", ConfigFactory.defaultReference())
implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(system))
implicit val ws: StandaloneWSClient = StandaloneAhcWSClient()
val tokenEndpoint: String = s"https://test.salesforce.com/services/oauth2/token"
val query = ws.url(tokenEndpoint).withRequestTimeout(Duration.apply(5L, TimeUnit.SECONDS))
.withRequestFilter(AhcCurlRequestLogger())
.post( Map("response_type" -> "device_code", "client_id" -> clientKey));
val results = Await.result(query, Duration.apply(5L, TimeUnit.SECONDS))
println(Json.parse(results.body))
ws.close()
}
With that client, with only httpsProxy allowed, I get dns errors, and if I add the url/ip pair in /etc/hosts, I get a timeout.
Scala Using URLConnection (HTTPS with only httpsProxy defined)
--------------------------------------------------------------
Transfer-Encoding: [chunked]
[HTTP/1.1 200 OK]
X-Content-Type-Options: [nosniff]
X-FRAME-OPTIONS: [DENY]
Date: [Tue, 08 Feb 2022 10:03:19 GMT]
Strict-Transport-Security: [max-age=31536000; includeSubDomains]
Cache-Control: [no-cache,must-revalidate,max-age=0,no-store,private]
Content-Security-Policy: [frame-ancestors 'none', upgrade-insecure-requests]
Vary: [Accept-Encoding]
Set-Cookie: [QCQQ=bzfE6xRGxLR; path=/; secure, BrowserId=VzwVGIjGEey_0Qe3-91VQQ; domain=.salesforce.com; path=/; expires=Wed, 08-Feb-2023 10:03:19 GMT; Max-Age=31536000, LSKey-c$CookieConsentPolicy=0:0; domain=test.salesforce.com; path=/; expires=Wed, 08-Feb-2023 10:03:19 GMT; Max-Age=31536000, CookieConsentPolicy=0:0; domain=test.salesforce.com; path=/; expires=Wed, 08-Feb-2023 10:03:19 GMT; Max-Age=31536000]
Expires: [Thu, 01 Jan 1970 00:00:00 GMT]
X-XSS-Protection: [1; mode=block]
Content-Type: [text/html; charset=UTF-8]
Scala Using WSclient (HTTPS with only httpsProxy defined)
---------------------------------------------------------
INFO [main] AhcCurlRequestLogger - curl \
--verbose \
--request POST \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'response_type=device_code&client_id=test-client-id' \
'https://test.salesforce.com/services/oauth2/token'
DEBUG[main] AbstractByteBuf - -Dplay.shaded.ahc.io.netty.buffer.checkAccessible: true
DEBUG[main] AbstractByteBuf - -Dplay.shaded.ahc.io.netty.buffer.checkBounds: true
DEBUG[main] ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: play.shaded.ahc.io.netty.util.ResourceLeakDetector#3e7634b9
DEBUG[main] NettyRequestSender - Aborting Future NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHandler=play.api.libs.ws.ahc.StandaloneAhcWSClient$$anon$1#2b5825fa,
nettyRequest=play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest#53d1b9b3,
future=java.util.concurrent.CompletableFuture#2cae1042[Not completed],
uri=https://test.salesforce.com/services/oauth2/token,
keepAlive=true,
redirectCount=0,
timeoutsHolder=play.shaded.ahc.org.asynchttpclient.netty.timeout.TimeoutsHolder#163d04ff,
inAuth=0,
touch=1644314479717}
DEBUG[main] NettyRequestSender - test.salesforce.com: Name or service not known
java.net.UnknownHostException: test.salesforce.com: Name or service not known
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_281]
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929) ~[na:1.8.0_281]
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324) ~[na:1.8.0_281]
at java.net.InetAddress.getAllByName0(InetAddress.java:1277) ~[na:1.8.0_281]
at java.net.InetAddress.getAllByName(InetAddress.java:1193) ~[na:1.8.0_281]
at java.net.InetAddress.getAllByName(InetAddress.java:1127) ~[na:1.8.0_281]
at play.shaded.ahc.io.netty.util.internal.SocketUtils$9.run(SocketUtils.java:161) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.io.netty.util.internal.SocketUtils$9.run(SocketUtils.java:158) ~[scalatest-1.0-SNAPSHOT.jar:na]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_281]
at play.shaded.ahc.io.netty.util.internal.SocketUtils.allAddressesByName(SocketUtils.java:158) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.io.netty.resolver.DefaultNameResolver.doResolveAll(DefaultNameResolver.java:52) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.io.netty.resolver.SimpleNameResolver.resolveAll(SimpleNameResolver.java:81) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.io.netty.resolver.SimpleNameResolver.resolveAll(SimpleNameResolver.java:73) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.resolver.RequestHostnameResolver.resolve(RequestHostnameResolver.java:50) ~[scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequestSender.resolveAddresses(NettyRequestSender.java:357) [scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithNewChannel(NettyRequestSender.java:300) [scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithCertainForceConnect(NettyRequestSender.java:142) [scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequestSender.sendRequest(NettyRequestSender.java:113) [scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.DefaultAsyncHttpClient.execute(DefaultAsyncHttpClient.java:241) [scalatest-1.0-SNAPSHOT.jar:na]
at play.shaded.ahc.org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(DefaultAsyncHttpClient.java:210) [scalatest-1.0-SNAPSHOT.jar:na]
at play.api.libs.ws.ahc.StandaloneAhcWSClient.execute(StandaloneAhcWSClient.scala:90) [scalatest-1.0-SNAPSHOT.jar:na]
at play.api.libs.ws.ahc.StandaloneAhcWSRequest.$anonfun$execute$1(StandaloneAhcWSRequest.scala:216) [scalatest-1.0-SNAPSHOT.jar:na]
Scala Using WSclient and DNS in /etc/hosts (HTTPS with only httpsProxy defined)
-------------------------------------------------------------------------------
DEBUG[AsyncHttpClient-timer-1-1] TimeoutTimerTask - Request timeout to test.salesforce.com:443 after 5000 ms for NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHandler=play.api.libs.ws.ahc.StandaloneAhcWSClient$$anon$1#156a2245,
nettyRequest=play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest#1badde98,
future=java.util.concurrent.CompletableFuture#1f924935[Not completed],
uri=https://test.salesforce.com/services/oauth2/token,
keepAlive=true,
redirectCount=0,
timeoutsHolder=play.shaded.ahc.org.asynchttpclient.netty.timeout.TimeoutsHolder#5a90d4a3,
inAuth=0,
touch=1644314381722} after 5042 ms
DEBUG[AsyncHttpClient-timer-1-1] NettyRequestSender - Aborting Future NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHandler=play.api.libs.ws.ahc.StandaloneAhcWSClient$$anon$1#156a2245,
nettyRequest=play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest#1badde98,
future=java.util.concurrent.CompletableFuture#1f924935[Not completed],
uri=https://test.salesforce.com/services/oauth2/token,
keepAlive=true,
redirectCount=0,
timeoutsHolder=play.shaded.ahc.org.asynchttpclient.netty.timeout.TimeoutsHolder#5a90d4a3,
inAuth=0,
touch=1644314381722}
Exception in thread "main" java.util.concurrent.TimeoutException: Future timed out after [5 seconds]
at scala.concurrent.impl.Promise$DefaultPromise.tryAwait0(Promise.scala:212)
at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:225)
at scala.concurrent.Await$.$anonfun$result$1(package.scala:200)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:62)
at scala.concurrent.Await$.result(package.scala:124)
at DeviceVerificationClient$.standaloneWSClientTest(DeviceVerification.scala:59)
at DeviceVerificationClient.standaloneWSClientTest(DeviceVerification.scala)
at ScalaTest.main(ScalaTest.java:17)
DEBUG[AsyncHttpClient-timer-1-1] NettyRequestSender - Request timeout to test.salesforce.com:443 after 5000 ms
I tried disabling hostname verification (disableHostnameVerification = true), SNI, and commented inet-address dns resolver to use async-dns (provider-object = "akka.io.dns.internal.AsyncDnsProvider") but none of them work.
I'd be glad to know if I'm missing something here, a parameter to configure, an option to set...
Any help would be greatly appreciated !
Regards
Frederic Esnault

Sse stream crashed io.gatling.http.action.sse.SseInvalidContentTypeException: Server returned http response with content-type null

I am trying to set up a load test scenario with Gatling;
package mypackage
import io.gatling.core.scenario.Simulation
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration.DurationInt
class My_LoadTest extends Simulation {
val httpProtocol = http
.baseUrl("https://my-base.url")
.header("API_KEY", "my-api-key")
val scn = scenario("MyTestScenario")
.exec(
sse("mySSE").connect("/my/end-point")
.await(10.seconds)(
sse.checkMessage("data").check(regex("""event: snapshot(.*)"""))
)
)
.pause(5)
.exec(sse("Close").close)
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}
but it's continuously throwing error:
> i.g.h.a.s.SseInvalidContentTypeException: Server returned http 1 (50.00%)
response with content-type null
> Close: Client issued close order but SSE stream was already cr 1 (50.00%)
ashed: i.g.h.a.s.SseInvalidContentTypeException: Server return...
Whereas, I have already tested with CURL command (and that works fine) as;
curl 'https://my-base.url/my/end-point' \
-H 'authority: xyz’ \
-H 'accept: text/event-stream' \
-H 'API_KEY: my’-api-key \
Now, even though, Gatling claims that Gatling automatically sets Accept header to text/event-stream and Cache-Control to no-cache., but I also tried with:
val sentHeaders = Map("Content-Type" -> "text/event-stream", "API_KEY" -> "my-api-key")
val httpProtocol = http
.baseUrl("https://my-base.url")
.headers(sentHeaders)
Whatever I have tried so far, the error remains the same; Server returned http response with content-type null.
Any clue/solution/suggestion?
Check the logs. A Server Sent Event stream must have a Content-Type header of text/event-stream, see specification. It looks like your stream is malformed.

Gatling.bat Command-line options, how do they work?

When I add the command-line option "-simulation" as per the Gatling web site to the "gatling.bat" file, which comes as part of the "gatling-charts-highcharts-bundle-3.3.1" download.
I get an error saying "Warning: Unknown option -simulation"
I don't understand why?
Im using Visual Studio Code and running "gatling.bat" from the Powershell Terminal window.
If i don't put any command-line options it runs as expected.
Here is some of my code and galting website screenshots
Gatling Website Screensots
Note it says that Gatling can be started
My Simulation Code
Note the classname is "AllTests"
package api
//Import API Object's to include in test
import api1.{foo => foofoo}
import api2.{bar => barbar}
//Gatling and Scala imports
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import java.util.concurrent.ThreadLocalRandom
import com.typesafe.config._
class AllTests extends Simulation {
/*
val conf = ConfigFactory.load("application.conf");
val baseUrl = conf.getString("base-app.baseurl")
*/
val httpProtocol = http
.baseUrl("https://api.accp.qqq/")
.header("Sec-Fetch-Site","same-origin")
.header("Sec-Fetch-Mode","cors")
.header("Sec-Fetch-Dest","empty")
.acceptHeader("application/json")
.acceptLanguageHeader("en-US,en;q=0.9")
.acceptEncodingHeader("gzip, deflate, br")
.userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38")
setUp(
foofoo.users.inject(atOnceUsers(1)),
barbar.users.inject(atOnceUsers(1))
).protocols(httpProtocol)
}
Here is the "gatling.bat" with the command-line option
Note the warning
C:\Users\xxx\source\perfrepo\Test01\bin> .\gatling.bat -simulation AllTests
GATLING_HOME is set to "C:\Users\xxx\source\perfrepo\Test01"
JAVA = ""C:\Program Files\Java\jdk-11.0.2\bin\java.exe""
Warning: Unknown option -simulation
Warning: Unknown argument 'AllTests'
Choose a simulation number:
[0] computerdatabase.advanced.AdvancedSimulationStep01
[1] computerdatabase.advanced.AdvancedSimulationStep02
[2] computerdatabase.advanced.AdvancedSimulationStep03
[3] computerdatabase.advanced.AdvancedSimulationStep04
[4] computerdatabase.advanced.AdvancedSimulationStep05
[5] api.AllTests
That's a error in our documentation generation, where -- (double dashes) were transformed into single ones (see doc sources).

403 response with HttpClient but not with browser

I’m having a problem with the HttpClient library in java.
The target web site is on SSL (https://www.betcris.com), and I can load the index page from that site just fine .
However, the different pages showing odds for the different sports returns a 403 response code with HttpClient, but loading the same pages in a browser works just fine.
Here is such a page : https://www.betcris.com/en/live-lines/soccer.
I started troubleshooting this page with the information gathered by HttpFox (a Firefox add-on that resembles LiveHttpHeaders), making sure I had all the correct request headers and cookies, but I couldn’t get it to load using HttpClient. I also determined that cookies have nothing to do with the problem, as I can remove all cookies for that web site within my browser, and then hit the page directly and it will load.
I confirmed that there’s something special going on with these pages by using the online tool at http://www.therightapi.com/test. This tool allows you to input the url of a page along with any Request header you want, and shows you the response you get from the target web site. Using that tool, I can load https://www.google.com just fine, but I get the same 403 error when trying to load https://www.betcris.com/en/live-lines/soccer.
Here's my setup at therightapi :
And the response :
Does anyone know what’s going on here ?
Thanks.
EDIT : I've created a test project, here's the java code, followed by the maven dependency you should have in your pom :
package com.yourpackage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
public class TestHttpClient {
public static void main(String[] args) {
String url = "https://www.betcris.com/en/live-lines/soccer";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
// add request header
request.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0");
try {
HttpResponse response = client.execute(request);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
I have solved this problem (avoiding 403) by setting up User-Agent property while making a request as like follow:
If you use HttpClient
HttpGet httpGet = new HttpGet(URL_HERE);
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
If you use HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
I use the following code to consume HTTPS Urls:
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
...
SSLContext sslContext =
new SSLContextBuilder().loadTrustMaterial(null, (certificate, authType) -> true).build();
try (CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext)
.setSSLHostnameVerifier(new NoopHostnameVerifier()).build()) {
HttpGet httpGet = new HttpGet("YOUR_HTTPS_URL");
httpGet.setHeader("Accept", "application/xml");
httpGet.setHeader("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
HttpResponse response = httpClient.execute(httpGet);
logger.info("Response: " + response);
}
pom.xml:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
In my case, the web server does not use a proxy to communicate with APIs.
I just disbaled the defaultproxy under system.net in web.config.
<system.net>
<defaultProxy enabled="false" />
</system.net>
403 Forbidden is used to signal an authentication requirement. In fact, the full 403 response should tell you exactly that. Luckily, HttpClient can do authentication.

Play 2.2.x 2.3.x check if a http request comes from mobile browser

I have a scala action like this:
def myAction(myParam: String) = Action { implicit request =>
}
How can I check if a request is from mobile browser? I searched and found nothing online.
To do this you can inspect "User-Agent" header in the request.
You can get regexp that matches mobile user agents from JSP snippet located here (JSP is based on Java and you can use Java's regexp-related classes and patterns in Scala, so you won't have to do much to use it in your code).
To get user agent you can use something like this:
request.headers().get("User-Agent")
Example of user agent check:
val ua = "Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
if (ua.matches("(?i).*((android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino).*")||ua.substring(0,4).matches("(?i)1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-")) {
println("mobile")
} else {
println("not mobile")
}