gophercises / urlshort Goto Github PK
View Code? Open in Web Editor NEWEx 2 - Create an http.Handler that forwards paths to other URLs
Home Page: https://gophercises.com
Ex 2 - Create an http.Handler that forwards paths to other URLs
Home Page: https://gophercises.com
Look over the README.md then attempt to complete the exercise and submit your solution as a directory inside of the students
directory. Eg if you have a github username of joncalhoun
then place your code in students/joncalhoun/your_code.go
For more info on how these are used see the README in the students directory.
Note: I am accepting multiple submissions (and recreating the issue) for this, as I am looking for multiple student-solutions to use in the casts.
After several attempts at my own solution, I decided to follow the tutorial , but after implementing the MapHandler, commenting out yaml related code, I still cannot get the "hello world" when calling localhost:8080.
I found some solutions for similar problems, but usually they require logging an error. However I cannot seem to figure out which net/http function in the code has this.
So I completed the exercise and ran into this error when I would go run main/main.go
As a sanity check, I pulled down the solution branch and tried to build but still get the same error.
Here is the full log:
2018/01/22 09:14:56 http: panic serving [::1]:65373: runtime error: invalid memory address or nil pointer dereference goroutine 19 [running]: net/http.(*conn).serve.func1(0xc42009a780) /usr/local/Cellar/go/1.9.2/libexec/src/net/http/server.go:1697 +0xd0 panic(0x124ff40, 0x13f9de0) /usr/local/Cellar/go/1.9.2/libexec/src/runtime/panic.go:491 +0x283 net/http.HandlerFunc.ServeHTTP(0x0, 0x13d0da0, 0xc420126000, 0xc420120000) /usr/local/Cellar/go/1.9.2/libexec/src/net/http/server.go:1918 +0x3f net/http.serverHandler.ServeHTTP(0xc420088f70, 0x13d0da0, 0xc420126000, 0xc420120000) /usr/local/Cellar/go/1.9.2/libexec/src/net/http/server.go:2619 +0xb4 net/http.(*conn).serve(0xc42009a780, 0x13d1220, 0xc42008c200) /usr/local/Cellar/go/1.9.2/libexec/src/net/http/server.go:1801 +0x71d created by net/http.(*Server).Serve /usr/local/Cellar/go/1.9.2/libexec/src/net/http/server.go:2720 +0x288
I tried to set up Delve earlier in the day and that's about the only thing I can think of that may be causing the issue as I was having problems with the self-signed certificate but I can't imagine that a debugger would be causing the issue.
That said, I double checked other Go projects on my local machine that use the http package and they seem to be working fine.
It seems like we need a primer on how go handles packages before we can carry out this exercise.
For example, main.go
is importing "github.com/gophercises/urlshort"
. Having tinkered with go
a bit in the past I know I can go get
the package and that will download it to $GOPATH/src/github.com/gophercises/urlshort
. So should I edit the package there directly? Or is there some other way of doing local package development? Seems kind of hacky to edit things in $GOPATH/src
directly, but maybe that's normal? I also tried copying it into my project and the compiler complained about finding multiple packages. I've shuffled things around and got it working but I have no idea if I'm adhering to best practices.
Look over the README.md then attempt to complete the exercise and submit your solution as a directory inside of the students
directory. Eg if you have a github username of joncalhoun
then place your code in students/joncalhoun/your_code.go
For more info on how these are used see the README in the students directory.
I am using Windows 10, with WSL, and ZSH.
When I run go env
in my VSCode terminal I get the following:
GOOS="linux"
GOPATH="/home/maylortaylor"
GORACE=""
GOROOT="/usr/lib/go-1.10"
When i run VSCode task Go: Current GOPATH
, i get the following:
C:\gocode\
According to my Windows Environment Variables I have
GOPATH = C:\gocode\
and
my PATH variable has C:\gocode\bin\
added at the end.
App Structure
Main.go
package main
import (
"fmt"
"net/http"
"github.com/gophercises/urlshort"
)
func main() {
mux := defaultMux()
// Build the MapHandler using the mux as the fallback
pathsToUrls := map[string]string{
"/urlshort-godoc": "https://godoc.org/github.com/gophercises/urlshort",
"/yaml-godoc": "https://godoc.org/gopkg.in/yaml.v2",
}
mapHandler := urlshort.MapHandler(pathsToUrls, mux)
// Build the YAMLHandler using the mapHandler as the
// fallback
yaml := `
- path: /urlshort
url: https://github.com/gophercises/urlshort
- path: /urlshort-final
url: https://github.com/gophercises/urlshort/tree/solution
`
yamlHandler, err := urlshort.YAMLHandler([]byte(yaml), mapHandler)
if err != nil {
panic(err)
}
fmt.Println("Starting the server on :8080")
http.ListenAndServe(":8080", yamlHandler)
}
func defaultMux() *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/", hello)
return mux
}
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world!")
}
Handler.go
package urlshort
import (
"net/http"
yaml "gopkg.in/yaml.v2"
)
func MapHandler(pathsToUrls map[string]string, fallback http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if dest, ok := pathsToUrls[path]; ok {
http.Redirect(w, r, dest, http.StatusFound)
return
}
fallback.ServeHTTP(w, r)
}
}
func YAMLHandler(yamlBytes []byte, fallback http.Handler) (http.HandlerFunc, error) {
pathUrls, err := parseYaml(yamlBytes)
if err != nil {
return nil, err
}
pathsToUrls := buildMap(pathUrls)
return MapHandler(pathsToUrls, fallback), nil
}
func buildMap(pathUrls []pathUrl) map[string]string {
pathsToUrls := make(map[string]string)
for _, pu := range pathUrls {
pathsToUrls[pu.Path] = pu.URL
}
return pathsToUrls
}
func parseYaml(data []byte) ([]pathUrl, error) {
var pathUrls []pathUrl
err := yaml.Unmarshal(data, &pathUrls)
if err != nil {
return nil, err
}
return pathUrls, nil
}
type pathUrl struct {
Path string `yaml:"path"`
URL string `yaml:"url"`
}
FULL ERROR
main/main.go:7:2: cannot find package "github.com/gophercises/urlshort" in any of:
/usr/lib/go-1.10/src/github.com/gophercises/urlshort (from $GOROOT)
/home/maylortaylor/src/github.com/gophercises/urlshort (from $GOPATH)
Thank you for your course! It's very helpful.
When you provide relevant links at GitHub, they work well. Probably, GitHub resolves relevant links correctly, e.g. (handler.go)
it resolves to https://github.com/gophercises/urlshort/blob/master/handler.go
.
On the other hand, on the website itself (e.g. on https://gophercises.com/exercises/urlshort) such links are resolved as relevant: (handler.go)
it resolves to https://gophercises.com/exercises/handler.go
and this page obviously doesn't exist.
The simplest way is probably to always use absolute paths. But maybe it might make sense to add some resolver to gophercises.com to resolve such URLs automatically?
Thank you again.
Look over the README.md then attempt to complete the exercise and submit your solution as a directory inside of the students
directory. Eg if you have a github username of joncalhoun
then place your code in students/joncalhoun/your_code.go
For more info on how these are used see the README in the students directory.
Note: I am accepting multiple submissions (and recreating the issue) for this, as I am looking for multiple student-solutions to use in the casts.
I was following instructions in the video, wrote code exactly as Jon, but redirecting for "/urlshort" and "/urlshort-final" don't work.
yaml.Unmarshal(yml, &pathUrls) returns only [{/urlshort }] for some reason.
Does it have something to do with tags added to struct? In the video he added yaml tags automatically. I use VS Code and when I tried it struct became this:
type pathUrl struct {
Path string `json:"path,omitempty"`
URL string `json:"url,omitempty"`
}
I changed it to yaml:"path"
and yaml:"url"
, still does not work.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.