104 lines
2.1 KiB
Go
104 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// SpartanURL parses u and calls SpartanParsedURL with the parsed url
|
|
func SpartanURL(u string) bool {
|
|
// Parse URL
|
|
parsed, err := url.Parse(u)
|
|
if err != nil {
|
|
fmt.Println("invalid url")
|
|
return false
|
|
}
|
|
if parsed.Scheme == "" {
|
|
// have to parse again
|
|
// ignoring err since it shouldn't fail here if it succeeded above
|
|
parsed, _ = url.Parse("spartan://" + u)
|
|
}
|
|
if parsed.Scheme != "spartan" {
|
|
fmt.Printf("Unsupported scheme %s", parsed.Scheme)
|
|
return false
|
|
}
|
|
return SpartanParsedURL(*parsed)
|
|
}
|
|
|
|
// SpartanParsedURL fetches u and displays the page
|
|
func SpartanParsedURL(u url.URL) bool {
|
|
host := u.Host
|
|
// Connect to server
|
|
if u.Port() == "" {
|
|
host += ":300"
|
|
}
|
|
conn, err := net.Dial("tcp", host)
|
|
if err != nil {
|
|
fmt.Println("unable to connect to " + u.Host)
|
|
fmt.Println(err.Error())
|
|
return false
|
|
}
|
|
defer conn.Close()
|
|
// Send request
|
|
path := u.Path
|
|
if u.Path == "" {
|
|
path = "/"
|
|
}
|
|
conn.Write([]byte(fmt.Sprintf("%s %s 0\r\n", u.Hostname(), path)))
|
|
// Receive and parse response header
|
|
reader := bufio.NewReader(conn)
|
|
header, err := reader.ReadString(byte('\n'))
|
|
if err != nil {
|
|
fmt.Println("Error reading response header")
|
|
return false
|
|
}
|
|
// Parse header
|
|
statusParts := strings.SplitN(header, " ", 2)
|
|
status, err := strconv.Atoi(statusParts[0])
|
|
if err != nil {
|
|
fmt.Println("invalid status code:" + statusParts[0])
|
|
return false
|
|
}
|
|
meta := statusParts[1]
|
|
|
|
// Handle status
|
|
switch status {
|
|
case 1:
|
|
fmt.Println("[INPUT]")
|
|
fmt.Println(meta)
|
|
case 2:
|
|
// TODO: handle mime type
|
|
bodyBytes, err := ioutil.ReadAll(reader)
|
|
if err != nil {
|
|
fmt.Println("Error reading body")
|
|
return false
|
|
}
|
|
body := string(bodyBytes)
|
|
fmt.Print(body)
|
|
case 3:
|
|
SpartanURL("spartan://" + u.Host + meta)
|
|
case 4:
|
|
fmt.Println("Error: " + meta)
|
|
case 5:
|
|
fmt.Println("Server error: " + meta)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args
|
|
if len(args) == 0 || args[1] == "--help" {
|
|
fmt.Println("Usage: <program> [--help] [URL]")
|
|
return
|
|
}
|
|
// TODO: support multiple args
|
|
SpartanURL(args[1])
|
|
}
|