HTTPS POST with Scala and Dispatch - scala

I am trying to do a HTTPS post with scala and the Dispatch library. I can't find where to mark my connection as being https not http. Here is the code I have so far
println("Running Test")
val http = new Http
val req = :/("www.example.com" , 443) / "full/path.asp"
var response: NodeSeq = Text("")
http(req << "username=x&password=y" <> {response = _ } )
response
println("Done Running Test")
EDIT
So After attempting to figure this out I traced down what was needed the http line needs to look like this
http(req.secure << "username=x&password=y" <> {response = _ } )
Also In this specific instance I needed to POST as application/x-www-form-urlencoded that required the line to look like this
http(req.secure << ("username=x&password=y","application/x-www-form-urlencoded") <> {response = _ } )
This will now replace 40 Lines of C++ + Boost + Asio code.

So After attempting to figure this out I traced down what was needed the http line needs to look like this
http(req.secure << "username=x&password=y" <> {response = _ } )
Also In this specific instance I needed to POST as application/x-www-form-urlencoded that required the line to look like this
http(req.secure << ("username=x&password=y","application/x-www-form-urlencoded") <> {response = _ }

You could apply "secure" to the :/ factory:
:/("host").secure

Related

Play Framework - edit Sec-WebSocket-Protocol in Web socket Response Header

Edit the Web socket header response sent from server to client.
I am creating a websocket server application using playframework. Right now the websocket response from the server is
taken care by Play. Following is the response header,
Request Header:
(UpgradeToWebSocket,),
(Host,localhost:8083),
(Connection,Upgrade),
(Upgrade,websocket),
(Sec-WebSocket-Version,13),
(Accept-Encoding,gzip, deflate, br),
(Accept-Language,en-US,en;q=0.9),
(Sec-WebSocket-Key,ZvfzpVo3EX4DFA4BRcgRIA==)
def chatSystem(): WebSocket = WebSocket.acceptOrResult[String, String] { request =>
Future.successful{
AuthenticationService.doBasicAuthentication(request.headers) match {
case Results.Ok => Right(ActorFlow.actorRef { out => ChatServiceActor.props(out) })
case _ => Left(Unauthorized)
}
}
}
I want to validate Sec-WebSocket-Protocol if it is present in the request header or add the same with value in the server response if it is not present.
I used the following code:
// Defined at http://tools.ietf.org/html/rfc6455#section-4.2.2
val MagicGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
def websocketAcceptForKey(key: String): String = {
val sha1 = MessageDigest.getInstance("sha1")
val salted = key + MagicGuid
val hash = sha1.digest(salted.asciiBytes)
val acceptKey: String = Base64.rfc2045().encodeToString(hash, false)
acceptKey
}
Use it like the following:
val wsKey: Optional[HttpHeader] = request.getHeader("Sec-WebSocket-Key")
val wsAccept = if (wsKey.isPresent) Some(RawHeader("Sec-WebSocket-Accept", websocketAcceptForKey(wsKey.get.value()))) else None

Groovy script for Jenkins: execute HTTP request without 3rd party libraries

I need to create a Groovy post build script in Jenkins and I need to make a request without using any 3rd party libraries as those can't be referenced from Jenkins.
I tried something like this:
def connection = new URL( "https://query.yahooapis.com/v1/public/yql?q=" +
URLEncoder.encode(
"select wind from weather.forecast where woeid in " + "(select woeid from geo.places(1) where text='chicago, il')",
'UTF-8' ) )
.openConnection() as HttpURLConnection
// set some headers
connection.setRequestProperty( 'User-Agent', 'groovy-2.4.4' )
connection.setRequestProperty( 'Accept', 'application/json' )
// get the response code - automatically sends the request
println connection.responseCode + ": " + connection.inputStream.text
but I also need to pass a JSON in the POST request and I'm not sure how I can do that. Any suggestion appreciated.
Executing POST request is pretty similar to a GET one, for example:
import groovy.json.JsonSlurper
// POST example
try {
def body = '{"id": 120}'
def http = new URL("http://localhost:8080/your/target/url").openConnection() as HttpURLConnection
http.setRequestMethod('POST')
http.setDoOutput(true)
http.setRequestProperty("Accept", 'application/json')
http.setRequestProperty("Content-Type", 'application/json')
http.outputStream.write(body.getBytes("UTF-8"))
http.connect()
def response = [:]
if (http.responseCode == 200) {
response = new JsonSlurper().parseText(http.inputStream.getText('UTF-8'))
} else {
response = new JsonSlurper().parseText(http.errorStream.getText('UTF-8'))
}
println "response: ${response}"
} catch (Exception e) {
// handle exception, e.g. Host unreachable, timeout etc.
}
There are two main differences comparing to GET request example:
You have to set HTTP method to POST
http.setRequestMethod('POST')
You write your POST body to outputStream:
http.outputStream.write(body.getBytes("UTF-8"))
where body might be a JSON represented as string:
def body = '{"id": 120}'
Eventually it's good practice to check what HTTP status code returned: in case of e.g. HTTP 200 OK you will get your response from inputStream while in case of any error like 404, 500 etc. you will get your error response body from errorStream.

How to make proper https request using Finagle to Telegram API

Currently i working at simple bot that will have a telegram interface. The problem is, that finagle have means to make http request, but i have no clue how to make https request.
I tried to make https request with scala-library finagle to telegram bot API:
val service: Service[http.Request, http.Response] = Http.client.withTlsWithoutValidation.newService("api.telegram.org:443")
val request = http.Request(http.Method.Get,bottoken + "/getMe")
request.host = "api.telegram.org"
val t = Await.result(service(request) onSuccess(a => a) onFailure( exc => println("Auth check failed : " + exc.toString )))
if (t.status == Status.Ok) {
println("Auth check success")
} else {
println("Auth check failed : " + t.toString + "\r\n" + t.contentString)
}
Every time i run this code it yields 400 Bad Request http response.
Http.client.withTls("api.telegram.org")
yields the same result.
What am i doing wrong?
You have to add in the Request the http protocol.
val request = http.Request(http.Method.Get, "http://yourholeHost/getMe")

akka-http how to accept invalid URI [will not solve]

I am developing a service that is called on one path with different query parameters. I have bind a Route to Http:
val route: Route = {
get {
pathPrefix("myRoute"){
parameterMap{ params =>
complete(
MyHandler.genExternResponse(params)
)
}
}
}
val bindingFuture = Http().bindAndHandleAsync(Route.asyncHandler(new myEndpoint().route), "localhost", 8081)
Since i have no influence on what parameters are used, i can't eliminate the calls that contain not-encoded special chars like German umlauts or trademark signs.
for example
www.myhost.com/myRoute?param1=asd&param2=adäöü
I know that those URLs are not valid But one of the requirements is that even requests with those chars are accepted und that i handle them with URL encoding.
The problem is that when i call the service like above, akka-http rejects the request with the Response-status 400 without even handing it to my code.
Is there a way that i can catch those request and handle them by myself or let akka-http URL-encode the special chars for me.
edit:
will not solve
Try This
val route: Route = {
get {
pathPrefix("myRoute"){
parameters('params)
{ params =>
complete(
MyHandler.genExternResponse(params)
)
}
}
}
val bindingFuture = Http().bindAndHandleAsync(Route.asyncHandler(new myEndpoint().route), "localhost", 8081)

HTTP4S client. How to get the exact request and response body

I am writing a small http4s client
val client = SimpleHttp1Client()
val uri = Uri.fromString(requestUrl).valueOr(throw _)
val task = POST(uri, UrlForm("username" -> userName, "password" -> password)).map{request => println("request: " + request.body)}
try {
val response = client.expect[String](task).unsafePerformSync
println("token: " + response)
response
} catch {
case e: Exception => println(e.getMessage);"BadToken"
}
The output is like
[info] Running com.researchnow.nova.shield.NovaShieldSetup
[info] Emit(Vector(ByteVector(44 bytes, 0x757365726e616d653d616268737269766173746176612670617373776f72643d41726)))
[info] Failed: unexpected HTTP status: 400 Bad Request
[info] token: BadToken
How to convert the binary request body to String? I want to see the body and headers in clear text.
I had a conversation with the http4s team on gitter and found the response. since gitter talk is not returned by google I am putting the answer here
val loggedReq = req.copy(body = request.body.observe(scalaz.stream.io.stdOutBytes))
println(loggedReq)
this prints all the headers. If we do something with the loggedReq then we get the entire body which is posted
loggedReq.as[String].run