Initial commit -- RFC1288 parser is passing unit tests.
This commit is contained in:
parent
13bf1649a8
commit
b7513a86fa
|
@ -1,3 +1,13 @@
|
|||
*#
|
||||
.#*
|
||||
*~
|
||||
*.orig
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
*.pdf
|
||||
*.bk
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# MONOLOGUED
|
||||
|
||||
Monologued is an implementation of an
|
||||
[RFC1288](https://tools.ietf.org/html/rfc1288) protocol server in Go.
|
||||
|
||||
That's right. Monologued is a
|
||||
*[Finger](https://en.wikipedia.org/wiki/Finger_protocol)* server.
|
||||
|
||||
# WHY‽‽‽‽
|
||||
|
||||
While what I really wanted was to
|
||||
[learn Rust](https://github.com/elfsternberg/monologued), work decided that
|
||||
Go was a better choice. Since I have to learn it, this seemed like the
|
||||
best way to go about it. Still not thrilled with the decision, but maybe
|
||||
I'll get a blog post out of it.
|
||||
|
||||
# Status
|
||||
|
||||
Monologued is still very much not working. Don't even bother
|
||||
downloading. It's mostly something to cut my teeth on while I try to
|
||||
figure out how Go works.
|
||||
|
||||
# Thanks
|
||||
|
||||
Thanks to my friend Nathaniel for the answer to my original question,
|
||||
"In a movie, when the villain is explaining his plans at length, what is
|
||||
that called?" Nathaniel explained that "He's monologuing," and now you
|
||||
know why it has that name.
|
||||
|
||||
# License
|
||||
|
||||
Apache 2.0. See the accompanying LICENSE file in this directory.
|
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("What the fuck, over?", extraNonsense())
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package rfc1288
|
||||
|
||||
import(
|
||||
"bytes"
|
||||
// "fmt"
|
||||
)
|
||||
|
||||
func is_unix_conventional(c byte) bool {
|
||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
|
||||
}
|
||||
|
||||
var Rfc1288ErrorMsgs = []string {
|
||||
"",
|
||||
"Protocol prefix not recognized",
|
||||
"Protocol request does not meet specifications",
|
||||
}
|
||||
|
||||
type Rfc1288ErrorCode int
|
||||
|
||||
const (
|
||||
Ok Rfc1288ErrorCode = 0
|
||||
BadProtocol Rfc1288ErrorCode = 1
|
||||
BadRequest Rfc1288ErrorCode = 2
|
||||
)
|
||||
|
||||
type Rfc1288RequestType int
|
||||
|
||||
const (
|
||||
UserList Rfc1288RequestType = 0
|
||||
User Rfc1288RequestType = 1
|
||||
Remote Rfc1288RequestType = 2
|
||||
)
|
||||
|
||||
type Rfc1288Request struct {
|
||||
Type Rfc1288RequestType
|
||||
User* string
|
||||
Host* string
|
||||
}
|
||||
|
||||
func parse_rfc1288_request(Buffer string) (Rfc1288ErrorCode, *Rfc1288Request) {
|
||||
Buflen := len(Buffer)
|
||||
|
||||
if Buflen < 2 {
|
||||
return BadProtocol, nil
|
||||
}
|
||||
|
||||
if Buffer[0] != '/' || (Buffer[1] != 'W' && Buffer[1] != 'w') {
|
||||
return BadProtocol, nil
|
||||
}
|
||||
|
||||
if len(Buffer) == 2 {
|
||||
return Ok, &Rfc1288Request{UserList, nil, nil}
|
||||
}
|
||||
|
||||
index := 2
|
||||
for index < Buflen && Buffer[index] == ' ' {
|
||||
index += 1
|
||||
}
|
||||
|
||||
if Buflen == index {
|
||||
return Ok, &Rfc1288Request{Type: UserList, User: nil, Host: nil}
|
||||
}
|
||||
|
||||
user := bytes.NewBufferString("")
|
||||
host := bytes.NewBufferString("")
|
||||
|
||||
for index < Buflen && is_unix_conventional(Buffer[index]) {
|
||||
user.WriteByte(Buffer[index])
|
||||
index += 1
|
||||
}
|
||||
|
||||
if index == Buflen || (index < Buflen && Buffer[index] == ' ') {
|
||||
ruser := user.String()
|
||||
return Ok, &Rfc1288Request{Type: User, User: &ruser, Host: nil}
|
||||
}
|
||||
|
||||
if Buffer[index] != '@' {
|
||||
return BadRequest, nil
|
||||
}
|
||||
|
||||
index += 1
|
||||
for index < Buflen && Buffer[index] != ' ' {
|
||||
host.WriteByte(Buffer[index])
|
||||
index += 1
|
||||
}
|
||||
|
||||
ruser := user.String()
|
||||
rhost := host.String()
|
||||
return Ok, &Rfc1288Request{Type: Remote, User: &ruser, Host: &rhost}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package rfc1288
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGood_List(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != UserList {
|
||||
t.Error("Expected UserList as a return type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_ListWSpaces(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W ");
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != UserList {
|
||||
t.Error("Expected UserList as a return type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBad_Start(t *testing.T) {
|
||||
res, _ := parse_rfc1288_request("")
|
||||
if res != BadProtocol {
|
||||
t.Error("Expected BadProtocol")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBad_Start1(t *testing.T) {
|
||||
res, _ := parse_rfc1288_request("/")
|
||||
if res != BadProtocol {
|
||||
t.Error("Expected BadProtocol")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBad_Start2(t *testing.T) {
|
||||
res, _ := parse_rfc1288_request("/X")
|
||||
if res != BadProtocol {
|
||||
t.Error("Expected BadProtocol, got", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_Name(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W foozle")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != User {
|
||||
t.Error("Expected User as a return type")
|
||||
}
|
||||
if *req.User != "foozle" {
|
||||
t.Error("The user name did not match passed in value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_NameExtraSpace(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W foozle ")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != User {
|
||||
t.Error("Expected User as a return type")
|
||||
}
|
||||
if *req.User != "foozle" {
|
||||
t.Error("The user name did not match passed in value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_NameWHost(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W foozle@localhost")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != Remote {
|
||||
t.Error("Expected Remote as a return type")
|
||||
}
|
||||
if *req.User != "foozle" {
|
||||
t.Error("The user name did not match passed in value.")
|
||||
}
|
||||
if *req.Host != "localhost" {
|
||||
t.Error("The host name did not match passed in value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_NameWHostAndSpaces(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/W foozle@localhost ")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != Remote {
|
||||
t.Error("Expected Remote as a return type")
|
||||
}
|
||||
if *req.User != "foozle" {
|
||||
t.Error("The user name did not match passed in value.")
|
||||
}
|
||||
if *req.Host != "localhost" {
|
||||
t.Error("The host name did not match passed in value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood_NameWHostAndSpacesAndLowerW(t *testing.T) {
|
||||
res, req := parse_rfc1288_request("/w foozle@localhost ")
|
||||
if res != Ok {
|
||||
t.Error("Expected a good return")
|
||||
}
|
||||
if req.Type != Remote {
|
||||
t.Error("Expected Remote as a return type")
|
||||
}
|
||||
if *req.User != "foozle" {
|
||||
t.Error("The user name did not match passed in value.")
|
||||
}
|
||||
if *req.Host != "localhost" {
|
||||
t.Error("The host name did not match passed in value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBad_Name(t *testing.T) {
|
||||
res, _ := parse_rfc1288_request("/W foozle.. ")
|
||||
if res != BadRequest {
|
||||
t.Error("Expected BadRequest")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue