How to add body title to Fprintf output? - go

I'm trying to add <title>Go</title> to my code example:
package main
import (
"fmt"
"net/http"
"os"
)
func favicon(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "favicon.ico")
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "\n\nSystem info:\nHostname [pod name]: %s", hostname)
fmt.Fprintf(w, "\nCurrent URL: %s\n", r.Host)
}
func main() {
http.HandleFunc("/favicon.ico", favicon)
http.HandleFunc("/", sayhelloName)
http.ListenAndServe(":80", nil)
}
I tried to add like:
fmt.Fprintf(w, "<title>Go</title>"). It works but make mess with strings next to. I wouldn't like to use html template only to add title to page. Is there any ways to add title in one string?

not used html template. just used only fmt.Fprintf.
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func favicon(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "favicon.ico")
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "<html>")
fmt.Fprintf(w, "<head>")
fmt.Fprintf(w, "<title>%s</title>", "Go")
fmt.Fprintf(w, "</head>")
fmt.Fprintf(w, "<body>")
fmt.Fprintf(w, "<h1>System info: Hostname [pod name]: %s", hostname)
fmt.Fprintf(w, "<h1>Current URL: %s", r.Host)
fmt.Fprintf(w, "</body>")
fmt.Fprintf(w, "</html>")
}
func main() {
http.HandleFunc("/favicon.ico", favicon)
http.HandleFunc("/", sayhelloName)
log.Fatal(http.ListenAndServe(":8080", nil))
}

Related

Serving favicon.ico with JulienSchmidt httprouter

I can get favicon.icon with the standard net/http package but am having trouble with julienschmidt/httprouter. This is what I'm trying and am receiving a 404 error for the favicon.ico file.
import (
"github.com/julienschmidt/httprouter"
"net/http"
"log"
)
func main(){
router := httprouter.New()
router.GET("/", index)
router.POST("/", login)
router.GET("/logout", logout)
router.GET("/favicon.ico", faviconHandler)
router.ServeFiles("/stuff/*filepath", http.Dir("stuff"))
log.Fatal(http.ListenAndServe(":8080", router))
}
func faviconHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.ServeFile(w, r, "/stuff/images/favicon.ico")
}
I was able to solve the problem by removing the leading slash from stuff/images/favicon.ico. Thanks #Peter.
import (
"github.com/julienschmidt/httprouter"
"net/http"
"log"
)
func main(){
router := httprouter.New()
router.GET("/", index)
router.POST("/", login)
router.GET("/logout", logout)
router.GET("/favicon.ico", faviconHandler)
router.ServeFiles("/stuff/*filepath", http.Dir("stuff"))
log.Fatal(http.ListenAndServe(":8080", router))
}
func faviconHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.ServeFile(w, r, "stuff/images/favicon.ico")
}

golang http server send r.URL.Path over socket

I have a http server, and I want to send the r.URL.Path text to a client using a socket
I get a error: undefined: conn in conn.Write
This is becauase conn is defined in another function
What I have tried:
package main
import (
"net"
"io"
"net/http"
)
ln, _ := net.Listen("tcp", ":8081")
conn, _ := ln.Accept()
func hello(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!")
conn.Write([]byte(r.URL.Path + "\n")) //Here I'm attemping to send it
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":8000", nil)
}
Your problem is actually in the way you try to declare variables.
If you want your conn to be on global scope, use var
package main
import (
"io"
"net/http"
"net"
)
var ln, _ = net.Listen("tcp", ":8081")
var conn, _ = ln.Accept()
func hello(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!")
conn.Write([]byte(r.URL.Path + "\n")) //Here I'm attemping to send it
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":8000", nil)
}

Multiple Dir serving is not working

Any mistakes in below code? Multiple directory serving is not working from the below code. When I access the localhost:9090/ide, the server will return 404 error.
package main
import (
"log"
"net/http"
)
func serveIDE(w http.ResponseWriter, r *http.Request) {
http.FileServer(http.Dir("/home/user/ide")).ServeHTTP(w, r)
}
func serveConsole(w http.ResponseWriter, r *http.Request) {
http.FileServer(http.Dir("/home/user/console")).ServeHTTP(w, r)
}
func main() {
http.HandleFunc("/ide", serveIDE)
http.HandleFunc("/console", serveConsole)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
When I change the code like this,
http.HandleFunc("/", serveIDE)
It will work as I expected.
One of the issues with using http.FileServer is that the request path is used to build the file name, so if you're serving from anywhere but the root you need to strip the route prefix to that handler.
The standard library includes a helpful tool for that http.StripPrefix, but that only works on http.Handlers, not http.HandleFuncs, so to use it you need to adapt your HandleFunc to a Handler.
Here is a working version that should do what you want. Note that wHandler is just an adapter from your HttpFunc methods to Hander interface:
package main
import (
"log"
"net/http"
)
func serveIDE(w http.ResponseWriter, r *http.Request) {
http.FileServer(http.Dir("/home/user/ide")).ServeHTTP(w, r)
}
func serveConsole(w http.ResponseWriter, r *http.Request) {
http.FileServer(http.Dir("/home/user/console")).ServeHTTP(w, r)
}
type wHandler struct {
fn http.HandlerFunc
}
func (h *wHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Printf("Handle request: %s %s", r.Method, r.RequestURI)
defer log.Printf("Done with request: %s %s", r.Method, r.RequestURI)
h.fn(w, r)
}
func main() {
http.Handle("/ide", http.StripPrefix("/ide", &wHandler{fn: serveIDE}))
http.Handle("/console", http.StripPrefix("/console", &wHandler{fn: serveConsole}))
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}

gorilla mux router handlers

I can not get the gorilla mux to work..
When requesting http://www.localhost:9000 this is returned by the web server 404 page not found
But this works http://localhost:9000/ and prints Hello world
package main
import (
"net/http"
"fmt"
"log"
"github.com/gorilla/mux"
)
func Handler(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w, "Hello world")
}
func main(){
r := mux.NewRouter()
r.Host("www.localhost")
r.HandleFunc("/", Handler)
err := http.ListenAndServe(":9000", r)
if err != nil {
log.Fatal("ListenAndServe error: ", err)
}
}
You want to be able to support both localhost and www.localhost
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
func Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello world")
}
func main() {
r := mux.NewRouter()
r.Host("www.localhost").Path("/").HandlerFunc(Handler)
r.HandleFunc("/", Handler)
err := http.ListenAndServe(":9000", r)
if err != nil {
log.Fatal("ListenAndServe error: ", err)
}
}
If you read the documentation carefully, you'll notice that r.Host() is just another pattern matching function. It doesn't set any global rule for that router.
if you want to make that rule to be inherited you'll need to use a subrouter:
subrouter := r.Host("www.localhost").Subrouter()
then you use "subrouter" in place of "r"

Print to Log using Go Language Simple HTTP Server

I am trying to log the IP address of the requestor, what METHOD they are using and what file they are requesting. But for some reason it only outputs on the terminal and doesn't save it to logfile.txt...
package main
import (
"fmt"
"net/http"
"log"
"encoding/json"
"io/ioutil"
)
type Options struct {
Path string
Port string
}
func Log(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
handler.ServeHTTP(w, r)
})
}
func main() {
op := &Options{Path: "./", Port: "8001"}
data, _ := ioutil.ReadFile("./config.json")
json.Unmarshal(data, op)
http.Handle("/", http.FileServer(http.Dir(op.Path)))
err := http.ListenAndServe(":" + op.Port, Log(http.DefaultServeMux))
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
In your Log function, you are using fmt.Printf not fmt.Fprintf.
For example,
package main
import (
"fmt"
"log"
"net/http"
"os"
)
var logFile *os.File
func Log(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(logFile, "%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
handler.ServeHTTP(w, r)
})
}
func main() {
var err error
logFile, err = os.Create("logfile.txt")
if err != nil {
log.Fatal("Log file create:", err)
return
}
defer logFile.Close()
}

Resources