Skip to content

Instantly share code, notes, and snippets.

@yanisurbis
Created September 22, 2022 12:59
Show Gist options
  • Save yanisurbis/d40feea43d7ae71244dc92642299ace7 to your computer and use it in GitHub Desktop.
Save yanisurbis/d40feea43d7ae71244dc92642299ace7 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"fmt"
"log"
"net"
"os"
"strings"
"time"
)
// should be enough to receive the header
const CHUNK_SIZE = 1000
const TMP_FILE_PATH = "/tmp/gflib_client"
const ADDRESS = "localhost:8888"
const FILE_PREFIX = "/courses/ud923/filecorpus/"
const HEADER_DIVIDER = "\r\n\r\n"
func check(str string, e error) {
if e != nil {
log.Fatal(str+": ", e)
}
}
func contains(x string, y string) {
if !strings.Contains(x, y) {
log.Fatalf("should contain %s\n", y)
}
}
func printSuccess() {
println("Ok!")
}
func compareSentAndReceivedFiles_(received []byte, path string) {
bytesSentFile, err := os.ReadFile("../server_root" + path)
if err != nil {
log.Fatal("failed to open a file, ", err)
}
//fmt.Println(bytesSentFile)
//fmt.Println(bytesReceivedFileWithoutZeros)
//fmt.Println(string(bytesSentFile))
//fmt.Println(string(received))
//
//fmt.Println(bytesSentFile)
//fmt.Println(received)
if bytes.Compare(bytesSentFile, received) != 0 {
err = os.Remove(TMP_FILE_PATH)
check("failed to delete a file", err)
f, err := os.Create(TMP_FILE_PATH)
check("failed to create temporary file", err)
_, err = f.Write(received)
check("failed to write to file", err)
f.Sync()
log.Fatalf("Files %s should be equal", path)
}
}
func testFilesAreTransferredOk(filePaths []string) {
for _, path := range filePaths {
filePath := FILE_PREFIX + path
conn, err := net.Dial("tcp", ADDRESS)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
request := fmt.Sprintf("GETFILE GET %s", filePath)
fmt.Println("Request:", request)
_, err = conn.Write([]byte(request + "\r\n\r\n"))
if err != nil {
log.Fatal("Failed to write: ", err)
}
reply := make([]byte, CHUNK_SIZE)
n, err := conn.Read(reply)
check("failed to read first chunk of data", err)
replyAsStr := string(reply[:n])
parts := strings.Split(replyAsStr, "\r\n\r\n")
response := parts[0]
fmt.Println("Response:", response)
fileData := []byte(parts[1])
check("failed to write first chunk to the temp file", err)
for {
n, err = conn.Read(reply)
if err != nil {
//log.Println("failed to read chunk of data", err)
break
}
if n == 0 {
break
}
fileData = append(fileData, reply[:n]...)
check("failed to write chunk of data", err)
}
conn.Close()
compareSentAndReceivedFiles_(fileData, filePath)
printSuccess()
}
}
func testHeaderCouldBeSentInParts(description string, path string) {
println("Testing:", description)
filePath := FILE_PREFIX + path
conn, err := net.Dial("tcp", ADDRESS)
check("failed to dial", err)
{
request := fmt.Sprintf("GETFILE GET %s", filePath)
fmt.Println("Request:", request)
{
_, err = conn.Write([]byte("GETFILE "))
check("failed to write, 1", err)
<-time.After(time.Duration(200) * time.Millisecond)
_, err = conn.Write([]byte("GET "))
check("failed to write, 2", err)
_, err = conn.Write([]byte(filePath))
check("failed to write, 3", err)
_, err = conn.Write([]byte("\r\n\r\n"))
check("failed to write, 4", err)
}
}
reply := make([]byte, CHUNK_SIZE)
n, err := conn.Read(reply)
check("failed to read first chunk of data", err)
replyAsStr := string(reply[:n])
parts := strings.Split(replyAsStr, "\r\n\r\n")
response := parts[0]
fmt.Println("Response:", response)
contains(response, "GETFILE OK")
contains(replyAsStr, HEADER_DIVIDER)
conn.Close()
printSuccess()
}
func testBrokenHeaders(description string, filePaths []string) {
println("Testing:", description)
for i, path := range filePaths {
filePath := FILE_PREFIX + path
conn, err := net.Dial("tcp", ADDRESS)
check("failed to dial", err)
var request string
if i == 0 {
request = fmt.Sprintf("GETFILE1 GET %s", filePath)
} else if i == 1 {
request = fmt.Sprintf("GETFILE PUT %s", filePath)
} else {
request = fmt.Sprintf("GETFILE GET ")
}
fmt.Println("Request:", request)
_, err = conn.Write([]byte(request + "\r\n\r\n"))
check("failed to write", err)
reply := make([]byte, CHUNK_SIZE)
n, err := conn.Read(reply)
check("failed to read first chunk of data", err)
replyAsStr := string(reply[:n])
parts := strings.Split(replyAsStr, "\r\n\r\n")
response := parts[0]
fmt.Println("Response:", response)
contains(response, "GETFILE INVALID")
contains(replyAsStr, HEADER_DIVIDER)
conn.Close()
printSuccess()
}
}
func testDifferentRequests(description string) {
println("Testing:", description)
paths := []string{"/xxxx", "foo.jpg"}
responses := []string{"GETFILE FILE_NOT_FOUND", "GETFILE INVALID"}
for i, path := range paths {
conn, err := net.Dial("tcp", ADDRESS)
check("failed to dial", err)
_, err = conn.Write([]byte(fmt.Sprintf("GETFILE GET %s\r\n\r\n", path)))
check("failed to write", err)
reply := make([]byte, CHUNK_SIZE)
n, err := conn.Read(reply)
check("failed to read first chunk of data", err)
replyAsStr := string(reply[:n])
parts := strings.Split(replyAsStr, "\r\n\r\n")
response := parts[0]
fmt.Println("Response:", response)
contains(response, responses[i])
contains(replyAsStr, HEADER_DIVIDER)
conn.Close()
}
printSuccess()
}
func main() {
filePaths := []string{"digits.txt",
"paraglider.jpg", "road.jpg",
"yellowstone.jpg",
//"1kb-sample-file-0.png",
//"1kb-sample-file-1.html", "1kb-sample-file-2.png",
//"1kb-sample-file-3.jpg", "1kb-sample-file-4.png",
}
//filePaths := []string{"/courses/ud923/filecorpus/digits.txt"}
testFilesAreTransferredOk(filePaths)
testHeaderCouldBeSentInParts(
"test that header could be sent in chunks",
filePaths[0],
)
testBrokenHeaders("broken header", filePaths)
testDifferentRequests("should return FILE_NOT_FOUND")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment