// Helper function for handleRequest - handles the case where we are received meta.info file. // @param net.Conn conn - The socket which the client is asking on // @param string request - The request sent to tracker // @return error - An error can be produced when trying to send a file or if there is incorrect // syntax in the request - otherwise error will be nil. func handlePush(request string, conn net.Conn) error { // Client syntax for push is "Meta_Push:<LynkName>\n" // So tmpArr[0] - Meta_Push | tmpArr[1] - <LynkName> tmpArr := strings.Split(request, ":") if len(tmpArr) != 2 { conn.Close() return errors.New("Invalid Request Syntax") } if client.IsDownloading(tmpArr[1]) { client.StopDownload(tmpArr[1]) } metaPath := lynxutil.HomePath + tmpArr[1] + "/" err := os.Remove(metaPath) if err != nil { fmt.Println(err) return err } newMetainfo, err := os.Create(metaPath) if err != nil { fmt.Println(err) return err } bufIn, err := ioutil.ReadAll(conn) // Decrypt //key := []byte("abcdefghijklmnopqrstuvwxyz123456") key := []byte(lynxutil.PrivateKey) var plainFile []byte if plainFile, err = mycrypt.Decrypt(key, bufIn); err != nil { log.Fatal(err) } // Decompress r, _ := gzip.NewReader(bytes.NewBuffer(plainFile)) bufOut, _ := ioutil.ReadAll(r) r.Read(bufOut) r.Close() fmt.Println(len(bufIn), "Bytes Received") newMetainfo.Write(bufOut) return nil // No errors if we reached this point }
// The function responsible for actually asking for a file from a peer // @param string lynkName - The name of the lynk we're asking about // @param string fileName - The name of the file to find in the peers // @param net.Conn conn - The connection to the peer // @return bool - True or false is returned based on whether or not we successfully received a file func askForFile(lynkName, fileName string, conn net.Conn) bool { fmt.Fprintf(conn, "Do_You_Have_FileName:"+lynkName+"/"+fileName+"\n") reply, err := bufio.NewReader(conn).ReadString('\n') // Waits for a String ending in newline reply = strings.TrimSpace(reply) gotFile := false // Has file and no errors if reply != "NO" && err == nil { file, err := os.Create(lynxutil.HomePath + lynkName + "/" + fileName) if err != nil { return gotFile } defer file.Close() bufIn, err := ioutil.ReadAll(conn) if err != nil { return gotFile } // Decrypt //key := []byte("abcdefghijklmnopqrstuvwxyz123456") key := []byte(lynxutil.PrivateKey) var plainFile []byte if plainFile, err = mycrypt.Decrypt(key, bufIn); err != nil { log.Fatal(err) } // Decompress r, _ := gzip.NewReader(bytes.NewBuffer(plainFile)) bufOut, _ := ioutil.ReadAll(r) r.Read(bufOut) r.Close() fmt.Println(len(bufIn), "Bytes Received") file.Write(bufOut) gotFile = true } return gotFile }
// Unit tests for listen, handle, and send functions as well as push meta // @param *testing.T t - The wrapper for the test func TestListenHandleSend(t *testing.T) { fmt.Println("\n----------------TestListen----------------") conn, err := net.Dial("tcp", "127.0.0.1:8080") if err != nil { t.Error(err.Error()) } else { fmt.Println("Successfully Connected To Server") successful++ } fmt.Println("\n----------------TestHandleRequest----------------") fmt.Fprintf(conn, "Do_You_Have_FileName:Tests/fake.txt\n") reply, err := bufio.NewReader(conn).ReadString('\n') // Waits for a String ending in newline reply = strings.TrimSpace(reply) if reply == "NO" { fmt.Println("Successfully Handled Invalid Request") successful++ } else { t.Error("Test failed, expected to have server respond 'NO'. Got", reply) } conn.Close() conn, err = net.Dial("tcp", "127.0.0.1:8080") fmt.Fprintf(conn, "Do_You_Have_FileName:Tests/test.txt\n") reply, err = bufio.NewReader(conn).ReadString('\n') // Waits for a String ending in newline reply = strings.TrimSpace(reply) if reply == "YES" { fmt.Println("Successfully Handled Valid Request") successful++ } else { t.Error("Test failed, expected to have server respond 'YES'. Got", reply) } fmt.Println("\n----------------TestSendFile----------------") file, err := os.Create("test.txt_ServerTest") if err != nil { t.Error(err.Error()) } defer file.Close() bufIn := make([]byte, 512) // Set to 512 because we know this file is small _, err = conn.Read(bufIn) // Decrypt //key := []byte("abcdefghijklmnopqrstuvwxyz123456") key := []byte(lynxutil.PrivateKey) var plainFile []byte if plainFile, err = mycrypt.Decrypt(key, bufIn); err != nil { log.Fatal(err) } // Decompress r, err := gzip.NewReader(bytes.NewBuffer(plainFile)) bufOut := make([]byte, 512) // Set to 512 because we know this file is small r.Read(bufOut) file.Write(bufOut) r.Close() if err != nil { t.Error(err.Error()) } else { fmt.Println("Successfully Sent 'text.txt'") successful++ } content, _ := ioutil.ReadFile("test.txt_ServerTest") s := string(content) if !strings.Contains(s, "test contents") { t.Error("File contents invalid. Got '" + s + "'") } else { fmt.Println("File contents valid.") successful++ } fmt.Println("\n----------------TestPushMeta----------------") if err != nil { t.Error(err.Error()) } else { fmt.Println("Successfully Pushed Meta") successful++ } fmt.Println("\nSuccess on ", successful, "/", total, " tests.") }