issue with accessing GET parameters net/http in golang - web-services

Following is my go program to extract GET parameters. (URL: /mysql?hostname=example.com)
package main
import (
"net/http"
"fmt"
//"encoding/json"
//"html"
"github.com/kr/pretty"
);
func main(){
http.HandleFunc("/", foo)
http.ListenAndServe(":80", nil)
}
func foo(w http.ResponseWriter, r * http.Request){
w.Header().Set("Server","A Go WebServer")
w.Header().Set("Content-Type", "text/html")
hostname := r.URL.Query()["hostname"]
//w.Write([]byte(hostname[0]))
fmt.Printf("%# v", pretty.Formatter(hostname[0]))
w.Write([]byte(hostname))
}
Error shown on console.
"example.com"2014/09/01 02:57:22 http: panic serving 172.17.92.14:49411: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42dc41)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f8b5)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410381)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x410228)
/root/go/src/api/main.go:34 (0x400d77)
foo: fmt.Printf("%# v", pretty.Formatter(hostname[0]))
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421bed)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422a6f)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x421a00)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d9bb)
2014/09/01 02:57:22 http: panic serving 172.17.92.14:49412: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42dc41)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f8b5)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410381)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x410228)
/root/go/src/api/main.go:34 (0x400d77)
foo: fmt.Printf("%# v", pretty.Formatter(hostname[0]))
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421bed)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422a6f)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x421a00)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d9bb)
2014/09/01 02:57:22 http: panic serving 172.17.92.14:49413: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42dc41)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f8b5)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410381)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x410228)
/root/go/src/api/main.go:34 (0x400d77)
foo: fmt.Printf("%# v", pretty.Formatter(hostname[0]))
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421bed)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422a6f)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x421a00)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d9bb)
I am having trouble with determining the data type of hostname variable. I should get it as a string.
When I try to write to http response writer
w.Write([]byte(hostname))
following build error is shown
go/src/api/main.go:38: cannot convert hostname (type []string) to type []byte
If I treat it as a string array build is successful but there is run time error
newhost := hostname[0];
w.Write([]byte(newhost))
Error:
2014/09/01 04:42:40 http: panic serving 172.17.92.14:50404: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42db27)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f79b)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410267)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x41010e)
/root/go/src/api/main.go:38 (0x400d63)
foo: newhost := hostname[0];
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421ad3)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422955)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x4218e6)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d8a1)
2014/09/01 04:42:40 http: panic serving 172.17.92.14:50405: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42db27)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f79b)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410267)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x41010e)
/root/go/src/api/main.go:38 (0x400d63)
foo: newhost := hostname[0];
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421ad3)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422955)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x4218e6)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d8a1)
2014/09/01 04:42:40 http: panic serving 172.17.92.14:50406: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42db27)
_func_003: buf.Write(debug.Stack())
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:1443 (0x40f79b)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:128 (0x410267)
/home/michael/DPKG/golang/src/pkg/runtime/runtime.c:85 (0x41010e)
/root/go/src/api/main.go:38 (0x400d63)
foo: newhost := hostname[0];
/usr/lib/go/src/pkg/net/http/server.go:690 (0x421ad3)
HandlerFunc.ServeHTTP: f(w, r)
/usr/lib/go/src/pkg/net/http/server.go:926 (0x422955)
(*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/lib/go/src/pkg/net/http/server.go:656 (0x4218e6)
(*conn).serve: handler.ServeHTTP(w, w.req)
/home/michael/DPKG/golang/src/pkg/runtime/proc.c:271 (0x40d8a1)
I also checked length of newhost as #VonC suggested and it gave expected results.
fmt.Print("\n")
fmt.Println((len(newhost)))
Output on console
"example.com"
11
2014/09/01 05:05:15 http: panic serving 172.17.92.14:50779: runtime error: index out of range
/usr/lib/go/src/pkg/net/http/server.go:576 (0x42dd33)

You need to use url/Values.Get, it will return the empty string if the value isn't set:
hostname := r.URL.Query().Get("hostname")
if len(hostname) != 0 {
io.WriteString(w, hostname) // or
w.Write([]byte(hostname))
}
// edit
Let's take it a step by step:
go/src/api/main.go:38: cannot convert hostname (type []string) to type []byte:
req.URL.Query["hostname"], returns a string slice ([]string) which you can't directly convert to []byte, only string can be converted like that.
The first runtime error: index out of range:
You're trying to use hostname[0] without checking how many elements in the slice, so in that case there weren't any elements.
That last runtime error: index out of range is weird though, I have no idea why you got it, must be something else you changed in the code.

If you only care about the first value, and you don't have to distinguish between POST or GET, you might consider using the simpler Request.FormValue function.
hostname := r.FormValue("hostname")

Related

The peculiar case of disappearing data

I am trying following code:
import std.stdio;
import std.range;
void main(){
auto data = [[1,2,3], [4,5,6]]; // putting auto instead of int[][] here makes no difference;
auto coldata = data.transposed;
writeln("coldata: ", coldata); // prints ok;
writeln("transposed data: ", coldata); // Empty list is printed. Data disappears/evaporates!
}
The output is:
$ rdmd evapor.d
coldata: [[1, 4], [2, 5], [3, 6]]
transposed data: []
In the second call, an empty list is printed. The data seems to just disappear/evaporate!
Why the data is not priting on second call?
Edit: Empty list is printed even if I call transpose each time:
writeln("coldata: ", data.transposed); // prints ok;
writeln("transposed data: ", data.transposed); // data disappears / evaporates!
Also, using coldata.dup does not work. I produces following error:
soq_evapor.d(10): Error: template object.dup cannot deduce function from argument types !()(Transposed!(int[][], cast(TransverseOptions)0)), candidates are:
/usr/include/dmd/druntime/import/object.d(3169): object.dup(T : V[K], K, V)(T aa)
/usr/include/dmd/druntime/import/object.d(3206): object.dup(T : V[K], K, V)(T* aa)
/usr/include/dmd/druntime/import/object.d(4482): object.dup(T)(T[] a) if (!is(const(T) : T))
/usr/include/dmd/druntime/import/object.d(4508): object.dup(T)(const(T)[] a) if (is(const(T) : T))
Failed: ["/usr/bin/dmd", "-v", "-o-", "soq_evapor.d", "-I."]
The range is being "consumed". If you need to reuse it like you have, you will need to make sure to call save before you use it.
https://forum.dlang.org/post/migwtldccpwryusyolkq#forum.dlang.org
https://forum.dlang.org/post/n2m1jl$2dqf$1#digitalmars.com
You can find more info about this here: https://forum.dlang.org/thread/plsuntcmsezxpjbxkfnz#forum.dlang.org
import std.stdio;
import std.range;
void main(){
auto data = [[1,2,3], [4,5,6]]; // putting auto instead of int[][] here makes no difference;
auto coldata = data.dup();
auto otherData = data.dup();
writeln("coldata: ", coldata.transposed); // prints ok;
writeln("transposed data: ", otherData.transposed); // this also prints ok.
}
is one such way of doing this.
The main reason for doing this is how the API is designed in D. Not all ranges are destructively iterated, it just depends on the kind. In general, though you can.
The D Lang site has this to say:
Most of the ranges in the standard library are structs and so foreach iteration is usually non-destructive, though not guaranteed. If this guarantee is important, an specialization of an InputRange can be used— forward ranges with a .save method:
https://tour.dlang.org/tour/en/basics/ranges

How to pass HashMap from one Actor to another

I have a method getAggOutput() that returns a HashMap, in Actor A.
def getAggOutput: HashMap[X, List[Y]] = {
println("***** Inside getAggOutput, rMap is: " + rMap)
return rMap
}
Also, in Actor A, the method is called that under the case object GETOUTPUT:
case GETOUTPUT =>
println("***** Inside GETOUTPUT")
getAggOutput
In Actor B, I am doing the following:
implicit val timeout = Timeout(5 seconds)
val reducerInput = sender ? GETOUTPUT
val result = Await.result(reducerInput, timeout.duration)
println("****** RESULT is: " + result)
The print statements show that the value for rMap is correct, however, I am getting the following error:
java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]
And result is not assigned the value of the HashMap.
How do I make this work? Or, is there a better way entirely? I just need to get rMap into Actor B
UPDATE:
I figured out this part. In the case GETOUTPUT, I need:
sender ! getAggOutput.
The println shows that the HashMap in the result variable is correct.
Now, I am trying to loop over the HashMap:
for( (key,value) <- result)
{
redOut += (key -> value)
}
And I am getting the following error:
type mismatch;
[error] found : (Any, Any)
[error] required: (X, U)
[error] redOut += (key -> value)
UPDATE:
I also tried:
for( (key,value) <- result)
{
redOut += (key.asInstanceOf[X] -> value.asInstanceOf[U])
}
However, I received the following error:
value withFilter is not a member of Any
[error] for( (key,value) <- result)
There was no need to do this, I just looped over the Hashmap in Actor A and sent each (key, value) pair to Actor B

Spock mock returns wrong value

I have got a strange use case where spock mock is returning the correct value when I do not check for two calls on the mocked class in the 'then:' section, but it is returning 0 when I include two checks in the 'then:' section.
This is the mock:
mockDao.readCounter(_, _, _, _, _) >> dbValue
and here is the 'then:' section that fails:
1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
In this case, instead of 'dbValue', '0' is returned. But if I comment out either of the two checks, then it passes. So, the following two cases pass:
//1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
OR
1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
//1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
Here is the gradle section for spock:
// spock
testCompile "org.codehaus.groovy:groovy:2.4.7"
compile group: 'org.spockframework', name: 'spock-core', version: '1.0-groovy-2.4'
// !!! To get none-interface base mocking to work with Spock
compile group: 'cglib', name: 'cglib-nodep', version: '3.2.4'
This is expected and documented behavior. If you want to mock and stub on the same mock, you have to do it in one line like
1 * mockDao.readCounter(_, _, _, _, _) >> dbValue
Here the relevant section:
Combining Mocking and Stubbing
Mocking and stubbing go hand-in-hand:
1 * subscriber.receive("message1") >> "ok"
1 * subscriber.receive("message2") >> "fail"
When mocking and stubbing the same method call, they have to happen in the same interaction. In particular, the following Mockito-style splitting of stubbing and mocking into two separate statements will not work:
setup:
subscriber.receive("message1") >> "ok"
when:
publisher.send("message1")
then:
1 * subscriber.receive("message1")
As explained in Where to Declare Interactions, the receive call will first get matched against the interaction in the then: block. Since that interaction doesn’t specify a response, the default value for the method’s return type (null in this case) will be returned. (This is just another facet of Spock’s lenient approach to mocking.). Hence, the interaction in the setup: block will never get a chance to match.
NOTE | Mocking and stubbing of the same method call has to happen in the same interaction.

Golang SplitAfter for Regexp type

In golang strings.SplitAfter method split text after an special character into an slice, but I didn't find a way for Regexp type to split text after matches. Is there a way to do that?
Example :
var text string = "1.2.3.4.5.6.7.8.9"
res := strings.Split(text, ".")
fmt.Println(res) // print [1 2 3 4 5 6 7 8 9]
res = strings.SplitAfter(text, ".")
fmt.Println(res) // print [1. 2. 3. 4. 5. 6. 7. 8. 9]
first at all, your regex "." is wrong for splitAfter function. You want number followed by value "." so the regex is: "[1-9]".
The function you are looking might look like this:
func splitAfter(s string, re *regexp.Regexp) (r []string) {
re.ReplaceAllStringFunc(s, func(x string) string {
s = strings.Replace(s,x,"::"+x,-1)
return s
})
for _, x := range strings.Split(s,"::") {
if x != "" {
r = append(r, x)
}
}
return
}
Than:
fmt.Println(splitAfter("healthyRecordsMetric",regexp.MustCompile("[A-Z]")))
fmt.Println(splitAfter("healthyrecordsMETetric",regexp.MustCompile("[A-Z]")))
fmt.Println(splitAfter("HealthyHecord Hetrics",regexp.MustCompile("[A-Z]")))
fmt.Println(splitAfter("healthy records metric",regexp.MustCompile("[A-Z]")))
fmt.Println(splitAfter("1.2.3.4.5.6.7.8.9",regexp.MustCompile("[1-9]")))
[Healthy Records Metric]
[healthy Records Metric]
[healthyrecords M E Tetric]
[Healthy Hecord Hetrics]
[healthy records metric]
[1. 2. 3. 4. 5. 6. 7. 8. 9]
Good luck!
Regexp type itself does not have a method to do that exactly that but it's quite simple to write a function that implements what your asking based on Regexp functionality:
func SplitAfter(s string, re *regexp.Regexp) []string {
var (
r []string
p int
)
is := re.FindAllStringIndex(s, -1)
if is == nil {
return append(r, s)
}
for _, i := range is {
r = append(r, s[p:i[1]])
p = i[1]
}
return append(r, s[p:])
}
Here I left a program to play with it.

Play 2.0 - mapping on a `map` or `for-yield` result in template

I want to perform two sequential map operations in Play 2.0 template. I have tried like this:
#defining(for(a <- as) yield { doSmthWith(a); doSmthWith2(a) })
{ aaas => aaas.map(_.toString).mkString("|") } /*CRASH*/
which I presume to be equivalent to regular Scala:
val aaas = for(a <- as) yield { doSmthWith(a); doSmthWith2(a) }
println(aaas.map(_.toString).mkString("|"))
but it crashes there on the first { saying expected start of definition...
Same thing as if I replace the for loop with regular map:
#(as.map(a => { doSmthWith(a); doSmthWith2(a) })).map(_.toString).mkString("|"))
With the same crash on the first } sign. How can I acheive sequentional mapping in a Play template?
UPDATE:
The stack - here it is! - right from the console:
sbt.PlayExceptions$CompilationException: Compilation error [expected start of de
finition]
at sbt.PlayReloader$$anon$2$$anonfun$reload$3$$anonfun$2$$anonfun$apply$
11$$anonfun$apply$12.apply(PlayReloader.scala:224) ~[na:na]
at sbt.PlayReloader$$anon$2$$anonfun$reload$3$$anonfun$2$$anonfun$apply$
11$$anonfun$apply$12.apply(PlayReloader.scala:224) ~[na:na]
at scala.Option.map(Option.scala:133) ~[scala-library.jar:0.11.2]
at sbt.PlayReloader$$anon$2$$anonfun$reload$3$$anonfun$2$$anonfun$apply$
11.apply(PlayReloader.scala:224) ~[na:na]
at sbt.PlayReloader$$anon$2$$anonfun$reload$3$$anonfun$2$$anonfun$apply$
11.apply(PlayReloader.scala:221) ~[na:na]
at scala.Option.map(Option.scala:133) ~[scala-library.jar:0.11.2]
The stack says smth about Option but I do not use them anywhere here. Must be some inner workings.
This works:
#defining(for (a <- List(1,2,3)) yield {
play.api.Logger.debug("a:" + a)
a*3
}) { as =>
#(as.mkString("|"))
}
Which displays 3|6|9 in the page and prints in the console:
[debug] application - a:1
[debug] application - a:2
[debug] application - a:3
So my guess is adding the # sign in front of the expression as well as putting the opening brace on the same line as the closing paren from defining would make it work (assuming doSmthWith2(a) actually returns something else than unit):
#defining(for(a <- as) yield { doSmthWith(a); doSmthWith2(a) }) { aaas =>
#(aaas.map(_.toString).mkString("|"))
}