Grails/Groovy URL .getText receive status - http

I'm including some wordpress contents to my grails app with a customTag
everything works fine.Now i want to render some standard-text if the url's status-code is not 200 OK
i have this so far
def wordpressHp = { body ->
// def url = grailsApplication.config.wordpress.server.url+'?include=true'
def url = "http://www.dasdasdasgsdniga.nd"
def content
try{
content = url.toURL().getText(connectTimeout: 10000)
}catch(e){
content="SORRY WORDPRESS IS CURRENTLY NOT AVAILABLE"
}
out << content
}
The correct url is commented out, i now expect the try to fail.
But instead of faling it's rendering some dns-error page of my provider.
So i think i have to look for http-status code, but how do i do that ?
for any hint, thanks in advance

You could try:
def url = "http://www.dasdasdasgsdniga.nd"
def content
try {
content = url.toURL().openConnection().with { conn ->
readTimeout = 10000
if( responseCode != 200 ) {
throw new Exception( 'Not Ok' )
}
conn.content.withReader { r ->
r.text
}
}
}
catch( e ) {
content="SORRY WORDPRESS IS CURRENTLY NOT AVAILABLE"
}

Related

How to stream Vertx request directly to file via pipe

I am using Vertx. 4.0.3 and trying to stream a request body directly to a file. For that purpose I am using the following (Kotlin) code:
router.post("/upload").handler { ctx ->
val startTime = System.currentTimeMillis()
val response = ctx.response()
val request = ctx.request()
val fs = vertx.fileSystem()
fs.open("data.bin", OpenOptions()) { res ->
if (res.succeeded()) {
val asyncFile = res.result()
request.pipeTo(asyncFile).onComplete { writeResult ->
if(writeResult.succeeded()) {
response.end("${System.currentTimeMillis() - startTime}")
} else {
response.setStatusCode(500).end(res.cause().stackTraceToString())
}
}
} else {
response.setStatusCode(500).end(res.cause().stackTraceToString())
}
}
}
Unfortunately I am getting an exception like:
java.lang.IllegalStateException: Request has already been read
at io.vertx.core.http.impl.Http1xServerRequest.checkEnded(Http1xServerRequest.java:628)
at io.vertx.core.http.impl.Http1xServerRequest.endHandler(Http1xServerRequest.java:334)
at io.vertx.core.http.impl.Http1xServerRequest.endHandler(Http1xServerRequest.java:60)
at io.vertx.core.streams.impl.PipeImpl.<init>(PipeImpl.java:35)
at io.vertx.core.streams.ReadStream.pipeTo(ReadStream.java:119)
at io.vertx.ext.web.impl.HttpServerRequestWrapper.pipeTo(HttpServerRequestWrapper.java:410)
at fileupload.AppKt$main$2$1.handle(App.kt:60)
at fileupload.AppKt$main$2$1.handle(App.kt)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:124)
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Since I do nothing to the request I have no idea where my request is already read. Can someone please give me some insights into this? Thanks!
This happens because by the time the callback of fs.open is invoked, the request has been fully read already.
You must pause the request before opening the file and resume it after:
router.post("/upload").handler { ctx ->
val startTime = System.currentTimeMillis()
val response = ctx.response()
val request = ctx.request()
val fs = vertx.fileSystem()
// Pause
request.pause()
fs.open("data.bin", OpenOptions()) { res ->
// Resume
request.resume()
if (res.succeeded()) {
val asyncFile = res.result()
request.pipeTo(asyncFile).onComplete { writeResult ->
if(writeResult.succeeded()) {
response.end("${System.currentTimeMillis() - startTime}")
} else {
response.setStatusCode(500).end(res.cause().stackTraceToString())
}
}
} else {
response.setStatusCode(500).end(res.cause().stackTraceToString())
}
}
}
Vert.x for Kotlin provide a equivalent set of suspend functions. In your case you may want to implement the equivalent openAwait and pipeToAwait functions in order to avoid the "callback hell". Now your code might look like this:
router.post("/upload").handler { ctx ->
val startTime = System.currentTimeMillis()
val response = ctx.response()
val request = ctx.request()
val fs = vertx.fileSystem()
val asyncFile = fs.openAwait("data.bin", OpenOptions())
val result = request.pipeToAwait(asyncFile)
// code for sending http response
}

How to use trigger variables in the message of the raised alert in Kibana ElasticSearch open distro

I am using elastic search open distro.This is my trigger condition :
for (int i = 0; i < ctx.results[0].hits.hits.length; i++) {
if(2 < ctx.results[0].hits.hits[i]._source.responseTime) {
score = true;
} else {
score = false;
}
}
return score;
I am trying to send the message with the specific details of my source with the API url and response time, something like below just for all raised alerts(how do we ensure that):
Monitor {{ctx.monitor.name}} just entered alert status. Please investigate the issue.
- **API Url : {{ctx.results.0.hits.hits.0._source.msg}} and response time {{ctx.results.0.hits.hits.0._source.responseTime}}** -- **need details only for raised alerts**
- Trigger: {{ctx.trigger.name}}
- Severity: {{ctx.trigger.severity}}
//painless trigger script
def errorCodes = new ArrayList();
for (def item : ctx.results[0].aggregations.mystats.bysats.buckets) {
if(item.val1 > 5) {
resMessate.add(item.key);
}
}
// at the end..
ctx.results[0].hits["customerror"] = errorCodes; `
//Now the custom error can be accessed from trigger Action template message format
//i.e
{
{{#ctx.results.0.hits.customerror}}
"erroIn": {{.}}
{{/ctx.results.0.hits.customerror}}
}

Load Image in async and update table cell in main thread

I get the following error when I try to load images from URL in async and render them in the main thread.The app is build with Xcode9-beta.
UIImageView.image must be used from main thread only
The images update only if I press on a cell in the tableView(and only for that particular button):
func updateUI(partyRock: PartyRock) {
videoTitle.text = partyRock.videoTitle
let url = URL(string: partyRock.imageURL)!
DispatchQueue.global().async {
do {
let data = try Data(contentsOf: url)
DispatchQueue.global().sync {
self.videoPreviewImage.image = UIImage(data: data)
}
} catch {
// handle error
}
}
}

Issue getting a .dll to load in iis 7

We have a .dll file that was written in 06, and according to .net reflector, it's not a .net assembly.
What this .dll does is allow for tests to be run from the browser, either remotely or on the server against IIS. When our customer had his server on Windows 2003, he had no issues. Since moving to 2008, he's not been able to get this functionality to work correctly.
I've been tasked with figuring out why.
The area tat calls this .dll is thus:
Spy.prototype.SendCommand = function( command )
{
var xmlDoc = null;
var url = this.urlBase + command;
if( "" != this.commandCode )
{
url += "&code=" + this.commandCode;
}
try
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
var rc = xmlDoc.load( url );
if( 4 == xmlDoc.readyState )
{
var err = xmlDoc.parseError;
if (err.errorCode != 0)
{
LogError( "parsing error: " + err.reason );
xmlDoc = null;
}
}
else
{
LogError( "unable to load: " + url );
xmlDoc = null;
}
}
catch( e )
{
LogError( e.description );
xmlDoc = null;
}
return xmlDoc;
}
and thus:
Spy.prototype.AcquireControl = function( useForceIfNecessary )
{
var success = false;
var xmlDoc = this.SendCommand( "acquire" );
var state = this.ProcessState( xmlDoc );
if( null != state )
{
success = ( "" != this.commandCode );
if( !success && useForceIfNecessary )
{
// Unable to acquire control so applying force.
xmlDoc = this.SendCommand( "acquire/force" );
state = this.ProcessState( xmlDoc );
if( null != state )
{
success = ( "" != this.commandCode );
if( !success )
{
LogError( "unable to acquire control of spy" );
}
}
else
{
LogError( "No response from spy (with force)." );
}
}
}
else
{
LogError( "No response from spy (without force)." );
}
return success;
}
What's returned is a parsing error from xmldocument.
The URL being passed is the root folder, with the name of the dll in it, as well as the command 'acquire' which is an internal command to the .dll near as I can tell.
Has anyone run into odd issues such as this? I've looked at security settings, and made sure I had script/execute allow. I do have compatibility with iis 6.0 installed.
Could this be simply calling a very old dll on an updated server? If so, how would I get around/fix this?
I don't have access to the source code on our dll. I was able to decompile it with hopper, and that's what led me to understand the command being passed 'acquire', 'acquire/force' were internal to the .dll.
When I try to go to this .dll directly from the browser instead of going through code, I receive this error:
HTTP Error 500.0
With these details:
Module IsapiModule
Notification ExecuteRequestHandler
Handler ISAPI-dll
Error Code 0x8007007f
Requested URL /mymachine:80/ourwebap/ourdll.dll/acquire
Physical Path C:\Program Files (x86)\our folder\ourwebappp\www\ourdll.dll\acquire
Logon Method Negotiate
Logon User **
I receive the same error if I remove the \acquire switch from the entered url request.
Any ideas?
Apparently, the issue is with the dll itself.
According to this article:
http://bytes.com/topic/net/answers/281186-isapi-dll-net-clr
IIS needs a dll to have these exports:
GetExtensionVersion
HttpExtensionProc
TerminateExtension
Our DLL does not have these exports. The only ones it as are
GetFilterVersion
HttpFilterProc
So, this dll and issue will not be able to run in IIS7. When being run on 6, after looking through the support history, the site had to be run in 5.0 mode. Looks like this one has been building for a while now!

Webtest with session-id in url

We have an ASP.Net site that redirects you to a url that shows a session-id. like this:
http://localhost/(S(f3rjcw45q4cqarboeme53lbx))/main.aspx
This id is unique with every request.
Is it possible to test this site using a standard visual studio 2008/2010 webtest? How can I provide the test this data?
I have to call a couple of different pages using that same id.
Yes, it is relatively easy to do this. You will need to create a coded webtest however.
In my example we have a login post that will return the url including the session string.
Just after the we yield the login post request (request3) to the enumerator I call the following.
WebTestRequest request3 = new WebTestRequest((this.Context["WebServer1"].ToString() + "/ICS/Login/English/Login.aspx"));
//more request setup code removed for clarity
yield return request3;
string responseUrl = Context.LastResponse.ResponseUri.AbsoluteUri;
string cookieUrl = GetUrlCookie(responseUrl, this.Context["WebServer1"].ToString(),"/main.aspx");
request3 = null;
Where GetUrlCookie is something like this:
public static string GetUrlCookie(string fullUrl, string webServerUrl, string afterUrlPArt)
{
string result = fullUrl.Substring(webServerUrl.Length);
result = result.Substring(0, result.Length - afterUrlPArt.Length);
return result;
}
Once you have the session cookie string, you can substitute it really easy in any subsequent urls for request/post
e.g.
WebTestRequest request4 = new WebTestRequest((this.Context["WebServer1"].ToString() + cookieUrl + "/mySecureForm.aspx"));
I apologise for my code being so rough, but it was deprecated in my project and is pulled from the first version of the codebase - and for saying it was easy :)
For any load testing, depending on your application, you may have to come up with a stored procedure to call to provide distinct login information each time the test is run.
Note, because the response url cannot be determined ahead of time, for the login post you will have to temporarily turn off the urlValidationEventHandler. To do this I store the validationruleeventhandler in a local variable:
ValidateResponseUrl validationRule1 = new ValidateResponseUrl();
urlValidationRuleEventHandler = new EventHandler<ValidationEventArgs>(validationRule1.Validate);
So can then turn it on and off as I require:
this.ValidateResponse -= urlValidationRuleEventHandler ;
this.ValidateResponse += urlValidationRuleEventHandler ;
The alternative is to code your own such as this (reflectored from the Visual Studio code and changed to be case insensitive.
class QueryLessCaseInsensitiveValidateResponseUrl : ValidateResponseUrl
{
public override void Validate(object sender, ValidationEventArgs e)
{
Uri uri;
string uriString = string.IsNullOrEmpty(e.Request.ExpectedResponseUrl) ? e.Request.Url : e.Request.ExpectedResponseUrl;
if (!Uri.TryCreate(e.Request.Url, UriKind.Absolute, out uri))
{
e.Message = "The request URL could not be parsed";
e.IsValid = false;
}
else
{
Uri uri2;
string leftPart = uri.GetLeftPart(UriPartial.Path);
if (!Uri.TryCreate(uriString, UriKind.Absolute, out uri2))
{
e.Message = "The request URL could not be parsed";
e.IsValid = false;
}
else
{
uriString = uri2.GetLeftPart(UriPartial.Path);
////this removes the query string
//uriString.Substring(0, uriString.Length - uri2.Query.Length);
Uri uritemp = new Uri(uriString);
if (uritemp.Query.Length > 0)
{
string fred = "There is a problem";
}
//changed to ignore case
if (string.Equals(leftPart, uriString, StringComparison.OrdinalIgnoreCase))
{
e.IsValid = true;
}
else
{
e.Message = string.Format("The value of the ExpectedResponseUrl property '{0}' does not equal the actual response URL '{1}'. QueryString parameters were ignored.", new object[] { uriString, leftPart });
e.IsValid = false;
}
}
}
}
}

Resources