├── API_Folder_Structure.odt ├── Connect.txt ├── Go Course-Slides1.pdf ├── GoCourse-Slides2.pdf ├── Lecture162-BenchmarkingHTTP1vsHTTP2 ├── http1_api │ ├── benchmarking.txt │ └── http1.go └── http2_api │ ├── benchmarking.txt │ ├── cert.pem │ ├── go.mod │ ├── go.sum │ ├── http2.go │ └── key.pem ├── Lecture163-Serialize-Deserialize └── main.go ├── MailHog instructions.txt ├── XSS Practice.txt ├── gRPC_API ├── MailHog.txt ├── cert │ ├── cert.pem │ └── key.pem ├── cmd │ └── grpcapi │ │ ├── .env │ │ ├── binaries │ │ ├── grpc_api_amd64_NON_TLS │ │ ├── grpc_api_amd64_TLS │ │ ├── obfuscated_grpc_api_amd64_NON_TLS │ │ └── obfuscated_grpc_api_amd64_TLS │ │ └── server.go ├── commands.txt ├── execsdatajson.txt ├── ghz_config.json ├── go.mod ├── go.sum ├── internals │ ├── api │ │ ├── handlers │ │ │ ├── execs.go │ │ │ ├── helpers.go │ │ │ ├── server_struct.go │ │ │ ├── students.go │ │ │ └── teachers.go │ │ └── interceptors │ │ │ ├── authentication.go │ │ │ ├── rate_limiting.go │ │ │ └── response_time.go │ ├── models │ │ ├── exec.go │ │ ├── student.go │ │ └── teacher.go │ └── repositories │ │ └── mongodb │ │ ├── execs_crud.go │ │ ├── helpers.go │ │ ├── mongoconnect.go │ │ ├── students_crud.go │ │ └── teachers_crud.go ├── pkg │ └── utils │ │ ├── authorize_user.go │ │ ├── error_handler.go │ │ ├── jwt.go │ │ └── password.go ├── proto │ ├── execs.proto │ ├── gen │ │ ├── execs.pb.go │ │ ├── execs.pb.validate.go │ │ ├── execs_grpc.pb.go │ │ ├── main.pb.go │ │ ├── main.pb.validate.go │ │ ├── main_grpc.pb.go │ │ ├── students.pb.go │ │ ├── students.pb.validate.go │ │ └── students_grpc.pb.go │ ├── main.proto │ ├── students.proto │ └── validate │ │ └── validate.proto ├── studentsdatajson.txt └── teachersdatajson.txt ├── go vs nodejs basic api ├── go_api_simple │ ├── benchmarking.txt │ ├── go.mod │ └── server.go └── node_api_simple │ ├── express_server.js │ ├── fastify_server.js │ ├── package-lock.json │ ├── package.json │ └── server.js ├── gocourse-RESTPractice ├── httpclient │ └── client.go ├── httpserver │ └── server.go └── simple_api │ ├── cert.pem │ ├── go.mod │ ├── go.sum │ ├── key.pem │ ├── openssl.cnf │ └── server.go ├── gocourse ├── advanced │ ├── atomic_counter.go │ ├── buffered_channels.go │ ├── channel_directions.go │ ├── channel_synchronization.go │ ├── channels.go │ ├── closing_channels.go │ ├── context.go │ ├── goroutines.go │ ├── multiplexing_select.go │ ├── mutex.go │ ├── non_blocking_channel_operation.go │ ├── os_processes.go │ ├── rate_limiting)_token_bucket_algo.go │ ├── rate_limiting_fixed_window_algo.go │ ├── rate_limiting_leaky_bucket_algo.go │ ├── reflect.go │ ├── signals.go │ ├── sorting.go │ ├── stateful_goroutines.go │ ├── testing_benchmarking_test.go │ ├── tickers.go │ ├── timers.go │ ├── unbuffered_channels.go │ ├── wait_groups.go │ └── worker_pools.go ├── basics │ ├── arithmetic_operators.go │ ├── arrays.go │ ├── constants.go │ ├── data_types.go │ ├── defer.go │ ├── exit.go │ ├── for_as_while.go │ ├── for_loop.go │ ├── functions.go │ ├── guessing_game.go │ ├── hello │ ├── hello.txt │ ├── if_else.go │ ├── import.txt │ ├── init.go │ ├── maps.go │ ├── multiple_return_values.go │ ├── naming_conventions.go │ ├── operators.txt │ ├── panic.go │ ├── range.go │ ├── recover.go │ ├── slices.go │ ├── switch_case.go │ ├── variables.go │ └── variadic_functions.go ├── intermediate │ ├── app.log │ ├── base64encoding.go │ ├── bufio.go │ ├── closures.go │ ├── command_line_args.go │ ├── command_line_sub_comm.go │ ├── custom_error.go │ ├── directories.go │ ├── embed_directive.go │ ├── env_var.go │ ├── epoch.go │ ├── errors.go │ ├── example.txt │ ├── example_.txt │ ├── file_paths.go │ ├── fmt_package.go │ ├── formatting_verbs.go │ ├── generics.go │ ├── go.mod │ ├── hashing_crypto.go │ ├── interfaces.go │ ├── io.go │ ├── io.txt │ ├── json.go │ ├── line_filter.go │ ├── logging.go │ ├── logrus_logging.go │ ├── methods.go │ ├── number_parsing.go │ ├── output.txt │ ├── pointers.go │ ├── random_numbers.go │ ├── reading_files.go │ ├── recursion.go │ ├── regular_expressions.go │ ├── string_formatting.go │ ├── string_functions.go │ ├── strings_runes.go │ ├── struct_embedding.go │ ├── struct_tags.go │ ├── structs.go │ ├── temp_files_dirs.go │ ├── text_templates.go │ ├── time.go │ ├── time_formatting.go │ ├── type_conversion.go │ ├── url_parsing.go │ ├── writeString.txt │ ├── writing_files.go │ ├── xml.go │ └── zap_log.go └── mac │ ├── cvp.go │ ├── deadlocks.go │ ├── for_select.go │ ├── race_conditions.go │ ├── rw_mutex.go │ ├── sync_new_cond.go │ ├── sync_once.go │ └── sync_pool.go ├── grpc_practice ├── benchmarking-Lecture305 │ ├── RUST │ │ ├── rust_api │ │ │ ├── .gitignore │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── main.rs │ │ └── wrk_benchmarking.lua │ ├── gRPC_gateway with TLS │ │ ├── benchmark_ghz.json │ │ ├── cert.pem │ │ ├── commands.txt │ │ ├── go.mod │ │ ├── go.sum │ │ ├── key.pem │ │ ├── proto │ │ │ ├── google │ │ │ │ └── api │ │ │ │ │ ├── annotations.proto │ │ │ │ │ └── http.proto │ │ │ ├── main.pb.go │ │ │ ├── main.pb.gw.go │ │ │ ├── main.pb.validate.go │ │ │ ├── main.proto │ │ │ ├── main_grpc.pb.go │ │ │ └── validate │ │ │ │ └── validate.proto │ │ ├── server.go │ │ └── wrk_benchmarking.lua │ ├── gRPC_gateway │ │ ├── commands.txt │ │ ├── go.mod │ │ ├── go.sum │ │ ├── proto │ │ │ ├── google │ │ │ │ └── api │ │ │ │ │ ├── annotations.proto │ │ │ │ │ └── http.proto │ │ │ ├── main.pb.go │ │ │ ├── main.pb.gw.go │ │ │ ├── main.pb.validate.go │ │ │ ├── main.proto │ │ │ ├── main_grpc.pb.go │ │ │ └── validate │ │ │ │ └── validate.proto │ │ ├── server.go │ │ └── wrk_benchmarking.lua │ └── rest_api_non_tls │ │ ├── server.go │ │ └── wrk_benchmarking.lua ├── gRPC_Gateway_RESTComboAPI │ ├── cert.pem │ ├── commands.txt │ ├── go.mod │ ├── go.sum │ ├── key.pem │ ├── proto │ │ ├── gen │ │ │ ├── main.pb.go │ │ │ ├── main.pb.gw.go │ │ │ ├── main.pb.validate.go │ │ │ └── main_grpc.pb.go │ │ ├── google │ │ │ └── api │ │ │ │ ├── annotations.proto │ │ │ │ └── http.proto │ │ ├── main.proto │ │ └── validate │ │ │ └── validate.proto │ └── server.go ├── gRPC_protovalidate │ ├── commands.txt │ ├── go.mod │ ├── go.sum │ ├── proto │ │ ├── gen │ │ │ ├── main.pb.go │ │ │ ├── main.pb.validate.go │ │ │ └── main_grpc.pb.go │ │ ├── main.proto │ │ └── validate │ │ │ └── validate.proto │ └── server.go ├── grpc_client │ ├── cert.pem │ ├── client.go │ ├── go.mod │ ├── go.sum │ └── proto │ │ ├── farewell │ │ └── farewell.proto │ │ ├── gen │ │ ├── farewell │ │ │ └── farewell.pb.go │ │ ├── greeter.pb.go │ │ ├── main.pb.go │ │ └── main_grpc.pb.go │ │ ├── greeter.proto │ │ └── main.proto ├── grpc_server │ ├── cert.conf │ ├── cert.pem │ ├── commands.txt │ ├── go.mod │ ├── go.sum │ ├── key.pem │ ├── proto │ │ ├── farewell │ │ │ └── farewell.proto │ │ ├── gen │ │ │ ├── farewell │ │ │ │ └── farewell.pb.go │ │ │ ├── greeter.pb.go │ │ │ ├── main.pb.go │ │ │ └── main_grpc.pb.go │ │ ├── greeter.proto │ │ └── main.proto │ └── server.go ├── grpc_stream_client │ ├── client.go │ ├── commands.txt │ ├── go.mod │ ├── go.sum │ └── proto │ │ ├── gen │ │ ├── main.pb.go │ │ └── main_grpc.pb.go │ │ └── main.proto └── grpc_streams │ ├── commands.txt │ ├── go.mod │ ├── go.sum │ ├── proto │ ├── gen │ │ ├── main.pb.go │ │ └── main_grpc.pb.go │ └── main.proto │ └── server.go ├── modernroutes ├── go.mod └── main.go ├── proto_buf_practice ├── command.txt └── proto │ ├── gen │ ├── main.pb.go │ ├── order.pb.go │ └── user │ │ └── user.pb.go │ ├── main.proto │ ├── order.proto │ └── user │ └── user.proto ├── rest_api_go ├── MailHog.txt ├── ROLEFORROUTES.TXT ├── cmd │ └── api │ │ ├── binaries │ │ ├── macOS │ │ │ └── rest_api_macOS_arm64 │ │ ├── rest_api_linux_X86-64_NONTLS_WO_Mdlwrs │ │ ├── rest_api_linux_X86-64_NONTLS_With_Mdlwrs │ │ ├── rest_api_linux_X86-64_TLS_WO_Mdlwrs_http2 │ │ ├── rest_api_linux_X86-64_withMdlwrs_http2_TLS │ │ └── win │ │ │ └── rest_api_windows_X86-64 │ │ ├── cert.pem │ │ ├── key.pem │ │ ├── obfuscated │ │ ├── rest_api_obf_linux_X86-64_TLS_With_Mdlwars │ │ └── rest_api_obf_linux_x86-64_NONTLS_WO_Mdlwars │ │ └── server.go ├── execsdata.json ├── go.mod ├── go.sum ├── helpful_commands.txt ├── internal │ ├── api │ │ ├── handlers │ │ │ ├── execs.go │ │ │ ├── helpers.go │ │ │ ├── students.go │ │ │ └── teachers.go │ │ ├── middlewares │ │ │ ├── compression.go │ │ │ ├── cors.go │ │ │ ├── exclude_routes.go │ │ │ ├── hpp.go │ │ │ ├── jwt_middleware.go │ │ │ ├── rate_limiter.go │ │ │ ├── response_time.go │ │ │ ├── sanitize.go │ │ │ └── security_headers.go │ │ └── router │ │ │ ├── execs_router.go │ │ │ ├── router.go │ │ │ ├── students_router.go │ │ │ └── teachers_router.go │ ├── models │ │ ├── exec.go │ │ ├── student.go │ │ └── teacher.go │ └── repository │ │ └── sqlconnect │ │ ├── exec_crud.go │ │ ├── sqlconfig.go │ │ ├── students_crud.go │ │ └── teachers_crud.go ├── pkg │ └── utils │ │ ├── authorize_user.go │ │ ├── database_utils.go │ │ ├── error_handler.go │ │ ├── jwt.go │ │ ├── middlewaresutil.go │ │ └── password.go ├── studentsdata.json └── teachersdata.json └── subrouting └── main.go /API_Folder_Structure.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/API_Folder_Structure.odt -------------------------------------------------------------------------------- /Connect.txt: -------------------------------------------------------------------------------- 1 | Discord server (stay connected for early updates / early bird discounts on future courses) :  https://discord.gg/aVJPs76B6M 2 | 3 | Youtube: https://www.youtube.com/channel/UClxNmn1bqGoSTwTyiWRkY1A 4 | 5 | X/Twitter (Follow for timely updates on new courses and course updates/discounts and offers): https://x.com/codeovation -------------------------------------------------------------------------------- /Go Course-Slides1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/Go Course-Slides1.pdf -------------------------------------------------------------------------------- /GoCourse-Slides2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/GoCourse-Slides2.pdf -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http1_api/benchmarking.txt: -------------------------------------------------------------------------------- 1 | sudo apt-get install wrk 2 | wrk -t8 -c400 -d30s "http://localhost:8080/person?id=1" 3 | 4 | h2load --h1 -n 100000 -c 100 -t 4 "http://localhost:8080/person?id=1" 5 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http1_api/http1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | // Person struct 9 | type Person struct { 10 | Name string `json:"name"` 11 | Age int32 `json:"age"` 12 | } 13 | 14 | // Sample data 15 | var personData = map[string]Person{ 16 | "1": {Name: "John Doe", Age: 30}, 17 | "2": {Name: "Jane Doe", Age: 28}, 18 | "3": {Name: "Jack Doe", Age: 25}, 19 | } 20 | 21 | // Handler function for the endpoint 22 | func getPersonHandler(w http.ResponseWriter, r *http.Request) { 23 | // Get the ID from the URL query parameters 24 | id := r.URL.Query().Get("id") 25 | if id == "" { 26 | http.Error(w, "ID is missing", http.StatusBadRequest) 27 | return 28 | } 29 | 30 | // Check if the ID exists in the personData map 31 | person, exists := personData[id] 32 | if !exists { 33 | http.Error(w, "Person not found", http.StatusNotFound) 34 | return 35 | } 36 | 37 | // Set the response header to application/json 38 | w.Header().Set("Content-Type", "application/json") 39 | 40 | // Encode the person data to JSON and write to the response 41 | if err := json.NewEncoder(w).Encode(person); err != nil { 42 | http.Error(w, "Failed to encode response", http.StatusInternalServerError) 43 | } 44 | } 45 | 46 | func main() { 47 | // Set up the endpoint and the handler function 48 | http.HandleFunc("/person", getPersonHandler) 49 | 50 | // Start the server 51 | http.ListenAndServe(":8080", nil) 52 | } 53 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http2_api/benchmarking.txt: -------------------------------------------------------------------------------- 1 | h2load -n 100000 -c 100 -t 4 "https://localhost:8000/person?id=1" 2 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http2_api/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDcTCCAlkCFCQSfoAbfM8LDujBRQwOYcM9i648MA0GCSqGSIb3DQEBCwUAMHUx 3 | CzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMG 4 | A1UECgwMT3JnYW5pemF0aW9uMRwwGgYDVQQLDBNPcmdhbml6YXRpb25hbCBVbml0 5 | MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjQwNzI3MDM0MzA4WhcNMjUwNzI3MDM0 6 | MzA4WjB1MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENp 7 | dHkxFTATBgNVBAoMDE9yZ2FuaXphdGlvbjEcMBoGA1UECwwTT3JnYW5pemF0aW9u 8 | YWwgVW5pdDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC 9 | AQ8AMIIBCgKCAQEAo6Tqdq8wS8e8l21qxLnwG8ei+J/fGKTig76IRBaZmhzBmoE5 10 | U3KB94ZANo//UgEkU2jmcGBkVBUosRVtPrbdYd86XeMMXSl6vvbtkLyKDqODmw24 11 | w2xnsnvHXv684kbq22j8RLoJN4LPAvBzFtG3tfz6t2pL11i0KVDvz25Gn966Nh8n 12 | 5L7ZPcpjptejDgAxOQ/tGz0+WSQlSGIIgBVsh9VfyTQRV45+gSg8vVRQjV5JNO8k 13 | ebHpd1A3vvBtvpSNGdoJs1fqDbGumnVNejEP8whC3knSH1KxJ2lMy68f3zVHK9cK 14 | tYKHkKTRw9lubTY9jYvmEwLXmrhXNVswXDh2pQIDAQABMA0GCSqGSIb3DQEBCwUA 15 | A4IBAQBJBgzslAxm81stDkiTNS4AcnNQbkJjFp36pGTp+1tSH+Uoxs9RhnOkjRTy 16 | Id8vklUrD835hz9DeiCGKMsNMgMa11NSsrTMLzdKNjWI658shFeTIJ7Oe8YKXFZd 17 | a7d98PMomoWSIaP35qv8Ql3HQok8oZd5mh85sX6eaxYd+OoF23W9TO/+HCg2hRIH 18 | R2fvA+nrFL0wLf95tR8SBiNc81ibE4ZOiFD9UYfZyczVdpWlcKHdo5DP+qGoQXn7 19 | CTGyrtZIHOE+Tj4I0O8Dh/0LSP/yV3+babcJOsNU4F1zAcmmbJHr4eKFP8EI7IHG 20 | q46mGLI+2wEDETOzjz5Xoap2eQQX 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http2_api/go.mod: -------------------------------------------------------------------------------- 1 | module http2_api 2 | 3 | go 1.22.5 4 | 5 | require golang.org/x/net v0.27.0 6 | 7 | require golang.org/x/text v0.16.0 // indirect 8 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http2_api/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= 2 | golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 3 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 4 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 5 | -------------------------------------------------------------------------------- /Lecture162-BenchmarkingHTTP1vsHTTP2/http2_api/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjpOp2rzBLx7yX 3 | bWrEufAbx6L4n98YpOKDvohEFpmaHMGagTlTcoH3hkA2j/9SASRTaOZwYGRUFSix 4 | FW0+tt1h3zpd4wxdKXq+9u2QvIoOo4ObDbjDbGeye8de/rziRurbaPxEugk3gs8C 5 | 8HMW0be1/Pq3akvXWLQpUO/Pbkaf3ro2Hyfkvtk9ymOm16MOADE5D+0bPT5ZJCVI 6 | YgiAFWyH1V/JNBFXjn6BKDy9VFCNXkk07yR5sel3UDe+8G2+lI0Z2gmzV+oNsa6a 7 | dU16MQ/zCELeSdIfUrEnaUzLrx/fNUcr1wq1goeQpNHD2W5tNj2Ni+YTAteauFc1 8 | WzBcOHalAgMBAAECggEAAbCYhji5ZjLuEN89oMHtx4+ocGpQNrQvLZ6YUCGunN+K 9 | pUKL2b9/NZPikl2qzIk7+4uEA6mPJ6ofRTLcMa9YOmRAeUs4q7absKCio+G6iDuq 10 | hn2eCJCUQozSKno1b529W54qKriEE1lrs1NR0OzB+aRe32l+1n6xP5L5Ivp3yrtR 11 | D4OV3dLJl6Zdtq7ncbLh7L/Gdp0nQO9htvzqNS75irqxo2kLxLMPZ/i0jiQpsQDp 12 | LJRfV/RUxllLt1DwJyZoFRqRDlnaRCwt2ZmMsE52TJ53P87hfI9w6M16JGVwmquA 13 | UICMHqMMfj4/zS0YrW/P72jh7EAtmGPVPNQRsYXZuQKBgQDi8l6vntMLHieGEEmk 14 | wn04vlvsVFRJYXJo2RqMRt3tqkXvmeFypu18RKnOX85shoyfZgK8pxjYrw5zCwPY 15 | f5gcxy3oP9SaosGfmHoB66aswX9IVy172hqWa5tTNjyU0UwNLa4uf77I/ybf+MJ1 16 | K0NACmVad9uMwR0jVlsJ6nhyjQKBgQC4l/VI7aEghHaQZpA2/3LY19+E7sY0lFhP 17 | omRxsGZpUiuHOG0gWL55egQ8rgOK4QwKRd/bW5AvEi8E346Xq+hlicAGPw+zpupg 18 | O2xix+Ml+ewjLwRk2zvmD4qph/zNx2qywcgp+Jvho0YhrHzhadyH+Q2kbXArVSQv 19 | je7V7kgaeQKBgBWQN+Tx71WIGPNJCuZHwIQquis7XALY6nkB397iQOX7HsgEVAKD 20 | z97V21iLi96N7kCa/bmVGuxDvdi6fDQO85IQbtE5d2b1/fW/FCColl6lyAVEm0LA 21 | V3RhZxHB/oGZXWOHKpyqcKNCcxwm07s0UCB+nGC7MLYwBye7Zc0MZUNlAoGAKSr6 22 | sUEN5kqkhp/ZGerumh3K48K8wY00BM6ayCAnNuX0fzu+WrBwCneD6mSEtbxrCv96 23 | ZVmOVnEfu16AVqMoOTz3bm0x+0cGjl+yVHVv21BZsZ8Sw8uBGFXu/tAtOVd4HFXL 24 | ZlDjsvbO9UOatkr9u/V3bWxaz881OsXUtjFmM0ECgYEAum4kDHIoTQ3MXnKI11n7 25 | 042qB66ODm/HV6qeNf1ufpQIRbVflYMybdw8zvzLG5JmnYhAxk0r+hZ/c1F640ho 26 | HBV+X3snY8L8A68Mz77WQTx+DjBRwTn2jzylv10YH95N77ZR/AZUFCmLk7kgCSuo 27 | qDsYfQlXt7Z2jV8aSviq52A= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /Lecture163-Serialize-Deserialize/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | "strings" 9 | ) 10 | 11 | type User struct { 12 | Name string `json:"name"` 13 | Email string `json:"email"` 14 | } 15 | 16 | func main() { 17 | user := User{Name: "Alice", Email: "alice@example.com"} 18 | fmt.Println(user) 19 | jsonData, err := json.Marshal(user) 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | fmt.Println(string(jsonData)) 24 | 25 | var user1 User 26 | err = json.Unmarshal(jsonData, &user1) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | fmt.Println("User created from json data", user1) 32 | 33 | jsonData1 := `{"name": "John", "email": "john@example.com"}` 34 | reader := strings.NewReader(jsonData1) 35 | decoder := json.NewDecoder(reader) 36 | 37 | var user2 User 38 | err = decoder.Decode(&user2) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | fmt.Println(user2) 43 | 44 | var buf bytes.Buffer 45 | encoder := json.NewEncoder(&buf) 46 | 47 | err = encoder.Encode(user) 48 | if err != nil { 49 | log.Fatal(err) 50 | } 51 | fmt.Println("Encoded json string:", buf.String()) 52 | 53 | } 54 | -------------------------------------------------------------------------------- /MailHog instructions.txt: -------------------------------------------------------------------------------- 1 | Update these lines in your .bashrc or .zshrc file (depending on what your default shell is. 2 | .bashrc or .zshrc files are in your Home Folder. 3 | 4 | Check your shell using command echo $SHELL 5 | 6 | Open these files using any text editor or a command prompt editor like nano or vim and add these lines in your file. 7 | 8 | export GOPATH=$HOME/go 9 | export PATH="$PATH:$GOPATH/bin" 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /XSS Practice.txt: -------------------------------------------------------------------------------- 1 | https://localhost:3000/execs/1/kjhg?param1='%3B%20DROP%20TABLE%20users;%20--¶m2=aacute<"<""<""alert" 2 | 3 | 4 | 5 | 6 | { 7 | "input": "Click me" 8 | } 9 | 10 | { 11 | "input": "" 12 | } 13 | 14 | { 15 | "input": "Click me" 16 | } 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /gRPC_API/MailHog.txt: -------------------------------------------------------------------------------- 1 | go install github.com/mailhog/MailHog@latest 2 | ~/go/bin/MailHog 3 | 4 | UI for incoming emails: http://localhost:8025/ 5 | 6 | -------------------------------------------------------------------------------- /gRPC_API/cert/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDezCCAmOgAwIBAgIUe0huEu/GoUBpOPQtFKYO+lyjtzMwDQYJKoZIhvcNAQEL 3 | BQAwWzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 4 | DVNhbiBGcmFuY2lzY28xCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3Qw 5 | HhcNMjQwODA0MDkyMDE3WhcNMjUwODA0MDkyMDE3WjBbMQswCQYDVQQGEwJVUzET 6 | MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkG 7 | A1UECwwCSVQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD 8 | ggEPADCCAQoCggEBALh1/PFnVQjQOmKjAox74WVT+6nDlWerwK4873drpeHx4FKm 9 | r722zFbuczyu170tcqQeImmIcSCWDXFJ8TQ0dnxSplmg8ydBlCurudW0bGSxi2ao 10 | Rf5QvdyP0y4R3N05IbSAL4Ys43jgHHVNaC8+Sxj59g8yMSuCJKVhKYFcMgG3VDI6 11 | yz8QCy7ejuD5Zv8z/CuF5iD8iUXkjti7ENw6rfPTGSg9GWEctsaGc+y57uSTzPnl 12 | kXx9MK2/Fqjb5qOgcgwGXzwhPQLqTwVbA1QMQngFMnLbAUNq1LuapxyfEP9e4Bgq 13 | y5wFZCkvOnVpXP0ahqMCEAWYnkmskYlCcNnuGikCAwEAAaM3MDUwFAYDVR0RBA0w 14 | C4IJbG9jYWxob3N0MB0GA1UdDgQWBBR6YnDWlIDv5l6okjcrJc38DNTFVTANBgkq 15 | hkiG9w0BAQsFAAOCAQEAinjfEnSudmlGwd9kZc+Sb0lDox9Go73Ym5i5XpVok1mw 16 | 1AnZW+fQTncjatYzR0ZcuP9l655vFpVZfeLOJevXOw28ez5jVHabRxqBNE/jsjTP 17 | wFqtExnGhrJZjObMfHWlOBiHr1OncUwJ3hvubsQmEjdDIlZGCp1VuzF0GlmCFf0V 18 | J3ZELOW5vtzBCBlU5IRomWWn8AwQPcLSCzSXiRx4vCI9oWICsILDeZ5EULwujwqz 19 | Ht2/YRx5bkgTx0fxw7KXkU+l5wCmNRt5ultsCj1EbgpfpkKybgkVk9qElngGO09a 20 | NS/23fXgeoJuU+ObNJTQD7HWllRKz2BPvpCw2g4Yqg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /gRPC_API/cert/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4dfzxZ1UI0Dpi 3 | owKMe+FlU/upw5Vnq8CuPO93a6Xh8eBSpq+9tsxW7nM8rte9LXKkHiJpiHEglg1x 4 | SfE0NHZ8UqZZoPMnQZQrq7nVtGxksYtmqEX+UL3cj9MuEdzdOSG0gC+GLON44Bx1 5 | TWgvPksY+fYPMjErgiSlYSmBXDIBt1QyOss/EAsu3o7g+Wb/M/wrheYg/IlF5I7Y 6 | uxDcOq3z0xkoPRlhHLbGhnPsue7kk8z55ZF8fTCtvxao2+ajoHIMBl88IT0C6k8F 7 | WwNUDEJ4BTJy2wFDatS7mqccnxD/XuAYKsucBWQpLzp1aVz9GoajAhAFmJ5JrJGJ 8 | QnDZ7hopAgMBAAECggEACd1AEjtvurGX+F+16oP9a7PFXjC4CVE6qUFXn6VBZlx5 9 | ndyNbVxx1PxEwVaq8XzqsogXWFlpjfqNls9YzMKOy4XdS3xl7xAnYlEj9kpYZDzH 10 | svewtobkKwADT7q40EPBNQEzNBOryR0C/erjyr2kD8kzirXTwfs1sSUJroHwUqhp 11 | 02ByvlaRM3wLEjdflVWf572Ku6SFSYUp5YW8R8Mqd+qR9s6TLkcezO/F/j+oMZ/A 12 | yBlVD44fHSFA5y6mJZany+KNatPsH/2hOaYgMNfVvozF0Vb/Vy6hION4zr+sN56G 13 | UL5N7wzDGuYZy4LoD2yMDkvW/KVo1soNbPwcDp6kmQKBgQDqWl+JdvscBj9n3tqD 14 | ZFROXW6qzGI3FyS2tLG/hxy8iWLilUhGZSFS26U5w1SF34OQWhbA7wBKz25fAeDF 15 | 5hZUZchqy14gJq/lTFjmFIECqfaWoxGA8X4UY3HafNe97df9KXPhtHbmfAGa5aw7 16 | aOj+jGkdp1WRu6soWOqZUjzqwwKBgQDJf9dNwJWHI15xNBmYguATSYd+DmM5u9cd 17 | iFSRpjBuV4RI+nJdqOIJrYdDwN6JNllArUnidQEcK+lU0HRur9iDoUxSnfPWZu9h 18 | J/BNiJZoGQ+zqjscPA/jS5mzevow4t6kp2B5zXPwk9D/6ZUJQURRY39ibuMnUtKA 19 | ACrFEb7gowKBgARx4FwAGLUoXS2AKY7SaVLvLLkqlTZMRxL8DF8AlgfxZyG7CRrk 20 | siQbLGATF1hOq/Uh8EqKfevtUT+WDohSW9wP7iQwZUGg2jc0In+CpgvB435p61wR 21 | uH10gWVOdt0QVMdlcOA4BwVKFtG0R3b8/2ZMjXXVhab080MZpKFx0Nv3AoGBALMD 22 | B1VFJdKEIpAxuBedFdMsvNnJkG+nKIpNJsyqt1YgHB71mQsKUZ5FculHfKysAwkJ 23 | qp0sU4sim83Ez9vSD2mJsBOpzgoJMtu+rqdDFFRxB1kXgCIqXfcRoAAq3gD2XNQs 24 | +vHbDAiMWd4xNz2cpUQlP/NEDjxOQUKEY3rmtAw/AoGARyRcQ8gbpzmhHNeckZgq 25 | VVL528fa+2AuAJegwRfDjEVOn44ZQZtrV24uoVBYwl/3dEvBbIWihJeh8iEH/L/W 26 | iwDdqo37FESdJVZNtI1TPS1NgZU5zLYhXV1clLNb8/YIC3DVlf4mKgeJuPah6kT7 27 | j/innmRIfQhFYdASUHQqr3U= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /gRPC_API/cmd/grpcapi/.env: -------------------------------------------------------------------------------- 1 | DB_NAME="school" 2 | DB_USER="root" 3 | DB_PASSWORD="root" 4 | JWT_SECRET="super_secret_string" 5 | JWT_EXPIRES_IN=120s 6 | SMTP_HOST="localhost" 7 | SMTP_PORT="1025" 8 | CERT_FILE="/home/codeovation/cert/grpc_cert/cert.pem" 9 | KEY_FILE="/home/codeovation/cert/grpc_cert/key.pem" 10 | RESET_TOKEN_EXP_DURATION=10 11 | SERVER_PORT=:50051 -------------------------------------------------------------------------------- /gRPC_API/cmd/grpcapi/binaries/grpc_api_amd64_NON_TLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/gRPC_API/cmd/grpcapi/binaries/grpc_api_amd64_NON_TLS -------------------------------------------------------------------------------- /gRPC_API/cmd/grpcapi/binaries/grpc_api_amd64_TLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/gRPC_API/cmd/grpcapi/binaries/grpc_api_amd64_TLS -------------------------------------------------------------------------------- /gRPC_API/cmd/grpcapi/binaries/obfuscated_grpc_api_amd64_NON_TLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/gRPC_API/cmd/grpcapi/binaries/obfuscated_grpc_api_amd64_NON_TLS -------------------------------------------------------------------------------- /gRPC_API/cmd/grpcapi/binaries/obfuscated_grpc_api_amd64_TLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/gRPC_API/cmd/grpcapi/binaries/obfuscated_grpc_api_amd64_TLS -------------------------------------------------------------------------------- /gRPC_API/commands.txt: -------------------------------------------------------------------------------- 1 | go get google.golang.org/grpc 2 | go get go.mongodb.org/mongo-driver/bson 3 | go get go.mongodb.org/mongo-driver/mongo/options 4 | go get github.com/envoyproxy/protoc-gen-validate 5 | go get github.com/joho/godotenv 6 | go get github.com/go-mail/mail/v2 7 | go get github.com/golang-jwt/jwt/v5 8 | 9 | ---------------USE THIS BEFORE APPLYING VALIDATION 10 | protoc -I=proto --go_out=. --go-grpc_out=. proto/main.proto proto/students.proto proto/execs.proto 11 | 12 | 13 | ---------------USE THIS AFTER APPLYING VALIDATION 14 | protoc -I=proto --go_out=. --go-grpc_out=. --validate_out="lang=go:." proto/main.proto proto/students.proto proto/execs.proto 15 | 16 | 17 | --------------- BUILDING API BINARY 18 | GOOS=darwin GOARCH=amd64 go build -o macOS_api_x86-64.exe server.go (Not if you are working on macOS amd64 system) 19 | GOOS=windows GOARCH=amd64 go build -o windows_binary/binary-windows_x86-64 server.go (Not if you are working on macOS amd64 system) 20 | 21 | go build -o cmd/grpcapi/binaries/grpc_api_amd64 cmd/grpcapi/server.go 22 | go build -o cmd/grpcapi/binaries/grpc_api_amd64_NON_TLS cmd/grpcapi/server.go 23 | garble build -o cmd/grpcapi/binaries/obfuscated_grpc_api_amd64 cmd/grpcapi/server.go 24 | garble build -o cmd/grpcapi/binaries/obfuscated_grpc_api_amd64_NON_TLS cmd/grpcapi/server.go 25 | 26 | --------------- RUNNING API BINARY 27 | ./grpc_api_amd64_NON_TLS 28 | ./grpc_api_amd64_TLS 29 | ./obfuscated_grpc_api_amd64_NON_TLS 30 | ./obfuscated_grpc_api_amd64_TLS 31 | 32 | 33 | -------------------------------------------------------------------------------- /gRPC_API/ghz_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "proto": "/home/codeovation/cert/grpc_cert/students.proto", 3 | "call": "main.StudentsService.GetStudents", 4 | "concurrency": 100, 5 | "data": { 6 | "page_number": 1, 7 | "page_size": 300 8 | }, 9 | "max-duration": "20s", 10 | "host": "localhost:50051", 11 | "cert": "/home/codeovation/cert/grpc_cert/cert.pem", 12 | "key": "/home/codeovation/cert/grpc_cert/key.pem", 13 | "cacert": "/home/codeovation/cert/grpc_cert/cert.pem", 14 | "metadata": { 15 | "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjU1OTQ2NjYsInJvbGUiOiJhZG1pbiIsInVpZCI6IjY2ZDY5YzgzNmU1NGJkZTg5YTZjMzRlOCIsInVzZXIiOiJhbGljZS5zbWl0aCJ9.AvUlaxaBtPbz-5ROO5UNP0doFLdROUJAv9VhuyK94dM" 16 | } 17 | } -------------------------------------------------------------------------------- /gRPC_API/go.mod: -------------------------------------------------------------------------------- 1 | module grpcapi 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect 7 | github.com/go-mail/mail/v2 v2.3.0 // indirect 8 | github.com/golang-jwt/jwt/v5 v5.2.1 // indirect 9 | github.com/golang/snappy v0.0.4 // indirect 10 | github.com/joho/godotenv v1.5.1 // indirect 11 | github.com/klauspost/compress v1.13.6 // indirect 12 | github.com/montanaflynn/stats v0.7.1 // indirect 13 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 14 | github.com/xdg-go/scram v1.1.2 // indirect 15 | github.com/xdg-go/stringprep v1.0.4 // indirect 16 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect 17 | go.mongodb.org/mongo-driver v1.16.1 // indirect 18 | golang.org/x/crypto v0.24.0 // indirect 19 | golang.org/x/net v0.26.0 // indirect 20 | golang.org/x/sync v0.7.0 // indirect 21 | golang.org/x/sys v0.21.0 // indirect 22 | golang.org/x/text v0.16.0 // indirect 23 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 24 | google.golang.org/grpc v1.66.0 // indirect 25 | google.golang.org/protobuf v1.34.2 // indirect 26 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /gRPC_API/internals/api/handlers/server_struct.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import pb "grpcapi/proto/gen" 4 | 5 | type Server struct { 6 | pb.UnimplementedExecsServiceServer 7 | pb.UnimplementedStudentsServiceServer 8 | pb.UnimplementedTeachersServiceServer 9 | } 10 | -------------------------------------------------------------------------------- /gRPC_API/internals/api/interceptors/rate_limiting.go: -------------------------------------------------------------------------------- 1 | package interceptors 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "sync" 8 | "time" 9 | 10 | "google.golang.org/grpc" 11 | "google.golang.org/grpc/codes" 12 | "google.golang.org/grpc/peer" 13 | "google.golang.org/grpc/status" 14 | ) 15 | 16 | type rateLimiter struct { 17 | mu sync.Mutex 18 | visitors map[string]int 19 | limit int 20 | resetTime time.Duration 21 | } 22 | 23 | func NewRateLimiter(limit int, resetTime time.Duration) *rateLimiter { 24 | rl := &rateLimiter{ 25 | visitors: make(map[string]int), 26 | limit: limit, 27 | resetTime: resetTime, 28 | } 29 | // start the reset routine 30 | go rl.resetVisitorCount() 31 | return rl 32 | } 33 | 34 | func (rl *rateLimiter) resetVisitorCount() { 35 | for { 36 | time.Sleep(rl.resetTime) 37 | rl.mu.Lock() 38 | rl.visitors = make(map[string]int) 39 | rl.mu.Unlock() 40 | } 41 | } 42 | 43 | func (rl *rateLimiter) RateLimitInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 44 | fmt.Println("Rate Limiter Middleware being returned...") 45 | rl.mu.Lock() 46 | defer rl.mu.Unlock() 47 | 48 | p, ok := peer.FromContext(ctx) 49 | if !ok { 50 | return nil, status.Error(codes.Unauthenticated, "unable to get client IP") 51 | } 52 | 53 | visitorIP := p.Addr.String() 54 | rl.visitors[visitorIP]++ 55 | log.Printf("+++++++++ Vistor count from IP: %s: %d\n", visitorIP, rl.visitors[visitorIP]) 56 | 57 | if rl.visitors[visitorIP] > rl.limit { 58 | return nil, status.Error(codes.ResourceExhausted, "Too many requests") 59 | } 60 | 61 | fmt.Println("Rate Limiter ends...") 62 | return handler(ctx, req) 63 | } 64 | -------------------------------------------------------------------------------- /gRPC_API/internals/api/interceptors/response_time.go: -------------------------------------------------------------------------------- 1 | package interceptors 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "google.golang.org/grpc" 10 | "google.golang.org/grpc/metadata" 11 | "google.golang.org/grpc/status" 12 | ) 13 | 14 | func ResponseTimeInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 15 | log.Println("ResponseTimeInterceptor Ran") 16 | // Record the start time 17 | start := time.Now() 18 | 19 | // Call the handler to proceed with the client request 20 | resp, err := handler(ctx, req) 21 | 22 | // Calculate the duration 23 | duration := time.Since(start) 24 | 25 | // Log the request details with duration 26 | st, _ := status.FromError(err) 27 | fmt.Printf("Method: %s, Status: %d, Duration: %v\n", info.FullMethod, st.Code(), duration) 28 | 29 | md := metadata.Pairs("X-Response-Time", duration.String()) 30 | grpc.SetHeader(ctx, md) 31 | 32 | log.Println("Sending response from ResponseTimeInterceptor ") 33 | return resp, err 34 | } 35 | -------------------------------------------------------------------------------- /gRPC_API/internals/models/exec.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Exec struct { 4 | Id string `protobuf:"id,omitempty" bson:"_id,omitempty"` 5 | FirstName string `protobuf:"first_name,omitempty" bson:"first_name,omitempty"` 6 | LastName string `protobuf:"last_name,omitempty" bson:"last_name,omitempty"` 7 | Email string `protobuf:"email,omitempty" bson:"email,omitempty"` 8 | Username string `protobuf:"username,omitempty" bson:"username,omitempty"` 9 | Password string `protobuf:"password,omitempty" bson:"password,omitempty"` 10 | Role string `protobuf:"role,omitempty" bson:"role,omitempty"` 11 | PasswordChangedAt string `protobuf:"password_changed_at,omitempty" bson:"password_changed_at,omitempty"` 12 | UserCreatedAt string `protobuf:"user_created_at,omitempty" bson:"user_created_at,omitempty"` 13 | PasswordResetToken string `protobuf:"password_reset_token,omitempty" bson:"password_reset_token,omitempty"` 14 | PasswordTokenExpires string `protobuf:"password_token_expires,omitempty" bson:"password_token_expires,omitempty"` 15 | InactiveStatus bool `protobuf:"inactive_status" bson:"inactive_status"` 16 | } 17 | -------------------------------------------------------------------------------- /gRPC_API/internals/models/student.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Student struct { 4 | Id string `protobuf:"id,omitempty" bson:"_id,omitempty"` 5 | FirstName string `protobuf:"first_name,omitempty" bson:"first_name,omitempty"` 6 | LastName string `protobuf:"last_name,omitempty" bson:"last_name,omitempty"` 7 | Email string `protobuf:"email,omitempty" bson:"email,omitempty"` 8 | Class string `protobuf:"class,omitempty" bson:"class,omitempty"` 9 | } 10 | -------------------------------------------------------------------------------- /gRPC_API/internals/models/teacher.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Teacher struct { 4 | Id string `protobuf:"id,omitempty" bson:"_id,omitempty"` 5 | FirstName string `protobuf:"first_name,omitempty" bson:"first_name,omitempty"` 6 | LastName string `protobuf:"last_name,omitempty" bson:"last_name,omitempty"` 7 | Email string `protobuf:"email,omitempty" bson:"email,omitempty"` 8 | Class string `protobuf:"class,omitempty" bson:"class,omitempty"` 9 | Subject string `protobuf:"subject,omitempty" bson:"subject,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /gRPC_API/internals/repositories/mongodb/mongoconnect.go: -------------------------------------------------------------------------------- 1 | package mongodb 2 | 3 | import ( 4 | "context" 5 | "grpcapi/pkg/utils" 6 | 7 | "go.mongodb.org/mongo-driver/mongo" 8 | "go.mongodb.org/mongo-driver/mongo/options" 9 | ) 10 | 11 | func CreateMongoClient() (*mongo.Client, error) { 12 | ctx := context.Background() 13 | // client, err := mongo.Connect(ctx, options.Client().ApplyURI("username:password@mongodb://localhost:27017")) 14 | client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017")) 15 | if err != nil { 16 | return nil, utils.ErrorHandler(err, "Unable to connect to database") 17 | } 18 | 19 | err = client.Ping(ctx, nil) 20 | if err != nil { 21 | return nil, utils.ErrorHandler(err, "Unable to ping database") 22 | } 23 | 24 | // log.Println("Connected to MongoDB") 25 | return client, nil 26 | } 27 | -------------------------------------------------------------------------------- /gRPC_API/pkg/utils/authorize_user.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | ) 7 | 8 | type ContextKey string 9 | 10 | func AuthorizeUser(ctx context.Context, allowedRoles ...string) error { 11 | userRole, ok := ctx.Value(ContextKey("role")).(string) 12 | if !ok { 13 | return errors.New("user not authorized for access: role not found") 14 | } 15 | 16 | for _, allowedRole := range allowedRoles { 17 | if allowedRole == userRole { 18 | return nil 19 | } 20 | } 21 | return errors.New("user not authorized for access") 22 | } 23 | -------------------------------------------------------------------------------- /gRPC_API/pkg/utils/error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | func ErrorHandler(err error, message string) error { 10 | errorLogger := log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) 11 | errorLogger.Println(message, err) 12 | return fmt.Errorf(message) 13 | } 14 | -------------------------------------------------------------------------------- /gRPC_API/pkg/utils/jwt.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "sync" 6 | "time" 7 | 8 | "github.com/golang-jwt/jwt/v5" 9 | ) 10 | 11 | func SignToken(userId string, username, role string) (string, error) { 12 | jwtSecret := os.Getenv("JWT_SECRET") 13 | jwtExpiresIn := os.Getenv("JWT_EXPIRES_IN") 14 | 15 | claims := jwt.MapClaims{ 16 | "uid": userId, 17 | "user": username, 18 | "role": role, 19 | } 20 | 21 | if jwtExpiresIn != "" { 22 | duration, err := time.ParseDuration(jwtExpiresIn) 23 | if err != nil { 24 | return "", ErrorHandler(err, "Internal error") 25 | } 26 | claims["exp"] = jwt.NewNumericDate(time.Now().Add(duration)) 27 | } else { 28 | claims["exp"] = jwt.NewNumericDate(time.Now().Add(15 * time.Minute)) 29 | } 30 | 31 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 32 | 33 | signedToken, err := token.SignedString([]byte(jwtSecret)) 34 | if err != nil { 35 | return "", ErrorHandler(err, "Internal error") 36 | } 37 | 38 | return signedToken, nil 39 | } 40 | 41 | var JwtStore = JWTStore{ 42 | Tokens: make(map[string]time.Time), 43 | } 44 | 45 | type JWTStore struct { 46 | mu sync.Mutex 47 | Tokens map[string]time.Time 48 | } 49 | 50 | func (store *JWTStore) AddToken(token string, expiryTime time.Time) { 51 | store.mu.Lock() 52 | defer store.mu.Unlock() 53 | store.Tokens[token] = expiryTime 54 | } 55 | 56 | func (store *JWTStore) CleanUpExpiredTokens() { 57 | for { 58 | time.Sleep(2 * time.Minute) 59 | 60 | store.mu.Lock() 61 | for token, timeStamp := range store.Tokens { 62 | if time.Now().After(timeStamp) { 63 | delete(store.Tokens, token) 64 | } 65 | } 66 | store.mu.Unlock() 67 | } 68 | } 69 | 70 | func (store *JWTStore) IsLoggedOut(token string) bool { 71 | store.mu.Lock() 72 | defer store.mu.Unlock() 73 | _, ok := store.Tokens[token] 74 | return ok 75 | } 76 | -------------------------------------------------------------------------------- /gRPC_API/pkg/utils/password.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/subtle" 6 | "encoding/base64" 7 | "errors" 8 | "fmt" 9 | "strings" 10 | 11 | "golang.org/x/crypto/argon2" 12 | ) 13 | 14 | func VerifyPassword(password, encodedHash string) error { 15 | parts := strings.Split(encodedHash, ".") 16 | if len(parts) != 2 { 17 | return ErrorHandler(errors.New("invalid encoded hash format"), "internal server error") 18 | } 19 | 20 | saltBase64 := parts[0] 21 | hashedPasswordBase64 := parts[1] 22 | 23 | salt, err := base64.StdEncoding.DecodeString(saltBase64) 24 | if err != nil { 25 | return ErrorHandler(err, "internal server error") 26 | } 27 | 28 | hashedPassword, err := base64.StdEncoding.DecodeString(hashedPasswordBase64) 29 | if err != nil { 30 | return ErrorHandler(err, "internal error") 31 | } 32 | 33 | hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) 34 | 35 | if len(hash) != len(hashedPassword) { 36 | return ErrorHandler(errors.New("hash length mismatch"), "incorrect password") 37 | } 38 | 39 | if subtle.ConstantTimeCompare(hash, hashedPassword) == 1 { 40 | return nil 41 | } 42 | return ErrorHandler(errors.New("incorrect password"), "incorrect password") 43 | } 44 | 45 | func HashPassword(password string) (string, error) { 46 | if password == "" { 47 | return "", ErrorHandler(errors.New("password is blank"), "please enter password") 48 | } 49 | salt := make([]byte, 16) 50 | _, err := rand.Read(salt) 51 | if err != nil { 52 | return "", ErrorHandler(errors.New("failed to generate salt"), "internal error") 53 | } 54 | 55 | hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) 56 | saltBase64 := base64.StdEncoding.EncodeToString(salt) 57 | hashBase64 := base64.StdEncoding.EncodeToString(hash) 58 | 59 | encodedHash := fmt.Sprintf("%s.%s", saltBase64, hashBase64) 60 | return encodedHash, nil 61 | } 62 | -------------------------------------------------------------------------------- /gRPC_API/proto/students.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | option go_package = "/proto/gen;grpcapipb"; 6 | 7 | service StudentsService { 8 | rpc GetStudents (GetStudentsRequest) returns (Students); 9 | rpc AddStudents (Students) returns (Students); 10 | rpc UpdateStudents (Students) returns (Students); 11 | rpc DeleteStudents (StudentIds) returns (DeleteStudentsConfirmation); 12 | } 13 | 14 | message DeleteStudentsConfirmation { 15 | string status = 1; 16 | repeated string deleted_ids = 2; 17 | } 18 | 19 | message StudentIds { 20 | repeated string ids = 1; 21 | } 22 | 23 | message GetStudentsRequest { 24 | Student student = 1; 25 | repeated SortField sort_by = 2; 26 | uint32 page_number = 3; 27 | uint32 page_size = 4; 28 | } 29 | 30 | message SortField { 31 | string field = 1; 32 | Order order = 2; 33 | } 34 | 35 | enum Order { 36 | ASC = 0; 37 | DESC = 1; 38 | } 39 | 40 | message Student { 41 | string id = 1; 42 | string first_name = 2; 43 | string last_name = 3; 44 | string email = 4; 45 | string class = 5; 46 | } 47 | 48 | message Students { 49 | repeated Student students = 1; 50 | } -------------------------------------------------------------------------------- /go vs nodejs basic api/go_api_simple/benchmarking.txt: -------------------------------------------------------------------------------- 1 | sudo apt-get install wrk 2 | wrk -t8 -c400 -d30s "http://localhost:8080/person?id=1" 3 | 4 | -------------------------------------------------------------------------------- /go vs nodejs basic api/go_api_simple/go.mod: -------------------------------------------------------------------------------- 1 | module go_api_simple 2 | 3 | go 1.22.5 4 | -------------------------------------------------------------------------------- /go vs nodejs basic api/go_api_simple/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | // Person struct 11 | type Person struct { 12 | Name string `json:"name"` 13 | Age int32 `json:"age"` 14 | } 15 | 16 | // Sample data 17 | var personData = map[string]Person{ 18 | "1": {Name: "John Doe", Age: 30}, 19 | "2": {Name: "Jane Doe", Age: 28}, 20 | "3": {Name: "Jack Doe", Age: 25}, 21 | } 22 | 23 | // Handler function for the endpoint 24 | func getPersonHandler(w http.ResponseWriter, r *http.Request) { 25 | // Get the ID from the URL query parameters 26 | id := r.URL.Query().Get("id") 27 | if id == "" { 28 | http.Error(w, "ID is missing", http.StatusBadRequest) 29 | return 30 | } 31 | 32 | // Check if the ID exists in the personData map 33 | person, exists := personData[id] 34 | if !exists { 35 | http.Error(w, "Person not found", http.StatusNotFound) 36 | return 37 | } 38 | 39 | // Set the response header to application/json 40 | w.Header().Set("Content-Type", "application/json") 41 | 42 | // Encode the person data to JSON and write to the response 43 | if err := json.NewEncoder(w).Encode(person); err != nil { 44 | http.Error(w, "Failed to encode response", http.StatusInternalServerError) 45 | } 46 | } 47 | 48 | func main() { 49 | // Define the port 50 | port := 8080 51 | 52 | // Print the confirmation message 53 | fmt.Printf("Server started on port %d\n", port) 54 | 55 | // Set up the endpoint and the handler function 56 | http.HandleFunc("/person", getPersonHandler) 57 | 58 | // Start the server 59 | log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) 60 | } 61 | -------------------------------------------------------------------------------- /go vs nodejs basic api/node_api_simple/express_server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cluster = require('cluster'); 3 | const os = require('os') 4 | 5 | const numCPUs = os.cpus().length; 6 | const port = 8080; 7 | 8 | if (cluster.isMaster) { 9 | for (let i=0; i { 14 | console.log("Worker ${worker.process.pid} died. Forking a new worker..."); 15 | cluster.fork(); 16 | }) 17 | } else { 18 | const app = express(); 19 | 20 | 21 | // Sample data 22 | const personData = { 23 | "1": { Name: "John Doe", Age: 30 }, 24 | "2": { Name: "Jane Doe", Age: 28 }, 25 | "3": { Name: "Jack Doe", Age: 25 } 26 | }; 27 | 28 | // Handler function for the endpoint 29 | app.get('/person', (req, res) => { 30 | const id = req.query.id; 31 | 32 | if (!id) { 33 | return res.status(400).send('ID is missing'); 34 | } 35 | 36 | const person = personData[id]; 37 | 38 | if (!person) { 39 | return res.status(404).send('Person not found'); 40 | } 41 | 42 | res.json(person); 43 | }); 44 | 45 | // Start the server 46 | app.listen(port, () => { 47 | console.log(`Server started on port ${port}`); 48 | }); 49 | 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /go vs nodejs basic api/node_api_simple/fastify_server.js: -------------------------------------------------------------------------------- 1 | // const fastify = require('fastify')({ logger: true }); 2 | const fastify = require('fastify')(); 3 | 4 | const cluster = require('cluster'); 5 | const os = require('os') 6 | 7 | const numCPUs = os.cpus().length; 8 | 9 | if (cluster.isMaster) { 10 | for (let i=0; i { 15 | console.log("Worker ${worker.process.pid} died. Forking a new worker..."); 16 | cluster.fork(); 17 | }) 18 | } else { 19 | 20 | // Sample data 21 | const personData = { 22 | "1": { Name: "John Doe", Age: 30 }, 23 | "2": { Name: "Jane Doe", Age: 28 }, 24 | "3": { Name: "Jack Doe", Age: 25 } 25 | }; 26 | 27 | // Define the route 28 | fastify.get('/person', async (request, reply) => { 29 | const id = request.query.id; 30 | 31 | if (!id) { 32 | reply.code(400).send('ID is missing'); 33 | return; 34 | } 35 | 36 | const person = personData[id]; 37 | 38 | if (!person) { 39 | reply.code(404).send('Person not found'); 40 | return; 41 | } 42 | 43 | reply.send(person); 44 | }); 45 | 46 | // Start the server 47 | const start = async () => { 48 | try { 49 | await fastify.listen({port: 8080}); 50 | fastify.log.info(`Server started on port 8080`); 51 | } catch (err) { 52 | fastify.log.error(err); 53 | process.exit(1); 54 | } 55 | }; 56 | start(); 57 | } -------------------------------------------------------------------------------- /go vs nodejs basic api/node_api_simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node_api_simple", 3 | "version": "1.0.0", 4 | "main": "express_server.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "start": "node server.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "express": "^4.19.2", 15 | "fastify": "^4.28.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /go vs nodejs basic api/node_api_simple/server.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | const url = require('url'); 3 | const cluster = require('cluster'); 4 | const os = require('os') 5 | 6 | const numCPUs = os.cpus().length; 7 | 8 | // Sample data 9 | const personData = { 10 | "1": { Name: "John Doe", Age: 30 }, 11 | "2": { Name: "Jane Doe", Age: 28 }, 12 | "3": { Name: "Jack Doe", Age: 25 } 13 | }; 14 | 15 | // Handler function for the endpoint 16 | const requestHandler = (req, res) => { 17 | const parsedUrl = url.parse(req.url, true); 18 | const path = parsedUrl.pathname; 19 | const query = parsedUrl.query; 20 | 21 | if (path === '/person') { 22 | const id = query.id; 23 | 24 | if (!id) { 25 | res.statusCode = 400; 26 | res.setHeader('Content-Type', 'text/plain'); 27 | res.end('ID is missing'); 28 | return; 29 | } 30 | 31 | const person = personData[id]; 32 | 33 | if (!person) { 34 | res.statusCode = 404; 35 | res.setHeader('Content-Type', 'text/plain'); 36 | res.end('Person not found'); 37 | return; 38 | } 39 | 40 | res.statusCode = 200; 41 | res.setHeader('Content-Type', 'application/json'); 42 | res.end(JSON.stringify(person)); 43 | } else { 44 | res.statusCode = 404; 45 | res.setHeader('Content-Type', 'text/plain'); 46 | res.end('Not Found'); 47 | } 48 | }; 49 | 50 | // Define the port 51 | const port = 8080; 52 | 53 | if (cluster.isMaster) { 54 | for (let i=0; i { 59 | console.log("Worker ${worker.process.pid} died. Forking a new worker..."); 60 | cluster.fork(); 61 | }) 62 | } else { 63 | 64 | // Create the server 65 | const server = http.createServer(requestHandler); 66 | 67 | // Start the server 68 | server.listen(port, () => { 69 | console.log(`Server started on port ${port}`); 70 | }); 71 | } -------------------------------------------------------------------------------- /gocourse-RESTPractice/httpclient/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func main() { 10 | 11 | // Create a new http client 12 | client := &http.Client{} 13 | 14 | // resp, err := client.Get("https://jsonplaceholder.typicode.com/posts/1") 15 | resp, err := client.Get("https://swapi.dev/api/people/1") 16 | if err != nil { 17 | fmt.Println("Error making GET request:", err) 18 | return 19 | } 20 | defer resp.Body.Close() 21 | 22 | // Read and print the response body 23 | body, err := io.ReadAll(resp.Body) 24 | if err != nil { 25 | fmt.Println("Error reading response body:", err) 26 | return 27 | } 28 | 29 | // fmt.Println(body) 30 | fmt.Println(string(body)) 31 | } 32 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/httpserver/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | func main() { 10 | 11 | http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) { 12 | fmt.Fprintln(resp, "Hello Server!") 13 | }) 14 | 15 | const port string = ":8080" 16 | 17 | fmt.Println("Server Listening on port:", port) 18 | err := http.ListenAndServe(port, nil) 19 | if err != nil { 20 | log.Fatalln("error starting server", err) 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/simple_api/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDcTCCAlkCFEKI7yDtTNPb5MupIrsF+cIMCaDKMA0GCSqGSIb3DQEBCwUAMHUx 3 | CzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMG 4 | A1UECgwMT3JnYW5pemF0aW9uMRwwGgYDVQQLDBNPcmdhbml6YXRpb25hbCBVbml0 5 | MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjQwODE3MDQ0MTEyWhcNMjUwODE3MDQ0 6 | MTEyWjB1MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENp 7 | dHkxFTATBgNVBAoMDE9yZ2FuaXphdGlvbjEcMBoGA1UECwwTT3JnYW5pemF0aW9u 8 | YWwgVW5pdDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC 9 | AQ8AMIIBCgKCAQEAm3a15AyP0j7MEnF8RFNl+ntq8X67uJ3eYXCtpUD5wpYRiJZn 10 | nw+kC4W6juPBeVmUsqMiJ1SDqcTrC7PQMkCU3NzoEb/I1JF70NadDIBctj8ny2HI 11 | g/VMnj6HwwzAR+YzWI3AqSFSKXWoRUJ4F+r0R5FkvZvDzMJz2O7p1sR7pGx5YXwy 12 | 6uNTqItSYlclCsVMnXkB1TRoTPgQJM1CaazPQ+CPztAQhfvSqqErAmdu/Mt3e6/F 13 | lcmXEs7F6O1vEIkvSVQom5rPgDntSFKmvZUhjPM6eQB1HiZH+GEC2YpiNOsdyQmV 14 | FXXEoxGBi66uku5jPewSBLH99eHTuRUqtTxKMwIDAQABMA0GCSqGSIb3DQEBCwUA 15 | A4IBAQAOuRKsiFSl0ZrV8nlDs5nuRJkJZuLQWHuzOIncNYT0bdxQosus1N44hope 16 | qJZyz443at6r98OCAS885G3j2m+VsYN7dVWWw6IsEazLkE3FanzviBjzcYaQJz3p 17 | UIgV9r8sISEqwssNc+ipbcnDtCM9Q/5+2qd/1/JmVI7Ps4FDjtB1mbCL3Kj5uqoj 18 | xUtAxSHLlKuN1D8s5K91Y2uUoTSu50I4P9QWIn7ordYv3XYuXIkdyUNJh16qvg1m 19 | yu1+BaeFX2Yth3SoPnupN3lhJxTghv4jR+d7JYo31+7TRHaRHruEmWP/yDLJAA+N 20 | liLVcicm7I2ukPAR9HwG0Mn+O5zi 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/simple_api/go.mod: -------------------------------------------------------------------------------- 1 | module simpleapi 2 | 3 | go 1.22.5 4 | 5 | require golang.org/x/net v0.28.0 6 | 7 | require golang.org/x/text v0.17.0 // indirect 8 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/simple_api/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= 2 | golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 3 | golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= 4 | golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 5 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/simple_api/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCbdrXkDI/SPswS 3 | cXxEU2X6e2rxfru4nd5hcK2lQPnClhGIlmefD6QLhbqO48F5WZSyoyInVIOpxOsL 4 | s9AyQJTc3OgRv8jUkXvQ1p0MgFy2PyfLYciD9UyePofDDMBH5jNYjcCpIVIpdahF 5 | QngX6vRHkWS9m8PMwnPY7unWxHukbHlhfDLq41Ooi1JiVyUKxUydeQHVNGhM+BAk 6 | zUJprM9D4I/O0BCF+9KqoSsCZ278y3d7r8WVyZcSzsXo7W8QiS9JVCibms+AOe1I 7 | Uqa9lSGM8zp5AHUeJkf4YQLZimI06x3JCZUVdcSjEYGLrq6S7mM97BIEsf314dO5 8 | FSq1PEozAgMBAAECggEAEtgo5CPBqzKBehrXfVC+o8YiCHPcPVylgBowcj+WBsg6 9 | B9xzYwx6Tgs/ueJRqWv6Ykzz7uCHtSRxeVGqguzhHoSIfN5KcbnQ0FezYbiNhGnT 10 | YQvRSm2JhAUAX9xD0nNM9gb4u4eWdgAVDZApDn0kbyholbMz4LYRZNJQ9f+LHTr4 11 | ZjVS3paPD6xe6IxxohAwpeeqTu3M/Jst6fTA1tfF71agJxwafe2ITfqKfTMjuOjs 12 | +qV7A45prQV7RClyA46BAj9UVzIhfSgWOYgzvbPfKdZN6gLp965+QDPda9g84/p/ 13 | V4ZLAKsk9vF5LYC96kmVJBTRWV7Gq5+N+ZAKa06HAQKBgQDUXNG7cuTh7MuCW6tJ 14 | P8iZwIax/K0UvRhGLu1fVQVxWLENCqYbURGMECY7/a6B3ThzUbqaZskS6DXd/wtO 15 | lEolqS3spclaU69A1uvXP8C7g2eBU5v3HuMabCKiZNR0z0+ZqREVADCoG52FRyDX 16 | mb2OT70eAQ8b4kB9NK0An0zdcQKBgQC7aMR4X7bZr4WYLoXkFz0P/e94G8/msN4p 17 | LsNwPeH+C0OizpjDIIw765jS7RSszKtRY+Jsoe/ZIZntiEgEvTJCD4KS4042jOjr 18 | z40NsKEyStoalgbH50WQljrYFiv6aLiKgT1AslUr7hwR9NSgOKB6xikbQkdcdOE4 19 | 1WvnNNdf4wKBgBVw/bgYZKWu++lAii3OI9nqR29HHM6gPQgxCsR6WB9WniG79oOB 20 | juz+YG3kMi9of5+dG+MlB55CFdZBPwoDDO16hGmFX6wgEOzSBmPoSvRj0xqKr4+m 21 | 7bUoP+L3nT/iAp54JIJjT4ZZq3DeeqFqI2pwAJ876iOdl3dMzz7l1qPxAoGBAIsW 22 | e1IXPz6aLN1AEfCxaok23oZWpdrBg3AvG69uzg3cUEtBZ1DSFCHYfah1efWxRKh4 23 | KDCVksukS3hlv4V84RL0LeVUO9TyiV+Rv07cuxX3RZ2boNa2BwQC6xM6iVMka2mn 24 | 90zPzbR32G9fNHrg7AGSlil77DhrKkgi5R1IM1wfAoGAAycpTAjYGRsaJyIe0QGC 25 | Ruxuilbo/QwXkFcwTjeuHwiBV4/XOOR2t6WQ/bUoDhhsVTZWabYQjNzC4pFSCUqf 26 | J/XnQ+041YANMC+8e/39pOLYatIgCuTUhA33YCwEIGLy/uWTXxz8Q9CQR0/M3rMf 27 | v0p/cAMtHcaUgZiogKdMBuM= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /gocourse-RESTPractice/simple_api/openssl.cnf: -------------------------------------------------------------------------------- 1 | [req] 2 | default_bits = 2048 3 | distinguished_name = req_distinguished_name 4 | req_extensions = req_ext 5 | prompt = no 6 | 7 | [req_distinguished_name] 8 | C = US 9 | ST = State 10 | L = City 11 | O = Organization 12 | OU = Organizational Unit 13 | CN = localhost 14 | 15 | [req_ext] 16 | subjectAltName = @alt_names 17 | 18 | [alt_names] 19 | DNS.1 = localhost 20 | DNS.2 = 127.0.0.1 21 | -------------------------------------------------------------------------------- /gocourse/advanced/atomic_counter.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "sync/atomic" 7 | ) 8 | 9 | type AtomicCounter struct { 10 | count int64 11 | } 12 | 13 | func (ac *AtomicCounter) increment() { 14 | atomic.AddInt64(&ac.count, 1) 15 | } 16 | 17 | func (ac *AtomicCounter) getValue() int64 { 18 | return atomic.LoadInt64(&ac.count) 19 | } 20 | 21 | func main() { 22 | var wg sync.WaitGroup 23 | numGoroutines := 10 24 | counter := &AtomicCounter{} 25 | // value := 0 26 | 27 | for range numGoroutines { 28 | wg.Add(1) 29 | go func() { 30 | defer wg.Done() 31 | for range 1000 { 32 | counter.increment() 33 | // value++ 34 | } 35 | }() 36 | } 37 | 38 | wg.Wait() 39 | fmt.Printf("Final counter value: %d\n", counter.getValue()) 40 | // fmt.Printf("Final counter value: %d\n", value) 41 | } 42 | -------------------------------------------------------------------------------- /gocourse/advanced/buffered_channels.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // func main() { 9 | // // =========== BLOCKING ON RECEIVE ONLY IF THE BUFFER IS EMPTY 10 | // ch := make(chan int, 2) 11 | 12 | // go func() { 13 | // time.Sleep(2 * time.Second) 14 | // ch <- 1 15 | // ch <- 2 16 | // }() 17 | // fmt.Println("Value: ", <-ch) 18 | // fmt.Println("Value: ", <-ch) 19 | // fmt.Println("End of program.") 20 | // } 21 | 22 | func main() { 23 | // ================== BLOCKING ON SEND ONLY IF THE BUFFER IS FULL 24 | // make(chan Type, capacity) 25 | ch := make(chan int, 2) 26 | ch <- 1 27 | ch <- 2 28 | fmt.Println("Receiving from buffer") 29 | go func() { 30 | fmt.Println("Goroutine 2 second timer started.") 31 | time.Sleep(2 * time.Second) 32 | fmt.Println("Received:", <-ch) //ends <- starts 33 | }() 34 | // fmt.Println("Blocking starts") 35 | ch <- 3 // Blocks because the buffer is full 36 | // fmt.Println("Blocking ends") 37 | // fmt.Println("Received:", <-ch) 38 | // fmt.Println("Received:", <-ch) 39 | } 40 | -------------------------------------------------------------------------------- /gocourse/advanced/channel_directions.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | ch := make(chan int) 8 | producer(ch) 9 | consumer(ch) 10 | } 11 | 12 | // Send only channel 13 | func producer(ch chan<- int) { 14 | go func() { 15 | for i := range 5 { 16 | ch <- i 17 | } 18 | close(ch) 19 | }() 20 | } 21 | 22 | // Receive only channel 23 | func consumer(ch <-chan int) { 24 | for value := range ch { 25 | fmt.Println("Received: ", value) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gocourse/advanced/channel_synchronization.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // func main() { 9 | 10 | // done := make(chan int) 11 | 12 | // go func() { 13 | // fmt.Println("Working...") 14 | // time.Sleep(2 * time.Second) 15 | // done <- 0 16 | // }() 17 | 18 | // <-done 19 | // fmt.Println("Finished.") 20 | 21 | // } 22 | 23 | // func main() { 24 | // ch := make(chan int) 25 | 26 | // go func() { 27 | // ch <- 9 // Blocking until the value is received 28 | // fmt.Println("Sent value") 29 | // }() 30 | 31 | // value := <-ch // Blocking until a value is sent 32 | // fmt.Println(value) 33 | // } 34 | 35 | // // ========= SYNCHRONIZING MULTIPLE GOROUTINES AND ENSURING THAT ALL GOROUTINES ARE COMPLETE 36 | // func main() { 37 | // numGoroutines := 3 38 | // done := make(chan int, 3) 39 | 40 | // for i := range numGoroutines { 41 | // go func(id int) { 42 | // fmt.Printf("Goroutine %d working...\n", id) 43 | // time.Sleep(time.Second) 44 | // done <- id // SENDING SIGNAL OF COMPLETION 45 | // }(i) 46 | // } 47 | 48 | // for range numGoroutines { 49 | // <-done // Wait for each goroutine to finish, WAIT FOR ALL GOROUTINES TO SIGNAL COMPLETION 50 | // } 51 | 52 | // fmt.Println("All goroutines are complete") 53 | // } 54 | 55 | // ========== SYNCHRONIZING DATA EXCHANGE 56 | func main() { 57 | 58 | data := make(chan string) 59 | 60 | go func() { 61 | for i := range 5 { 62 | data <- "hello " + string('0'+i) 63 | time.Sleep(100 * time.Millisecond) 64 | } 65 | close(data) 66 | }() 67 | // close(data) // Channel closed before Goroutine could send a value to the channel 68 | 69 | for value := range data { 70 | fmt.Println("Received value:", value, ":", time.Now()) 71 | } // Loops over only on active channel, creates receiver each time and stops creating receiver (looping) once the channel is closed 72 | } 73 | -------------------------------------------------------------------------------- /gocourse/advanced/channels.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func channels() { 9 | 10 | //variable := make(chan type) '<-' operator 11 | greeting := make(chan string) 12 | greetString := "Hello" 13 | 14 | go func() { 15 | greeting <- greetString // blocking because it is continuously trying to receive values, it is ready to receive continuous flow of data. 16 | greeting <- "World" 17 | for _, e := range "abcde" { 18 | greeting <- "Alphabet: " + string(e) 19 | } 20 | }() 21 | 22 | // go func() { 23 | // receiver := <-greeting 24 | // fmt.Println(receiver) 25 | // receiver = <-greeting 26 | // fmt.Println(receiver) 27 | // }() 28 | 29 | receiver := <-greeting 30 | fmt.Println(receiver) 31 | receiver = <-greeting 32 | fmt.Println(receiver) 33 | 34 | for range 5 { 35 | rcvr := <-greeting 36 | fmt.Println(rcvr) 37 | } 38 | 39 | time.Sleep(1 * time.Second) 40 | fmt.Println("End of program.") 41 | 42 | } 43 | -------------------------------------------------------------------------------- /gocourse/advanced/closing_channels.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func producer(ch chan<- int) { 8 | for i := range 5 { 9 | ch <- i 10 | } 11 | close(ch) 12 | } 13 | 14 | func filter(in <-chan int, out chan<- int) { 15 | for val := range in { 16 | if val%2 == 0 { 17 | out <- val 18 | } 19 | } 20 | close(out) 21 | } 22 | 23 | func main() { 24 | 25 | ch1 := make(chan int) 26 | ch2 := make(chan int) 27 | 28 | go producer(ch1) 29 | go filter(ch1, ch2) 30 | 31 | for val := range ch2 { 32 | fmt.Println(val) 33 | } 34 | } 35 | 36 | // func main() { 37 | // ch := make(chan int) 38 | // go func() { 39 | // close(ch) 40 | // // close(ch) 41 | // }() 42 | // time.Sleep(time.Second) 43 | // } 44 | 45 | // // RANGE OVER CLOSED CHANNEL 46 | // func main() { 47 | // ch := make(chan int) 48 | // go func() { 49 | // for i := range 5 { 50 | // ch <- i 51 | // } 52 | // close(ch) 53 | // }() 54 | 55 | // for val := range ch { 56 | // fmt.Println("Received:", val) 57 | // } 58 | // } 59 | 60 | // // RECEIVING FROM A CLOSED CHANNEL 61 | // func main() { 62 | 63 | // ch := make(chan int) 64 | // close(ch) 65 | 66 | // val, ok := <-ch 67 | // if !ok { 68 | // fmt.Println("Channel is closed") 69 | // return 70 | // } 71 | // fmt.Println(val) 72 | 73 | // } 74 | 75 | // === Simple closing channel example 76 | // func main() { 77 | 78 | // ch := make(chan int) 79 | 80 | // go func() { 81 | // for i := range 5 { 82 | // ch <- i 83 | // } 84 | // close(ch) 85 | // }() 86 | 87 | // for val := range ch { 88 | // fmt.Println(val) 89 | // } 90 | 91 | // } 92 | -------------------------------------------------------------------------------- /gocourse/advanced/goroutines.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // Goroutines are just functions that leave the main thread and run in the background and come back to join the main thread once the functions are finished/ready to return any value 9 | // Goroutines do not stop the program flow and are non blocking 10 | 11 | func main() { 12 | var err error 13 | 14 | fmt.Println("Beginning program.") 15 | go sayHello() 16 | fmt.Println("After sayHello function.") 17 | 18 | go func() { 19 | err = doWork() 20 | }() 21 | 22 | // err = go doWork() // This is not accepted 23 | go printNumbers() 24 | go printLetters() 25 | 26 | time.Sleep(2 * time.Second) 27 | 28 | if err != nil { 29 | fmt.Println("Error:", err) 30 | } else { 31 | fmt.Println("Work completed successfully") 32 | } 33 | } 34 | 35 | func sayHello() { 36 | time.Sleep(1 * time.Second) 37 | fmt.Println("Hello from Goroutine") 38 | } 39 | 40 | func printNumbers() { 41 | for i := 0; i < 5; i++ { 42 | fmt.Println("Number: ", i, time.Now()) 43 | time.Sleep(100 * time.Millisecond) 44 | } 45 | } 46 | 47 | func printLetters() { 48 | for _, letter := range "abcde" { 49 | fmt.Println(string(letter), time.Now()) 50 | time.Sleep(200 * time.Millisecond) 51 | } 52 | } 53 | 54 | func doWork() error { 55 | // Simulate work 56 | time.Sleep(1 * time.Second) 57 | 58 | return fmt.Errorf("an error occured in doWork.") 59 | } 60 | -------------------------------------------------------------------------------- /gocourse/advanced/multiplexing_select.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | ch := make(chan int) 9 | 10 | go func() { 11 | ch <- 1 12 | close(ch) 13 | }() 14 | 15 | for { 16 | select { 17 | case msg, ok := <-ch: 18 | if !ok { 19 | fmt.Println("Channel closed") 20 | // clean up activities 21 | return 22 | } 23 | fmt.Println("Received:", msg) 24 | } 25 | } 26 | } 27 | 28 | // func main() { 29 | // ch := make(chan int) 30 | 31 | // go func() { 32 | // time.Sleep(2 * time.Second) 33 | // ch <- 1 34 | // close(ch) 35 | // }() 36 | 37 | // select { 38 | // case msg := <-ch: 39 | // fmt.Println("Received:", msg) 40 | // case <-time.After(3 * time.Second): 41 | // fmt.Println("Timeout.") 42 | // } 43 | // } 44 | 45 | // func main() { 46 | 47 | // ch1 := make(chan int) 48 | // ch2 := make(chan int) 49 | 50 | // go func() { 51 | 52 | // time.Sleep(time.Second) 53 | // ch1 <- 1 54 | // }() 55 | // go func() { 56 | 57 | // // time.Sleep(time.Second) 58 | // ch2 <- 2 59 | // }() 60 | 61 | // time.Sleep(2 * time.Second) 62 | 63 | // for range 2 { 64 | // select { 65 | // case msg := <-ch1: 66 | // fmt.Println("Received from ch1:", msg) 67 | // case msg := <-ch2: 68 | // fmt.Println("Received from ch2:", msg) 69 | // default: 70 | // fmt.Println("No channels ready...") 71 | // } 72 | // } 73 | 74 | // fmt.Println("End of program") 75 | 76 | // } 77 | -------------------------------------------------------------------------------- /gocourse/advanced/mutex.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | var counter int 10 | var wg sync.WaitGroup 11 | var mu sync.Mutex 12 | 13 | numGoroutines := 5 14 | wg.Add(numGoroutines) 15 | 16 | increment := func() { 17 | defer wg.Done() 18 | for range 1000 { 19 | mu.Lock() 20 | counter++ 21 | mu.Unlock() 22 | } 23 | } 24 | 25 | for range numGoroutines { 26 | go increment() 27 | } 28 | 29 | wg.Wait() 30 | fmt.Printf("Final counter value: %d\n", counter) 31 | } 32 | 33 | // type counter struct { 34 | // mu sync.Mutex 35 | // count int 36 | // } 37 | 38 | // func (c *counter) increment() { 39 | // c.mu.Lock() 40 | // defer c.mu.Unlock() 41 | // c.count++ 42 | // } 43 | 44 | // func (c *counter) getValue() int { 45 | // c.mu.Lock() 46 | // defer c.mu.Unlock() 47 | // return c.count 48 | // } 49 | 50 | // func main() { 51 | 52 | // var wg sync.WaitGroup 53 | // counter := &counter{} 54 | // numGoroutines := 10 55 | 56 | // // wg.Add(numGoroutines) 57 | // for range numGoroutines { 58 | // wg.Add(1) 59 | // go func() { 60 | // defer wg.Done() 61 | // for range 1000 { 62 | // counter.increment() 63 | // // counter.count++ 64 | // } 65 | // }() 66 | // } 67 | 68 | // wg.Wait() 69 | // fmt.Printf("Final counter value: %d\n", counter.getValue()) 70 | 71 | // } 72 | -------------------------------------------------------------------------------- /gocourse/advanced/non_blocking_channel_operation.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | // ch := make(chan int) 11 | 12 | // === NON BLOCKING RECEIVE OPERATION 13 | // select { 14 | // case msg := <-ch: 15 | // fmt.Println("Received:", msg) 16 | // default: 17 | // fmt.Println("No messages available.") 18 | // } 19 | 20 | // // === NON BLOCKING SEND OPERATION 21 | // select { 22 | // case ch <- 1: 23 | // fmt.Println("Sent message.") 24 | // default: 25 | // fmt.Println("Channel is not ready to receive.") 26 | // } 27 | 28 | // === NON BLOCKING OPERATION IN REAL TIME SYSTEMS 29 | 30 | data := make(chan int) 31 | quit := make(chan bool) 32 | 33 | go func() { 34 | for { 35 | select { 36 | case d := <-data: 37 | fmt.Println("Data received:", d) 38 | case <-quit: 39 | fmt.Println("Stopping...") 40 | return 41 | default: 42 | fmt.Println("Waiting for data...") 43 | time.Sleep(500 * time.Millisecond) 44 | } 45 | } 46 | }() 47 | 48 | for i := range 5 { 49 | data <- i 50 | time.Sleep(time.Second) 51 | } 52 | 53 | quit <- true 54 | 55 | } 56 | -------------------------------------------------------------------------------- /gocourse/advanced/rate_limiting)_token_bucket_algo.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type RateLimiter struct { 9 | tokens chan struct{} 10 | refillTime time.Duration 11 | } 12 | 13 | func NewRateLimiter(rateLimit int, refillTime time.Duration) *RateLimiter { 14 | rl := &RateLimiter{ 15 | tokens: make(chan struct{}, rateLimit), 16 | refillTime: refillTime, 17 | } 18 | for range rateLimit { 19 | rl.tokens <- struct{}{} 20 | } 21 | go rl.startRefill() 22 | return rl 23 | } 24 | 25 | func (rl *RateLimiter) startRefill() { 26 | ticker := time.NewTicker(rl.refillTime) 27 | defer ticker.Stop() 28 | for { 29 | select { 30 | case <-ticker.C: 31 | select { 32 | case rl.tokens <- struct{}{}: 33 | default: 34 | } 35 | } 36 | } 37 | } 38 | 39 | func (rl *RateLimiter) allow() bool { 40 | select { 41 | case <-rl.tokens: 42 | return true 43 | default: 44 | return false 45 | } 46 | } 47 | 48 | func main() { 49 | 50 | rateLimiter := NewRateLimiter(5, time.Second) 51 | 52 | for range 10 { 53 | if rateLimiter.allow() { 54 | fmt.Println("Request allowed") 55 | } else { 56 | fmt.Println("Request denied") 57 | } 58 | time.Sleep(300 * time.Millisecond) 59 | } 60 | } 61 | 62 | //1 0 ms First Request Allowed 5 tokens left 63 | //2 200 ms Second Request Allowed 4 tokens left 64 | //3 400 ms Third Request Allowed 3 tokens left 65 | //4 600 ms Fourth Request Allowed 2 tokens left 66 | //5 800 ms Fifth Request Allowed 1 tokens left 67 | //6 1000 ms Sixth Request Allowed (not 0) 1 tokens left the startRefill function executes and adds one more token 68 | //7 1200 ms Seven Request Denied tokens left 69 | //8 1400 ms Eight Request Denied tokens left 70 | //9 1600 ms Ninth Request Denied tokens left 71 | //10 1800 ms Tenth Request Denied 72 | -------------------------------------------------------------------------------- /gocourse/advanced/rate_limiting_fixed_window_algo.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type RateLimiter struct { 10 | mu sync.Mutex 11 | count int 12 | limit int 13 | window time.Duration 14 | resetTime time.Time 15 | } 16 | 17 | func NewRateLimiter(limit int, window time.Duration) *RateLimiter { 18 | return &RateLimiter{ 19 | limit: limit, 20 | window: window, 21 | } 22 | } 23 | 24 | func (rl *RateLimiter) Allow() bool { 25 | rl.mu.Lock() 26 | defer rl.mu.Unlock() 27 | 28 | now := time.Now() 29 | if now.After(rl.resetTime) { 30 | rl.resetTime = now.Add(rl.window) 31 | rl.count = 0 32 | } 33 | 34 | if rl.count < rl.limit { 35 | rl.count++ 36 | return true 37 | } 38 | return false 39 | } 40 | 41 | func main() { 42 | var wg sync.WaitGroup 43 | rateLimiter := NewRateLimiter(3, 1*time.Second) 44 | 45 | for range 10 { 46 | wg.Add(1) 47 | go func() { 48 | if rateLimiter.Allow() { 49 | fmt.Println("Request allowed.") 50 | } else { 51 | fmt.Println("Request denied.") 52 | } 53 | wg.Done() 54 | }() 55 | // time.Sleep(200 * time.Millisecond) 56 | } 57 | wg.Wait() 58 | 59 | } 60 | -------------------------------------------------------------------------------- /gocourse/advanced/signals.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | 13 | pid := os.Getpid() 14 | fmt.Println("Process ID:", pid) 15 | sigs := make(chan os.Signal, 1) 16 | done := make(chan bool, 1) 17 | 18 | // Notify channel on interrupt or terminate signals 19 | signal.Notify(sigs, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGHUP) 20 | 21 | go func() { 22 | sig := <-sigs 23 | fmt.Println("Received signal:", sig) 24 | done <- true 25 | }() 26 | 27 | go func() { 28 | 29 | for { 30 | select { 31 | case <-done: 32 | fmt.Println("Stopping work due to signal.") 33 | // os.Exit(0) 34 | return 35 | default: 36 | fmt.Println("Working...") 37 | time.Sleep(time.Second) 38 | } 39 | } 40 | // sig := <-sigs 41 | // for sig := range sigs { 42 | // switch sig { 43 | // case syscall.SIGINT: 44 | // fmt.Println("Received SIGINT (Interrupt)") 45 | // // case syscall.SIGTERM: 46 | // // fmt.Println("Received SIGTERM (Terminate)") 47 | // case syscall.SIGHUP: 48 | // fmt.Println("Received SIGHUP (Hangup)") 49 | // case syscall.SIGUSR1: 50 | // fmt.Println("Received SIGNUSR1 (User defined Signal 1)") 51 | // fmt.Println("User define function is executed") 52 | // // continue 53 | // } 54 | // // fmt.Println("Graceful exit.") 55 | // // os.Exit(0) 56 | // } 57 | }() 58 | 59 | // Simulate some work 60 | // fmt.Println("Working...") 61 | for { 62 | time.Sleep(time.Second) 63 | } 64 | } 65 | 66 | // tasklist - List of all processes on Windows 67 | // taskkill /F /PID : taskkill /F /PID 12345 68 | // Stop-Process -Id 12345 -Force 69 | -------------------------------------------------------------------------------- /gocourse/advanced/stateful_goroutines.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type StatefulWorker struct { 9 | count int 10 | ch chan int 11 | } 12 | 13 | func (w *StatefulWorker) Start() { 14 | go func() { 15 | for { 16 | select { 17 | case value := <-w.ch: 18 | w.count += value 19 | fmt.Println("Current count:", w.count) 20 | 21 | } 22 | } 23 | }() 24 | } 25 | 26 | func (w *StatefulWorker) Send(value int) { 27 | w.ch <- value 28 | } 29 | 30 | func main() { 31 | 32 | stWorker := &StatefulWorker{ 33 | ch: make(chan int), 34 | } 35 | 36 | stWorker.Start() 37 | 38 | for i := range 5 { 39 | stWorker.Send(i) 40 | time.Sleep(500 * time.Millisecond) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /gocourse/advanced/tickers.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | ticker := time.NewTicker(time.Second) 11 | stop := time.After(5 * time.Second) 12 | defer ticker.Stop() 13 | 14 | for { 15 | select { 16 | case tick := <-ticker.C: 17 | fmt.Println("Tick at:", tick) 18 | case <-stop: 19 | fmt.Println("Stopping ticker.") 20 | return 21 | } 22 | } 23 | } 24 | 25 | // ========= SCHEDULING LOGGING, PERIODIC TASKS, POLLING FOR UPDATES 26 | // func periodicTask() { 27 | // fmt.Println("Performing periodic task at:", time.Now()) 28 | // } 29 | 30 | // func main() { 31 | // ticker := time.NewTicker(time.Second) 32 | // defer ticker.Stop() 33 | 34 | // for { 35 | // select { 36 | // case <-ticker.C: 37 | // periodicTask() 38 | // } 39 | // } 40 | // } 41 | 42 | // func main() { 43 | 44 | // ticker := time.NewTicker(2 * time.Second) 45 | // defer ticker.Stop() 46 | // // for tick := range ticker.C { 47 | // // fmt.Println("Tick at:", tick) 48 | // // } 49 | // i := 1 50 | // for range 5 { 51 | // i *= 2 52 | // fmt.Println(i) 53 | // } 54 | 55 | // // for tick := range ticker.C { 56 | // // i *= 2 57 | // // fmt.Println(tick) 58 | // // } 59 | // } 60 | -------------------------------------------------------------------------------- /gocourse/advanced/timers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | timer1 := time.NewTimer(1 * time.Second) 10 | timer2 := time.NewTimer(2 * time.Second) 11 | 12 | select { 13 | case <-timer1.C: 14 | fmt.Println("Timer1 expired") 15 | case <-timer2.C: 16 | fmt.Println("Timer2 expired") 17 | } 18 | } 19 | 20 | // // =========== SCHEDULING DELAYED OPERATIONS 21 | 22 | // func main() { 23 | // timer := time.NewTimer(2 * time.Second) // non blocking timer starts 24 | 25 | // go func() { 26 | // <-timer.C 27 | // fmt.Println("Delayed operation executed") 28 | // }() 29 | 30 | // fmt.Println("Waiting...") 31 | // time.Sleep(3 * time.Second) // blocking timer starts 32 | // fmt.Println("End of the program") 33 | // } 34 | 35 | // ============= TIMEOUT 36 | // func longRunningOperation() { 37 | // for i := range 20 { 38 | // fmt.Println(i) 39 | // time.Sleep(time.Second) 40 | // } 41 | // } 42 | 43 | // func main() { 44 | // timeout := time.After(3 * time.Second) 45 | // done := make(chan bool) 46 | 47 | // go func() { 48 | // longRunningOperation() 49 | // done <- true 50 | // }() 51 | 52 | // select { 53 | // case <-timeout: 54 | // fmt.Println("operation timed out") 55 | // case <-done: 56 | // fmt.Println("Operation completed") 57 | // } 58 | 59 | // } 60 | 61 | // ======== BASIC TIMER USE 62 | // func main() { 63 | // // time.Sleep(time.Second) 64 | // fmt.Println("Starting app.") 65 | // timer := time.NewTimer(2 * time.Second) 66 | // fmt.Println("Waiting for timer.c") 67 | // stopped := timer.Stop() 68 | // if stopped { 69 | // fmt.Println("Timer stopped") 70 | // } 71 | // timer.Reset(time.Second) 72 | // fmt.Println("Timer reset") 73 | // <-timer.C // blocking in nature 74 | // fmt.Println("Timer expired") 75 | // } 76 | -------------------------------------------------------------------------------- /gocourse/advanced/unbuffered_channels.go: -------------------------------------------------------------------------------- 1 | package advanced 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func unbuffered() { 9 | 10 | ch := make(chan int) 11 | go func() { 12 | time.Sleep(3 * time.Second) 13 | 14 | fmt.Println(<-ch) 15 | fmt.Println("3 second Goroutine finished") 16 | }() 17 | ch <- 1 18 | // go func() { 19 | // time.Sleep(2 * time.Second) 20 | // fmt.Println("2 second Goroutine finished") 21 | // }() 22 | // go func() { 23 | // // ch <- 1 24 | // time.Sleep(3 * time.Second) 25 | // fmt.Println("3 second Goroutine finished") 26 | // }() 27 | // receiver := <-ch 28 | // fmt.Println(receiver) 29 | fmt.Println("End of program") 30 | } 31 | -------------------------------------------------------------------------------- /gocourse/basics/arithmetic_operators.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | // Variable declaration 10 | var a, b int = 10, 3 11 | var result int 12 | 13 | result = a + b 14 | fmt.Println("Addition:", result) 15 | 16 | result = a - b 17 | fmt.Println("Subtraction:", result) 18 | 19 | result = a * b 20 | fmt.Println("Multiplication:", result) 21 | 22 | result = a / b 23 | fmt.Println("Division:", result) 24 | 25 | result = a % b 26 | fmt.Println("Remainder:", result) 27 | 28 | const p float64 = 22.0 / 7.0 29 | fmt.Println(p) 30 | 31 | // Overflow with signed integers 32 | var maxInt int64 = 9223372036854775807 // max value that int64 can hold 33 | fmt.Println(maxInt) 34 | 35 | maxInt = maxInt + 1 36 | fmt.Println(maxInt) 37 | 38 | // Overflow with unsigned integers 39 | var uMaxInt uint64 = 18446744073709551615 // max value for uint64 type 40 | fmt.Println(uMaxInt) 41 | 42 | uMaxInt = uMaxInt + 1 43 | fmt.Println(uMaxInt) 44 | 45 | // Underflow with floating point numbers 46 | var smallFloat float64 = 1.0e-323 47 | fmt.Println(smallFloat) 48 | 49 | smallFloat = smallFloat / math.MaxFloat64 50 | fmt.Println(smallFloat) 51 | 52 | } 53 | -------------------------------------------------------------------------------- /gocourse/basics/arrays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // var arrayName [size]elementType 8 | 9 | // var numbers [5]int 10 | // fmt.Println(numbers) 11 | 12 | // numbers[4] = 20 13 | // fmt.Println(numbers) 14 | 15 | // numbers[0] = 9 16 | // fmt.Println(numbers) 17 | 18 | // fruits := [4]string{"Apple", "Banana", "Orange", "Grapes"} 19 | // fmt.Println("Fruits array:", fruits) 20 | 21 | // fmt.Println("Third element:", fruits[2]) 22 | 23 | // originalArray := [3]int{1, 2, 3} 24 | // copiedArray := originalArray 25 | 26 | // copiedArray[0] = 100 27 | 28 | // fmt.Println("Original array:", originalArray) 29 | // fmt.Println("Copied array:", copiedArray) 30 | 31 | // for i := 0; i < len(numbers); i++ { 32 | // fmt.Println("Element at index,", i, ":", numbers[i]) 33 | // } 34 | 35 | // // underscore is blank identifier, used to store unused values 36 | // for _, v := range numbers { 37 | // fmt.Printf(" Value: %d\n", v) 38 | // } 39 | 40 | // fmt.Println("The length of numbers array is", len(numbers)) 41 | 42 | // // Comparing Arrays 43 | // array1 := [3]int{1, 2, 3} 44 | // array2 := [3]int{10, 2, 3} 45 | 46 | // fmt.Println("Array1 is equal to Array2:", array1 == array2) 47 | 48 | // var matrix [3][3]int = [3][3]int{ 49 | // {1, 2, 3}, 50 | // {4, 5, 6}, 51 | // {7, 8, 9}, 52 | // } 53 | 54 | // fmt.Println(matrix) 55 | 56 | originalArray := [3]int{1, 2, 3} 57 | var copiedArray *[3]int 58 | 59 | copiedArray = &originalArray 60 | copiedArray[0] = 100 61 | 62 | fmt.Println("Original array:", originalArray) 63 | // fmt.Println("Copied array:", *copiedArray) 64 | } 65 | 66 | func someFunction() (int, int) { 67 | return 1, 2 68 | } 69 | -------------------------------------------------------------------------------- /gocourse/basics/constants.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | const pi = 3.14 4 | const GRAVITY = 9.81 5 | 6 | func main() { 7 | 8 | const days int = 7 9 | 10 | const ( 11 | monday = 1 12 | tuesday = 2 13 | wenesday = 3 14 | thursday int = 4 15 | ) 16 | 17 | // name := "John" 18 | 19 | } 20 | -------------------------------------------------------------------------------- /gocourse/basics/data_types.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("Hello" + "World") 7 | fmt.Println("9 X 10 =", 9*10) 8 | fmt.Println("180.18/2.0 = ", 180.18/2.0) 9 | 10 | fmt.Println(true && false) 11 | fmt.Println(true || false) 12 | fmt.Println(!true) 13 | } 14 | -------------------------------------------------------------------------------- /gocourse/basics/defer.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | process(10) 8 | 9 | } 10 | 11 | func process(i int) { 12 | defer fmt.Println("Deffered i value:", i) 13 | defer fmt.Println("First deferred statement executed") 14 | defer fmt.Println("Second deferred statement executed") 15 | defer fmt.Println("Third deferred statement executed") 16 | i++ 17 | fmt.Println("Normal execution statement") 18 | fmt.Println("Value of i:", i) 19 | } 20 | -------------------------------------------------------------------------------- /gocourse/basics/exit.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | 10 | defer fmt.Println("Deferred statement") 11 | 12 | fmt.Println("Starting the main function") 13 | 14 | // Exit with status code of 1 15 | os.Exit(1) 16 | 17 | // This will never be executed 18 | fmt.Println("End of main function") 19 | 20 | } 21 | -------------------------------------------------------------------------------- /gocourse/basics/for_as_while.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // for as while with break 8 | // sum := 0 9 | // for { 10 | // sum += 10 11 | // fmt.Println("Sum:", sum) 12 | // if sum >= 50 { 13 | // break 14 | // } 15 | 16 | // } 17 | 18 | num := 1 19 | for num <= 10 { 20 | if num%2 == 0 { 21 | num++ 22 | continue 23 | } 24 | fmt.Println("Odd Number:", num) 25 | num++ // ++ increment operator increases value by 1 and -- decrement operator, decreases value by 1 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /gocourse/basics/for_loop.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // Simple iteration over a range 8 | // for initialization;condition;post{code block to be executed repeatedly} 9 | for i := 1; i <= 5; i++ { 10 | fmt.Println(i) 11 | } 12 | 13 | // iterate over collection 14 | // numbers := []int{1, 2, 3, 4, 5, 6} 15 | // for index, value := range numbers { 16 | // fmt.Printf("Index: %v, Value:%v\n", index, value) 17 | // } 18 | 19 | // for i := 1; i <= 10; i++ { 20 | // if i%2 == 0 { 21 | // continue // continue the loop but skip the rest of lines/statements 22 | // } 23 | // fmt.Println("Odd Number:", i) 24 | // if i == 5 { 25 | // break // break out of the loop 26 | // } 27 | // } 28 | 29 | // ASTERISK LAYOUT 30 | // rows := 5 31 | 32 | // //Outer loop 33 | // for i := 1; i <= rows; i++ { 34 | // // inner loop for spaces before stars 35 | // for j := 1; j <= rows-i; j++ { 36 | // fmt.Print(" ") 37 | // } 38 | // // inner loop for stars 39 | // for k := 1; k <= 2*i-1; k++ { 40 | // fmt.Print("*") 41 | // } 42 | // fmt.Println() // Move to the next line 43 | // } 44 | 45 | // Go 1.22 update 46 | // for i := range 10 { 47 | // i++ 48 | // fmt.Println(i) 49 | // } 50 | // fmt.Println("We have a lift off!") 51 | 52 | } 53 | -------------------------------------------------------------------------------- /gocourse/basics/functions.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // func (parameters list) returnType { 8 | // code block 9 | // return value 10 | // } 11 | 12 | // sum := add(1, 2) 13 | // fmt.Println(add(2, 3)) 14 | 15 | // greet := func() { 16 | // fmt.Println("Hello Anonymous Function") 17 | // } 18 | 19 | // greet() 20 | 21 | // operation := add 22 | 23 | // result := operation(3, 5) 24 | 25 | // fmt.Println(result) 26 | 27 | // Passing a function as an argument 28 | result := applyOperation(5, 3, add) 29 | fmt.Println("5 + 3 =", result) 30 | 31 | // Returning and using a function 32 | multiplyBy2 := createMultiplier(2) 33 | fmt.Println("6 * 2 = ", multiplyBy2(6)) 34 | 35 | } 36 | 37 | func add(a, b int) int { 38 | return a + b 39 | } 40 | 41 | // Function that takes a function as an argument 42 | func applyOperation(x int, y int, operation func(int, int) int) int { 43 | return operation(x, y) 44 | } 45 | 46 | // Function that returns a function 47 | func createMultiplier(factor int) func(int) int { 48 | return func(x int) int { 49 | return x * factor 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /gocourse/basics/guessing_game.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | 11 | source := rand.NewSource(time.Now().UnixNano()) 12 | random := rand.New(source) 13 | 14 | // Generate a random number between 1 and 100 15 | target := random.Intn(100) + 1 16 | 17 | // Welcome message 18 | fmt.Println("Welcome to the Guessing Game!") 19 | fmt.Println("I have chosen a number between 1 and 100") 20 | fmt.Println("Can you guess what it is?") 21 | 22 | var guess int 23 | for { 24 | fmt.Println("Enter your guess: ") 25 | fmt.Scanln(&guess) 26 | 27 | // Check if the guess if correct 28 | if guess == target { 29 | fmt.Println("Congratulations! You guessed the correct number!") 30 | break 31 | } else if guess < target { 32 | fmt.Println("Too low! Try guessing a higher number.") 33 | } else { 34 | fmt.Println("Too high! Try guessing a lower number.") 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /gocourse/basics/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/gocourse/basics/hello -------------------------------------------------------------------------------- /gocourse/basics/hello.txt: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("Hello World!") 7 | } 8 | -------------------------------------------------------------------------------- /gocourse/basics/if_else.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // if condition { 8 | // block of code 9 | // } 10 | 11 | // age := 25 12 | 13 | // if age >= 18 { 14 | // fmt.Println("You are an adult.") 15 | // } 16 | 17 | // if condition { 18 | // block of code 19 | // } else if { 20 | // block of code 21 | // } else { 22 | // block of code 23 | // } 24 | 25 | // temperature := 25 26 | // if temperature >= 30 { 27 | // fmt.Println("It's hot outside.") 28 | // } else { 29 | // fmt.Println("It's cool outside.") 30 | // } 31 | 32 | score := 95 33 | 34 | // if score >= 90 { 35 | // fmt.Println("Grade A") 36 | // } else if score >= 80 { 37 | // fmt.Println("Grade B") 38 | // } else if score >= 70 { 39 | // fmt.Println("Grade C") 40 | // } else { 41 | // fmt.Println("Grade D") 42 | // } 43 | 44 | if score >= 90 { 45 | fmt.Println("Grade A") 46 | } else if score >= 80 { 47 | fmt.Println("Grade B") 48 | } else if score >= 70 { 49 | fmt.Println("Grade C") 50 | } else { 51 | fmt.Println("Grade D") 52 | } 53 | // this line will be executed after one of the condition is met 54 | 55 | // if condition1 { 56 | // Code block1 57 | // if condition2{ 58 | // code block 2 59 | // } 60 | // } 61 | 62 | // num := 18 63 | // if num%2 == 0 { 64 | // if num%3 == 0 { 65 | // fmt.Println("Number is divisible by both 2 and 3.") 66 | // } else { 67 | // fmt.Println("Number is divisible by 2 but not 3.") 68 | // } 69 | // } else { 70 | // fmt.Println("Number is not divisible by 2.") 71 | // } 72 | 73 | // Logical operators 74 | // || OR 75 | // && AND 76 | 77 | if 10%2 == 0 || 6%2 == 0 { 78 | fmt.Println("Either 10 or 6 are even.") 79 | } 80 | 81 | if 10%2 == 0 && 6%2 == 0 { 82 | fmt.Println("Both 10 and 6 are even.") 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /gocourse/basics/import.txt: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | foo "net/http" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello, Go Standard Library") 10 | 11 | resp, err := foo.Get("https://jsonplaceholder.typicode.com/posts/1") 12 | if err != nil { 13 | fmt.Println("Error: ", err) 14 | return 15 | } 16 | defer resp.Body.Close() 17 | 18 | fmt.Println("HTTP Response Status:", resp.Status) 19 | } 20 | -------------------------------------------------------------------------------- /gocourse/basics/init.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func init() { 6 | fmt.Println("Initializing package1...") 7 | } 8 | 9 | func init() { 10 | fmt.Println("Initializing package2...") 11 | } 12 | 13 | func init() { 14 | fmt.Println("Initializing package3...") 15 | } 16 | 17 | func main() { 18 | 19 | fmt.Println("Inside the main function") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /gocourse/basics/multiple_return_values.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | 10 | // func functionName(parameter1 type1, parameter2 type2,...) (returnType1, returnType2,...){ 11 | //code block 12 | // return returvalue1, returnValue2,... 13 | // } 14 | 15 | q, r := divide(10, 3) 16 | fmt.Printf("Quotient: %v. Remainder: %v\n", q, r) 17 | 18 | result, err := compare(3, 3) 19 | if err != nil { 20 | fmt.Println("Error:", err) 21 | } else { 22 | fmt.Println(result) 23 | } 24 | } 25 | 26 | func divide(a, b int) (quotient int, remainder int) { 27 | quotient = a / b 28 | remainder = a % b 29 | return 30 | } 31 | 32 | func compare(a, b int) (string, error) { 33 | if a > b { 34 | return "a is greater than b", nil 35 | } else if b > a { 36 | return "b is greater than a", nil 37 | } else { 38 | return "", errors.New("Unable to compare which is greater") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gocourse/basics/naming_conventions.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | type EmployeeGoogle struct { 6 | FirstName string 7 | LastName string 8 | Age int 9 | } 10 | 11 | type EmployeeApple struct { 12 | FirstName string 13 | LastName string 14 | Age int 15 | } 16 | 17 | func main() { 18 | // PascalCase 19 | // Eg. CalculateArea, UserInfo, NewHTTPRequest 20 | // Structs, interfaces, enums 21 | 22 | // snake_case 23 | // Eg. user_id, first_name, http_request 24 | 25 | // UPPERCASE 26 | // Use case is Constants 27 | 28 | // mixedCase 29 | // Eg. javaScript, htmlDocument, isValid 30 | 31 | const MAXRETRIES = 5 32 | 33 | var employeeID = 1001 34 | fmt.Println("EmployeeID: ", employeeID) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /gocourse/basics/operators.txt: -------------------------------------------------------------------------------- 1 | Logical Operators: 2 | 3 | ! (logical NOT) 4 | || (logical OR) a > b || a > c || c > g 5 | && (logical AND) a > b && a > c && c > d 6 | 7 | Bitwise Operators: 8 | 9 | & (bitwise AND) 10 | | (bitwise OR) 11 | ^ (bitwise XOR) 12 | &^ (bitwise, AND NOT) 13 | << (left shift) 14 | >> (right shift) 15 | 16 | Comparison Operators: 17 | 18 | == (equal) 19 | != (not equal) 20 | < (less than) 21 | <= (less than or equal to) 22 | > (greater than) 23 | >= (greater than or equal to) -------------------------------------------------------------------------------- /gocourse/basics/panic.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // panic(interface{}) 8 | 9 | // Example of a valid input 10 | process(10) 11 | 12 | // Example of an invalid input 13 | process(-3) 14 | } 15 | 16 | func process(input int) { 17 | 18 | defer fmt.Println("Deferred 1") 19 | defer fmt.Println("Deferred 2") 20 | 21 | if input < 0 { 22 | fmt.Println("Before Panic") 23 | panic("input must be a non-negative number") 24 | // fmt.Println("After Panic") 25 | // defer fmt.Println("Deferred 3") 26 | } 27 | fmt.Println("Processing input:", input) 28 | } 29 | -------------------------------------------------------------------------------- /gocourse/basics/range.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | message := "Hello World" 8 | 9 | for i, v := range message { 10 | // fmt.Println(i, v) 11 | fmt.Printf("Index: %d, Rune: %c\n", i, v) 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /gocourse/basics/recover.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | process() 8 | fmt.Println("Returned from process") 9 | 10 | } 11 | 12 | func process() { 13 | defer func() { 14 | // if r := recover(); r != nil { 15 | r := recover() 16 | if r != nil { 17 | fmt.Println("Recovered:", r) 18 | } 19 | }() 20 | 21 | fmt.Println("Start Process") 22 | panic("Something went wrong!") 23 | fmt.Println("End Process") 24 | } 25 | -------------------------------------------------------------------------------- /gocourse/basics/slices.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "slices" 6 | ) 7 | 8 | func main() { 9 | 10 | // var sliceName[]ElementType 11 | 12 | // var numbers []int 13 | // var numbers1 = []int{1, 2, 3} 14 | 15 | // numbers2 := []int{9, 8, 7} 16 | 17 | // slice := make([]int, 5) 18 | 19 | a := [5]int{1, 2, 3, 4, 5} 20 | slice1 := a[1:4] 21 | 22 | fmt.Println(slice1) 23 | 24 | slice1 = append(slice1, 6, 7) 25 | fmt.Println("Slice1:", slice1) 26 | 27 | sliceCopy := make([]int, len(slice1)) 28 | copy(sliceCopy, slice1) 29 | 30 | fmt.Println("Slicecopy:", sliceCopy) 31 | 32 | // var nilSlice []int 33 | 34 | for i, v := range slice1 { 35 | fmt.Println(i, v) 36 | } 37 | 38 | fmt.Println("Element at index 3 of slice1", slice1[3]) 39 | 40 | // slice1[3] = 50 41 | // fmt.Println("Element at index 3 of slice1", slice1[3]) 42 | 43 | if slices.Equal(slice1, sliceCopy) { 44 | fmt.Println("slice1 is equal to sliceCopy") 45 | } 46 | 47 | twoD := make([][]int, 3) 48 | for i := 0; i < 3; i++ { 49 | innerLen := i + 1 50 | twoD[i] = make([]int, innerLen) 51 | for j := 0; j < innerLen; j++ { 52 | twoD[i][j] = i + j 53 | fmt.Printf("Adding value %d in outer slice at index %d, and in inner slice index of %d\n", i+j, i, j) 54 | } 55 | } 56 | 57 | fmt.Println(twoD) 58 | 59 | // slice[low:high] 60 | slice2 := slice1[2:4] 61 | fmt.Println(slice2) 62 | 63 | } 64 | -------------------------------------------------------------------------------- /gocourse/basics/variables.go: -------------------------------------------------------------------------------- 1 | package basics 2 | 3 | import "fmt" 4 | 5 | var middleName = "Cane" 6 | 7 | func main() { 8 | // var age int 9 | // var name string = "John" 10 | // var name1 = "Jane" 11 | 12 | // count := 10 13 | // lastName := "Smith" 14 | // middleName := "Cane" 15 | // middleName := "Mayor" 16 | fmt.Println(middleName) 17 | // Default values 18 | // Numeric Types: 0 19 | // Boolean Types: false 20 | // String Type: "" 21 | // Pointers, slices, maps, functions, and structs: nil 22 | 23 | // ---- SCOPE 24 | 25 | // fmt.Println(firstName) 26 | 27 | } 28 | 29 | func printname() { 30 | firstName := "Michael" 31 | fmt.Println(firstName) 32 | } 33 | -------------------------------------------------------------------------------- /gocourse/basics/variadic_functions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // ... Ellipsis 8 | // func functionName(param1 type1, param2 ...type2) returnType{ 9 | // function body 10 | // } 11 | 12 | // fmt.Println("Sum of 1, 2, 3:", sum(1, 2, 3)) 13 | // statement, total := sum("The sum of 1, 2, 3 is", 1, 2, 3, 4, 5, 6) 14 | sequence, total := sum(1, 20, 30, 40, 50, 60) 15 | fmt.Println("Sequence: ", sequence, "Total", total) 16 | sequence2, total2 := sum(2, 40, 36, 40, 50, 60) 17 | fmt.Println("Sequence: ", sequence2, "Total", total2) 18 | 19 | numbers := []int{1, 2, 3, 4, 5, 9} 20 | 21 | sequence3, total3 := sum(3, numbers...) 22 | fmt.Println("Sequence: ", sequence3, "Total", total3) 23 | } 24 | 25 | func sum(sequence int, nums ...int) (int, int) { 26 | total := 0 27 | for _, v := range nums { 28 | total += v 29 | } 30 | return sequence, total 31 | } 32 | -------------------------------------------------------------------------------- /gocourse/intermediate/app.log: -------------------------------------------------------------------------------- 1 | INFO: 2024/07/12 08:21:16 logging.go:31: This is a debug message. 2 | DEBUG: 2024/07/12 08:21:53 logging.go:31: This is a debug message. 3 | DEBUG: 2024/07/12 08:24:27 logging.go:35: This is a debug message. 4 | WARN: 2024/07/12 08:24:27 This is a warning message. 5 | INFO: 2024/07/12 08:24:27 logging.go:37: This is an info mesage. 6 | ERROR: 2024/07/12 08:24:27 logging.go:38: This is an error. 7 | -------------------------------------------------------------------------------- /gocourse/intermediate/base64encoding.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | 10 | data := []byte("He~lo, Base64 Encoding") 11 | 12 | // Encode to Base64 13 | encoded := base64.StdEncoding.EncodeToString(data) 14 | fmt.Println(encoded) 15 | 16 | // Decode from Base64 17 | decoded, err := base64.StdEncoding.DecodeString(encoded) 18 | if err != nil { 19 | fmt.Println("Error in decoding:", err) 20 | return 21 | } 22 | fmt.Println("Decoded:", string(decoded)) 23 | 24 | // URL safe, avoid '/' and '+' 25 | 26 | urlSafeEncoded := base64.URLEncoding.EncodeToString(data) 27 | fmt.Println("URL Safe encoded:", urlSafeEncoded) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /gocourse/intermediate/bufio.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | // reader := bufio.NewReader(strings.NewReader("Hello, bufio packageee!\nHow are you doing?")) 12 | 13 | // // Reading byte slice 14 | // data := make([]byte, 20) 15 | // n, err := reader.Read(data) 16 | // if err != nil { 17 | // fmt.Println("Error reading:", err) 18 | // return 19 | // } 20 | // fmt.Printf("Read %d bytes: %s\n", n, data[:n]) 21 | 22 | // line, err := reader.ReadString('\n') 23 | // if err != nil { 24 | // fmt.Println("Error reading string:", err) 25 | // return 26 | // } 27 | // fmt.Println("Read string:", line) 28 | 29 | writer := bufio.NewWriter(os.Stdout) 30 | 31 | // Writing byte slice 32 | data := []byte("Hello, bufio package!\n") 33 | n, err := writer.Write(data) 34 | if err != nil { 35 | fmt.Println("Error writing:", err) 36 | return 37 | } 38 | fmt.Printf("Wrote %d bytes\n", n) 39 | 40 | // Flush the buffer to ensure all data is written to os.Stdout 41 | err = writer.Flush() 42 | if err != nil { 43 | fmt.Println("Error flushing writer:", err) 44 | return 45 | } 46 | 47 | // Writing string 48 | str := "This is a string.\n" 49 | n, err = writer.WriteString(str) 50 | if err != nil { 51 | fmt.Println("Error writing string:", err) 52 | return 53 | } 54 | fmt.Printf("Wrote %d bytes.\n", n) 55 | 56 | // Flush the buffer 57 | err = writer.Flush() 58 | if err != nil { 59 | fmt.Println("Error flushing writer:", err) 60 | return 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /gocourse/intermediate/closures.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // sequence := adder() 8 | 9 | // fmt.Println(sequence()) 10 | // fmt.Println(sequence()) 11 | // fmt.Println(sequence()) 12 | // fmt.Println(sequence()) 13 | 14 | // sequence2 := adder() 15 | // fmt.Println(sequence2()) 16 | 17 | subtracter := func() func(int) int { 18 | 19 | countdown := 99 20 | return func(x int) int { 21 | countdown -= x 22 | return countdown 23 | } 24 | }() 25 | 26 | // Using the closure subtracter 27 | fmt.Println(subtracter(1)) 28 | fmt.Println(subtracter(2)) 29 | fmt.Println(subtracter(3)) 30 | fmt.Println(subtracter(4)) 31 | fmt.Println(subtracter(5)) 32 | 33 | } 34 | 35 | func adder() func() int { 36 | i := 0 37 | fmt.Println("previous value of i:", i) 38 | return func() int { 39 | i++ 40 | fmt.Println("added 1 to i") 41 | return i 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /gocourse/intermediate/command_line_args.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | fmt.Println("Command:", os.Args[0]) 12 | 13 | for i, arg := range os.Args { 14 | fmt.Println("Argument", i, ":", arg) 15 | } 16 | 17 | // Define flags 18 | var name string 19 | var age int 20 | var male bool 21 | 22 | flag.StringVar(&name, "name", "John", "Name of the user") 23 | flag.IntVar(&age, "age", 18, "Age of the user") 24 | flag.BoolVar(&male, "male", true, "Gender of the user") 25 | 26 | flag.Parse() 27 | 28 | fmt.Println("Name:", name) 29 | fmt.Println("Age:", age) 30 | fmt.Println("Male:", male) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /gocourse/intermediate/command_line_sub_comm.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | stringFlag := flag.String("user", "Guest", "Name of the user") 12 | flag.Parse() 13 | fmt.Println(stringFlag) 14 | subcommand1 := flag.NewFlagSet("firstSub", flag.ExitOnError) 15 | subcommand2 := flag.NewFlagSet("secondSub", flag.ExitOnError) 16 | 17 | firstFlag := subcommand1.Bool("processing", false, "Command processing status") 18 | secondFlag := subcommand1.Int("bytes", 1024, "Byte length of result") 19 | 20 | flagsc2 := subcommand2.String("language", "Go", "Enter your language") 21 | 22 | if len(os.Args) < 2 { 23 | fmt.Println("This program requires additional commands") 24 | os.Exit(1) 25 | } 26 | 27 | switch os.Args[1] { 28 | case "firstSub": 29 | subcommand1.Parse(os.Args[2:]) 30 | fmt.Println("subCommand1:") 31 | fmt.Println("processing:", *firstFlag) 32 | fmt.Println("bytes:", *secondFlag) 33 | case "secondSub": 34 | subcommand2.Parse(os.Args[2:]) 35 | fmt.Println("subCommand2:") 36 | fmt.Println("language:", *flagsc2) 37 | default: 38 | fmt.Println("no subcommand entered!") 39 | os.Exit(1) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /gocourse/intermediate/custom_error.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | 10 | err := doSomething() 11 | if err != nil { 12 | fmt.Print(err) 13 | return 14 | } 15 | fmt.Println("Operation completed successfully!") 16 | 17 | } 18 | 19 | type customError struct { 20 | code int 21 | message string 22 | er error 23 | } 24 | 25 | // Error returns the error message. Implementing Error() method of error interface 26 | func (e *customError) Error() string { 27 | return fmt.Sprintf("Error %d: %s, %v\n", e.code, e.message, e.er) 28 | } 29 | 30 | // Function that return a custom error 31 | // 32 | // func doSomething() error { 33 | // return &customError{ 34 | // code: 500, 35 | // message: "Something went wrong!", 36 | // } 37 | // } 38 | func doSomething() error { 39 | err := doSomethingElse() 40 | if err != nil { 41 | return &customError{ 42 | code: 500, 43 | message: "Something went wrong", 44 | er: err, 45 | } 46 | } 47 | return nil 48 | } 49 | 50 | func doSomethingElse() error { 51 | return errors.New("internal error") 52 | } 53 | -------------------------------------------------------------------------------- /gocourse/intermediate/embed_directive.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "fmt" 6 | "io/fs" 7 | "log" 8 | ) 9 | 10 | //go:embed example_.txt 11 | var content string 12 | 13 | //go:embed basics 14 | var basicsFolder embed.FS 15 | 16 | func main() { 17 | 18 | fmt.Println("Embedded content:", content) 19 | content, err := basicsFolder.ReadFile("basics/hello.txt") 20 | if err != nil { 21 | fmt.Println("Error reading file:", err) 22 | return 23 | } 24 | 25 | fmt.Println("Embedded file content:", string(content)) 26 | 27 | err = fs.WalkDir(basicsFolder, "basics", func(path string, d fs.DirEntry, err error) error { 28 | if err != nil { 29 | fmt.Println(err) 30 | return err 31 | } 32 | fmt.Println(path) 33 | return nil 34 | 35 | }) 36 | 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /gocourse/intermediate/env_var.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | func main() { 10 | 11 | user := os.Getenv("USER") 12 | home := os.Getenv("HOME") 13 | 14 | fmt.Println("User env var:", user) 15 | fmt.Println("Home env var:", home) 16 | 17 | err := os.Setenv("FRUIT", "APPLE") 18 | if err != nil { 19 | fmt.Println("Error setting environment variable:", err) 20 | } 21 | fmt.Println("Environment variable FRUIT set successfully.") 22 | 23 | fmt.Println("FRUIT env var:", os.Getenv("FRUIT")) 24 | 25 | // for _, e := range os.Environ() { 26 | // kvpair := strings.SplitN(e, "=", 2) 27 | // fmt.Println(kvpair[0]) 28 | // } 29 | 30 | err = os.Unsetenv("FRUIT") 31 | if err != nil { 32 | fmt.Println("Error unsetting environment variable:", err) 33 | return 34 | } 35 | fmt.Println("Unset env var done on key FRUIT") 36 | 37 | fmt.Println("FRUIT env var:", os.Getenv("FRUIT")) 38 | fmt.Println("---------------------------------------------------") 39 | 40 | str := "a=b=c=d=e" 41 | // n = 1 returns "a=b=c=d" 42 | // n = 2 returns "a" and "b=c=d" 43 | // n = 3 returns "a" and "b" and "c=d" 44 | // n = 4 returns "a" and "b" and "c" and "d" 45 | fmt.Println(strings.SplitN(str, "=", -1)) 46 | fmt.Println(strings.SplitN(str, "=", 0)) 47 | fmt.Println(strings.SplitN(str, "=", 1)) 48 | fmt.Println(strings.SplitN(str, "=", 2)) 49 | fmt.Println(strings.SplitN(str, "=", 3)) 50 | fmt.Println(strings.SplitN(str, "=", 4)) 51 | fmt.Println(strings.SplitN(str, "=", 5)) 52 | 53 | } 54 | -------------------------------------------------------------------------------- /gocourse/intermediate/epoch.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | // 00:00:00 UTC on Jan 1, 1970 11 | 12 | now := time.Now() 13 | unixTime := now.Unix() 14 | fmt.Println("Current Unix Time:", unixTime) 15 | t := time.Unix(unixTime, 0) 16 | fmt.Println(t) 17 | fmt.Println("Time:", t.Format("2006-01-02")) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /gocourse/intermediate/errors.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func sqrt(x float64) (float64, error) { 9 | if x < 0 { 10 | return 0, errors.New("Math Error: square root of negative number") 11 | } 12 | // compute the square root 13 | return 1, nil 14 | } 15 | 16 | func process(data []byte) error { 17 | if len(data) == 0 { 18 | return errors.New("Empty data") 19 | } 20 | // Process data 21 | return nil 22 | } 23 | 24 | func main() { 25 | 26 | // result, err := sqrt(16) 27 | // if err != nil { 28 | // fmt.Println(err) 29 | // return 30 | // } 31 | // fmt.Println(result) 32 | 33 | // result1, err1 := sqrt(-16) 34 | // if err1 != nil { 35 | // fmt.Println(err1) 36 | // return 37 | // } 38 | // fmt.Println(result1) 39 | 40 | // data := []byte{} 41 | // // if err := process(data); err != nil { 42 | // err := process(data) 43 | // if err != nil { 44 | // fmt.Println("Error:", err) 45 | // return 46 | // } 47 | // fmt.Println("Data Processed Successfully") 48 | 49 | // --- error interface of builtin package 50 | // err1 := eprocess() 51 | // if err1 != nil { 52 | // fmt.Println(err1) 53 | // return 54 | // } 55 | // println("") 56 | 57 | err := readData() 58 | if err != nil { 59 | fmt.Println(err) 60 | return 61 | } 62 | fmt.Println("Data read successfully.") 63 | 64 | } 65 | 66 | type myError struct { 67 | message string 68 | } 69 | 70 | func (m *myError) Error() string { 71 | return fmt.Sprintf("Error: %s", m.message) 72 | } 73 | 74 | func eprocess() error { 75 | return &myError{"Custom error message"} 76 | } 77 | 78 | func readData() error { 79 | err := readConfig() 80 | if err != nil { 81 | return fmt.Errorf("readData: %w", err) 82 | } 83 | return nil 84 | } 85 | 86 | func readConfig() error { 87 | return errors.New("config error") 88 | } 89 | -------------------------------------------------------------------------------- /gocourse/intermediate/example.txt: -------------------------------------------------------------------------------- 1 | Some important info. 2 | 3 | Another important piece of data. 4 | This is going to be important. 5 | 6 | 7 | Please finish this, this is important. 8 | 9 | Go is an important language to learn in this era. 10 | 11 | Go is a valuable addition to programming. -------------------------------------------------------------------------------- /gocourse/intermediate/example_.txt: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /gocourse/intermediate/file_paths.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | "strings" 7 | ) 8 | 9 | func main() { 10 | 11 | relativePath := "./data/file.txt" 12 | absolutePath := "/home/user/docs/file.txt" 13 | 14 | // Join paths using filepath.join 15 | joinedPath := filepath.Join("home", "Documents", "downloads", "file.zip") 16 | fmt.Println("Joined Path:", joinedPath) 17 | 18 | normalizedPath := filepath.Clean("./data/../data/file.txt") 19 | fmt.Println("Normalized Path:", normalizedPath) 20 | 21 | dir, file := filepath.Split("/home/user/docs/file.txt") 22 | fmt.Println("File:", file) 23 | fmt.Println("Dir:", dir) 24 | fmt.Println(filepath.Base("/home/user/docs/")) 25 | 26 | fmt.Println("Is relativePath variable absolute:", filepath.IsAbs(relativePath)) 27 | fmt.Println("Is absolutePath variable absolute:", filepath.IsAbs(absolutePath)) 28 | 29 | fmt.Println(filepath.Ext(file)) 30 | fmt.Println(strings.TrimSuffix(file, filepath.Ext(file))) 31 | 32 | rel, err := filepath.Rel("a/b", "a/b/t/file") 33 | if err != nil { 34 | panic(err) 35 | } 36 | fmt.Println(rel) 37 | 38 | rel, err = filepath.Rel("a/c", "a/b/t/file") 39 | if err != nil { 40 | panic(err) 41 | } 42 | fmt.Println(rel) 43 | 44 | absPath, err := filepath.Abs(relativePath) 45 | if err != nil { 46 | fmt.Println("Error:", err) 47 | } else { 48 | fmt.Println("Absolute Path:", absPath) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gocourse/intermediate/fmt_package.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // Printing Functions 8 | // fmt.Print("Hello ") 9 | // fmt.Print("World!") 10 | // fmt.Print(12, 456) 11 | 12 | // fmt.Println("Hello ") 13 | // fmt.Println("World!") 14 | // fmt.Println(12, 456) 15 | 16 | // name := "John" 17 | // age := 25 18 | // fmt.Printf("Name: %s, Age: %d\n", name, age) 19 | // fmt.Printf("Binary: %b, Hex: %X\n", age, age) 20 | 21 | // Formatting Functions 22 | // s := fmt.Sprint("Hello", "World!", 123, 456) 23 | // fmt.Print(s) 24 | 25 | // s = fmt.Sprintln("Hello", "World!", 123, 456) 26 | // fmt.Print(s) 27 | // fmt.Print(s) 28 | 29 | // sf := fmt.Sprintf("Name: %s, Age %d", name, age) 30 | // fmt.Println(sf) 31 | // fmt.Println(sf) 32 | 33 | // Scanning Functions 34 | // var name string 35 | // var age int 36 | 37 | // fmt.Print("Enter your name and age:") 38 | // // fmt.Scan(&name, &age) 39 | // // fmt.Scanln(&name, &age) 40 | // fmt.Scanf("%s %d", &name, &age) 41 | // fmt.Printf("Name: %s, Age: %d\n", name, age) 42 | 43 | // Error Formatting Functions 44 | 45 | err := checkAge(19) 46 | if err != nil { 47 | fmt.Println("Error: ", err) 48 | } 49 | 50 | } 51 | 52 | func checkAge(age int) error { 53 | if age < 18 { 54 | return fmt.Errorf("Age %d is too young to drive.", age) 55 | } 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /gocourse/intermediate/generics.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | // func swap[T any](a, b T) (T, T) { 6 | // return b, a 7 | // } 8 | 9 | type Stack[T any] struct { 10 | elements []T 11 | } 12 | 13 | func (s *Stack[T]) push(element T) { 14 | s.elements = append(s.elements, element) 15 | } 16 | 17 | func (s *Stack[T]) pop() (T, bool) { 18 | if len(s.elements) == 0 { 19 | var zero T 20 | return zero, false 21 | } 22 | element := s.elements[len(s.elements)-1] 23 | s.elements = s.elements[:len(s.elements)-1] 24 | return element, true 25 | } 26 | 27 | func (s *Stack[T]) isEmpty() bool { 28 | return len(s.elements) == 0 29 | } 30 | 31 | func (s Stack[T]) printAll() { 32 | if len(s.elements) == 0 { 33 | fmt.Println("The stack is empty.") 34 | return 35 | } 36 | fmt.Print("Stack elements: ") 37 | for _, element := range s.elements { 38 | fmt.Print(element) 39 | } 40 | fmt.Println() 41 | } 42 | 43 | func main() { 44 | 45 | // x, y := 1, 2 46 | // x, y = swap(x, y) 47 | // fmt.Println(x, y) 48 | 49 | // x1, y1 := "John", "Jane" 50 | // x1, y1 = swap(x1, y1) 51 | // fmt.Println(x1, y1) 52 | 53 | intStack := Stack[int]{} 54 | intStack.push(1) 55 | intStack.push(2) 56 | intStack.push(3) 57 | intStack.printAll() 58 | fmt.Println(intStack.pop()) 59 | intStack.printAll() 60 | fmt.Println(intStack.pop()) 61 | fmt.Println("Is stack empty:", intStack.isEmpty()) 62 | fmt.Println(intStack.pop()) 63 | fmt.Println("Is stack empty:", intStack.isEmpty()) 64 | 65 | stringStack := Stack[string]{} 66 | stringStack.push("Hello") 67 | stringStack.push("World") 68 | stringStack.push("John") 69 | stringStack.printAll() 70 | fmt.Println(stringStack.pop()) 71 | fmt.Println("Is stringStack empty:", stringStack.isEmpty()) 72 | stringStack.printAll() 73 | fmt.Println(stringStack.pop()) 74 | fmt.Println(stringStack.pop()) 75 | fmt.Println("Is stringStack empty:", stringStack.isEmpty()) 76 | 77 | } 78 | -------------------------------------------------------------------------------- /gocourse/intermediate/go.mod: -------------------------------------------------------------------------------- 1 | module gocourse 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/sirupsen/logrus v1.9.3 // indirect 7 | go.uber.org/multierr v1.10.0 // indirect 8 | go.uber.org/zap v1.27.0 // indirect 9 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /gocourse/intermediate/interfaces.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type geometry interface { 9 | area() float64 10 | perim() float64 11 | } 12 | 13 | type circle struct { 14 | radius float64 15 | } 16 | 17 | func (c circle) area() float64 { 18 | return math.Pi * c.radius * c.radius 19 | } 20 | func (c circle) perim() float64 { 21 | return 2 * math.Pi * c.radius 22 | } 23 | func (c circle) diameter() float64 { 24 | return 2 * c.radius 25 | } 26 | 27 | type rect struct { 28 | width, height float64 29 | } 30 | 31 | func (r rect) area() float64 { 32 | return r.height * r.width 33 | } 34 | func (r rect) perim() float64 { 35 | return 2 * (r.height + r.width) 36 | } 37 | 38 | type rect1 struct { 39 | width, height float64 40 | } 41 | 42 | func (r rect1) area() float64 { 43 | return r.height * r.width 44 | } 45 | 46 | // func (r rect1) perim() float64 { 47 | // return 2 * (r.height + r.width) 48 | // } 49 | 50 | func measure(g geometry) { 51 | fmt.Println(g) 52 | fmt.Println(g.area()) 53 | fmt.Println(g.perim()) 54 | } 55 | 56 | func main() { 57 | 58 | r := rect{width: 3, height: 4} 59 | c := circle{radius: 5} 60 | // r1 := rect1{width: 3, height: 4} 61 | measure(r) 62 | measure(c) 63 | // measure(r1) 64 | 65 | myPrinter(1, "John", 45.9, true) 66 | 67 | printType(9) 68 | printType("John") 69 | printType(false) 70 | 71 | } 72 | 73 | func printType(i interface{}) { 74 | switch i.(type) { 75 | case int: 76 | fmt.Println("Type: Int") 77 | case string: 78 | fmt.Println("Type: String") 79 | default: 80 | fmt.Println("Type: Unknown") 81 | } 82 | } 83 | 84 | func myPrinter(i ...interface{}) { 85 | for _, v := range i { 86 | fmt.Println(v) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /gocourse/intermediate/io.txt: -------------------------------------------------------------------------------- 1 | Hello File!Hello File!Hello File! -------------------------------------------------------------------------------- /gocourse/intermediate/line_filter.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | 12 | file, err := os.Open("example.txt") 13 | if err != nil { 14 | fmt.Println("Error opening file:", err) 15 | return 16 | } 17 | 18 | defer file.Close() 19 | 20 | scanner := bufio.NewScanner(file) 21 | 22 | lineNumber := 1 23 | 24 | // Keyword to filter lines 25 | keyword := "important" 26 | 27 | // Read and filter lines 28 | for scanner.Scan() { 29 | line := scanner.Text() 30 | if strings.Contains(line, keyword) { 31 | updatedLine := strings.ReplaceAll(line, keyword, "necessary") 32 | fmt.Printf("%d Filtered line: %v\n", lineNumber, line) 33 | lineNumber++ 34 | fmt.Printf("%d Updated line: %v\n", lineNumber, updatedLine) 35 | lineNumber++ 36 | } 37 | } 38 | 39 | err = scanner.Err() 40 | if err != nil { 41 | fmt.Println("Error scanning file:", err) 42 | return 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /gocourse/intermediate/logging.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | 10 | log.Println("This is a log message.") 11 | 12 | log.SetPrefix("INFO: ") 13 | log.Println("This is an info message.") 14 | 15 | // Log Flags 16 | log.SetFlags(log.Ldate | log.Ltime | log.Llongfile) 17 | log.Println("This is a log message with date, time.") 18 | 19 | infoLogger.Println("This is an info message") 20 | warnLogger.Println("This is a warning message.") 21 | errorLogger.Println("This is an wrror message.") 22 | 23 | file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) 24 | if err != nil { 25 | log.Fatalf("Failed to open log file: %v", err) 26 | } 27 | defer file.Close() 28 | 29 | warnLogger1 := log.New(file, "WARN: ", log.Ldate|log.Ltime) 30 | infoLogger1 := log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) 31 | errorLogger1 := log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) 32 | 33 | debugLogger := log.New(file, "DEBUG: ", log.Ldate|log.Ltime|log.Lshortfile) 34 | 35 | debugLogger.Println("This is a debug message.") 36 | warnLogger1.Println("This is a warning message.") 37 | infoLogger1.Println("This is an info mesage.") 38 | errorLogger1.Println("This is an error.") 39 | } 40 | 41 | var ( 42 | infoLogger = log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) 43 | warnLogger = log.New(os.Stdout, "WARN: ", log.Ldate|log.Ltime) 44 | errorLogger = log.New(os.Stdout, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) 45 | ) 46 | -------------------------------------------------------------------------------- /gocourse/intermediate/logrus_logging.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "github.com/sirupsen/logrus" 4 | 5 | func main() { 6 | 7 | log := logrus.New() 8 | 9 | // Set log level 10 | log.SetLevel(logrus.InfoLevel) 11 | 12 | // Set log format 13 | log.SetFormatter(&logrus.JSONFormatter{}) 14 | 15 | // Logging examples 16 | log.Info("This is an info message.") 17 | log.Warn("This is a warning message.") 18 | log.Error("This is an error message.") 19 | 20 | log.WithFields(logrus.Fields{ 21 | "username": "John Doe", 22 | "method": "GET", 23 | }).Info("User logged in.") 24 | 25 | } 26 | -------------------------------------------------------------------------------- /gocourse/intermediate/methods.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | type Shape struct { 6 | Rectangle 7 | } 8 | 9 | type Rectangle struct { 10 | length float64 11 | width float64 12 | } 13 | 14 | // Method with value receiver 15 | func (r Rectangle) Area() float64 { 16 | return r.length * r.width 17 | } 18 | 19 | // Method with pointer receiver 20 | func (r *Rectangle) Scale(factor float64) { 21 | r.length *= factor // r.length = r.length * factor 22 | r.width *= factor 23 | } 24 | 25 | func main() { 26 | 27 | rect := Rectangle{length: 10, width: 9} 28 | area := rect.Area() 29 | fmt.Println("Area of rectangle with width 9 and length 10 is", area) 30 | rect.Scale(2) 31 | area = rect.Area() 32 | fmt.Println("Area of rectangle with a factor of 2 is", area) 33 | 34 | num := MyInt(-5) 35 | num1 := MyInt(9) 36 | fmt.Println(num.IsPositive()) 37 | fmt.Println(num1.IsPositive()) 38 | fmt.Println(num.welcomeMessage()) 39 | 40 | s := Shape{Rectangle: Rectangle{length: 10, width: 9}} 41 | fmt.Println(s.Area()) 42 | fmt.Println(s.Rectangle.Area()) 43 | } 44 | 45 | type MyInt int 46 | 47 | // Method on a user-defined type 48 | func (m MyInt) IsPositive() bool { 49 | return m > 0 50 | } 51 | 52 | func (MyInt) welcomeMessage() string { 53 | return "Welcome to MyInt Type" 54 | } 55 | -------------------------------------------------------------------------------- /gocourse/intermediate/number_parsing.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | 10 | numStr := "12345" 11 | num, err := strconv.Atoi(numStr) 12 | if err != nil { 13 | fmt.Println("Error parsing the value:", err) 14 | } 15 | fmt.Println("Parsed Integer:", num) 16 | fmt.Println("Parsed Integer:", num+1) 17 | 18 | numistr, err := strconv.ParseInt(numStr, 10, 32) 19 | if err != nil { 20 | fmt.Println("Error parsing the value:", err) 21 | } 22 | 23 | fmt.Println("Parsed Integer:", numistr) 24 | 25 | floatstr := "3.14" 26 | floatval, err := strconv.ParseFloat(floatstr, 64) 27 | if err != nil { 28 | fmt.Println("Error parsing value:", err) 29 | } 30 | fmt.Printf("Parsed float: %.2f\n", floatval) 31 | 32 | binaryStr := "1010" // 0 + 2 + 0 + 8 = 10 33 | decimal, err := strconv.ParseInt(binaryStr, 2, 64) 34 | if err != nil { 35 | fmt.Println("Error parsing binary value:", err) 36 | return 37 | } 38 | fmt.Println("Parsed binary to decimal:", decimal) 39 | 40 | hexStr := "FF" 41 | hex, err := strconv.ParseInt(hexStr, 16, 64) 42 | if err != nil { 43 | fmt.Println("Error parsing binary value:", err) 44 | return 45 | } 46 | fmt.Println("Parsed hex to decimal:", hex) 47 | 48 | invalidNum := "456abc" 49 | invalidParse, err := strconv.Atoi(invalidNum) 50 | if err != nil { 51 | fmt.Println("Error parsing value:", err) 52 | return 53 | } 54 | fmt.Println("Parsed invalid number:", invalidParse) 55 | } 56 | -------------------------------------------------------------------------------- /gocourse/intermediate/output.txt: -------------------------------------------------------------------------------- 1 | Hello World! 2 | 3 | 4 | Bye World! -------------------------------------------------------------------------------- /gocourse/intermediate/pointers.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var ptr *int 8 | var a int = 10 9 | ptr = &a // referencing 10 | 11 | fmt.Println(a) 12 | fmt.Println(ptr) 13 | // fmt.Println(*ptr) // dereferencing a pointer 14 | // if ptr == nil { 15 | // fmt.Println("Pointer is nil") 16 | // } 17 | 18 | modifyValue(ptr) 19 | fmt.Println(a) 20 | 21 | } 22 | 23 | func modifyValue(ptr *int) { 24 | *ptr++ 25 | } 26 | -------------------------------------------------------------------------------- /gocourse/intermediate/random_numbers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | ) 7 | 8 | func main() { 9 | 10 | // // val := rand.New(rand.NewSource(time.Now().Unix())) 11 | 12 | // fmt.Println(rand.Intn(6) + 5) 13 | // // fmt.Println(val.Intn(101)) 14 | // fmt.Println(rand.Float64()) // between 0.0 and 1.0 15 | 16 | for { 17 | // Show the menu 18 | fmt.Println("Welcome to the Dice Game!") 19 | fmt.Println("1. Roll the dice") 20 | fmt.Println("2. Exit") 21 | fmt.Print("Enter your choice (1 or 2): ") 22 | 23 | var choice int 24 | _, err := fmt.Scan(&choice) 25 | if err != nil || (choice != 1 && choice != 2) { 26 | fmt.Println("Invalid choice, please enter 1 or 2.") 27 | continue 28 | } 29 | if choice == 2 { 30 | fmt.Println("Thanks for playing! Goodbye.") 31 | break 32 | } 33 | 34 | die1 := rand.Intn(6) + 1 35 | die2 := rand.Intn(6) + 1 36 | 37 | // show the results 38 | fmt.Printf("You rolled a %d and a %d.\n", die1, die2) 39 | fmt.Println("Total:", die1+die2) 40 | 41 | // Ask of the user wants to roll again 42 | fmt.Println("Do you want to roll again? (y/n): ") 43 | var rollAgain string 44 | _, err = fmt.Scan(&rollAgain) 45 | if err != nil || (rollAgain != "y" && rollAgain != "n") { 46 | fmt.Println("Invalid input, assuming no.") 47 | break 48 | } 49 | if rollAgain == "n" { 50 | fmt.Println("Thanks for playing! Goodbye.") 51 | break 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gocourse/intermediate/reading_files.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | file, err := os.Open("output.txt") 12 | if err != nil { 13 | fmt.Println("Error opening file:", err) 14 | return 15 | } 16 | defer func() { 17 | fmt.Println("Closing open file") 18 | file.Close() 19 | }() 20 | 21 | fmt.Println("File opened successfully.") 22 | 23 | // // Read the contents of the opened file 24 | // data := make([]byte, 1024) // Buffer to read data into 25 | // _, err = file.Read(data) 26 | // if err != nil { 27 | // fmt.Println("Error reading data from file:", err) 28 | // return 29 | // } 30 | 31 | // fmt.Println("File content:", string(data)) 32 | 33 | scanner := bufio.NewScanner(file) 34 | 35 | // Read line by line 36 | for scanner.Scan() { 37 | line := scanner.Text() 38 | fmt.Println("Line:", line) 39 | } 40 | 41 | err = scanner.Err() 42 | if err != nil { 43 | fmt.Println("Error reading file:", err) 44 | return 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /gocourse/intermediate/recursion.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | fmt.Println(factorial(5)) 8 | fmt.Println(factorial(10)) 9 | 10 | fmt.Println(sumOfDigits(9)) 11 | fmt.Println(sumOfDigits(12)) 12 | fmt.Println(sumOfDigits(12345)) 13 | 14 | } 15 | 16 | func factorial(n int) int { 17 | // Base case: factorial of 0 is 1 18 | if n == 0 { 19 | return 1 20 | } 21 | // Recursive case: factorial of n is n * factorial(n - 1) 22 | return n * factorial(n-1) 23 | // n * (n - 1) * (n-2) * factorial (n-3)..... factorial(0) 24 | 25 | } 26 | 27 | func sumOfDigits(n int) int { 28 | // Base case 29 | if n < 10 { 30 | return n 31 | } 32 | return n%10 + sumOfDigits(n/10) 33 | } 34 | -------------------------------------------------------------------------------- /gocourse/intermediate/regular_expressions.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | ) 7 | 8 | func main() { 9 | 10 | fmt.Println("He said, \"I am great\"") 11 | fmt.Println(`He said, "I am great"`) 12 | 13 | // Compile a regex pattern to match email address 14 | re := regexp.MustCompile(`[a-zA-Z0-9._+%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}`) 15 | 16 | // Test strings 17 | email1 := "user@email.com" 18 | email2 := "invalid_email" 19 | 20 | // Match 21 | fmt.Println("Email1:", re.MatchString(email1)) 22 | fmt.Println("Email2:", re.MatchString(email2)) 23 | 24 | // Capturing Groups 25 | // Compile a regex pattern to capture date components 26 | re = regexp.MustCompile(`(\d){4}-(\d{2})-(\d{2})`) 27 | 28 | // Test string 29 | date := "2024-07-30" 30 | 31 | // Find all submatches 32 | submatches := re.FindStringSubmatch(date) 33 | fmt.Println(submatches) 34 | fmt.Println(submatches[0]) 35 | fmt.Println(submatches[1]) 36 | fmt.Println(submatches[2]) 37 | fmt.Println(submatches[3]) 38 | 39 | // Source string 40 | str := "Hello World" 41 | 42 | re = regexp.MustCompile(`[aeiou]`) 43 | 44 | result := re.ReplaceAllString(str, "*") 45 | fmt.Println(result) 46 | 47 | // i - case insensitive 48 | // m - multi line model 49 | // s - dot matches all 50 | 51 | re = regexp.MustCompile(`(?i)go`) 52 | // re = regexp.MustCompile(`go`) 53 | 54 | // Test string 55 | text := "Golang is great" 56 | 57 | // Match 58 | fmt.Println("Match:", re.MatchString(text)) 59 | } 60 | -------------------------------------------------------------------------------- /gocourse/intermediate/string_formatting.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | num := 424 8 | fmt.Printf("%05d\n", num) 9 | 10 | message := "Hello" 11 | fmt.Printf("|%10s|\n", message) 12 | fmt.Printf("|%-10s|\n", message) 13 | 14 | message1 := "Hello \nWorld!" 15 | message2 := `Hello \nWorld!` 16 | 17 | fmt.Println(message1) 18 | fmt.Println(message2) 19 | 20 | // sqlQuery := `SELECT * FROM users WHERE age > 30` 21 | 22 | } 23 | -------------------------------------------------------------------------------- /gocourse/intermediate/strings_runes.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "unicode/utf8" 6 | ) 7 | 8 | func main() { 9 | 10 | message := "Hello, \nGo!" 11 | message1 := "Hello, \tGo!" 12 | message2 := "Hello, Go!" // Go!lo 13 | rawMessage := `Hello\nGo` 14 | 15 | fmt.Println(message) 16 | fmt.Println(message1) 17 | fmt.Println(message2) 18 | fmt.Println(rawMessage) 19 | 20 | fmt.Println("Length of rawmessage variable is", len(rawMessage)) 21 | 22 | fmt.Println("The first character in message var is", message[0]) // ASCII 23 | 24 | greeting := "Hello " 25 | name := "Alice" 26 | fmt.Println(greeting + name) 27 | 28 | str1 := "Apple" // A has an ASCII value of 65 29 | str := "apple" // a has an ASCII value of 97 30 | str2 := "banana" // b has an ASCII value of 98 31 | str3 := "app" // a has an ASCII value of 97 32 | fmt.Println(str1 < str2) 33 | fmt.Println(str3 < str1) 34 | fmt.Println(str > str1) 35 | fmt.Println(str > str3) 36 | 37 | for _, char := range message { 38 | // fmt.Printf("Character at index %d is %c\n", i, char) 39 | fmt.Printf("%v\n", char) 40 | } 41 | 42 | fmt.Println("Rune count:", utf8.RuneCountInString(greeting)) 43 | 44 | greetingWithName := greeting + name 45 | fmt.Println(greetingWithName) 46 | 47 | var ch rune = 'a' 48 | jch := '日' 49 | 50 | fmt.Println(ch) 51 | fmt.Println(jch) 52 | 53 | fmt.Printf("%c\n", ch) 54 | fmt.Printf("%c\n", jch) 55 | 56 | cstr := string(ch) 57 | fmt.Println(cstr) 58 | 59 | fmt.Printf("Type of cstr is %T\n", cstr) 60 | 61 | const NIHONGO = "日本語" // Japanese text 62 | fmt.Println(NIHONGO) 63 | 64 | jhello := "こんにちは" // Japanese "Hello" 65 | for _, runeValue := range jhello { 66 | fmt.Printf("%c\n", runeValue) 67 | } 68 | 69 | r := '😊' 70 | fmt.Printf("%v\n", r) 71 | fmt.Printf("%c\n", r) 72 | } 73 | -------------------------------------------------------------------------------- /gocourse/intermediate/struct_embedding.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | type person struct { 6 | name string 7 | age int 8 | } 9 | 10 | type Employee struct { 11 | employeeInfo person // Embedded struct Named field 12 | // person // Anonymous field 13 | empId string 14 | salary float64 15 | } 16 | 17 | func (p person) introduce() { 18 | fmt.Printf("Hi, I'm %s and I'm %d years old.\n", p.name, p.age) 19 | } 20 | 21 | func (e Employee) introduce() { 22 | fmt.Printf("Hi, I'm %s, employee ID: %s, and I earn %.2f.\n", e.employeeInfo.name, e.empId, e.salary) 23 | } 24 | 25 | func main() { 26 | 27 | emp := Employee{ 28 | employeeInfo: person{name: "John", age: 30}, 29 | empId: "E001", salary: 50000, 30 | } 31 | 32 | fmt.Println("Name:", emp.employeeInfo.name) // Accessing the embedded struct field emp.person.name 33 | fmt.Println("Age:", emp.employeeInfo.age) // Same as above 34 | fmt.Println("Emp ID:", emp.empId) 35 | fmt.Println("Salary:", emp.salary) 36 | 37 | emp.introduce() 38 | 39 | } 40 | -------------------------------------------------------------------------------- /gocourse/intermediate/struct_tags.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | ) 8 | 9 | type Person struct { 10 | FirstName string `json:"first_name" db:"firstn" xml:"first"` 11 | LastName string `json:"last_name,omitempty"` 12 | Age int `json:"-"` 13 | } 14 | 15 | func main() { 16 | 17 | // person := Person{FirstName: "Jane", LastName: "", Age: 0} 18 | person := Person{FirstName: "Jane", Age: 30} 19 | 20 | jsonData, err := json.Marshal(person) 21 | if err != nil { 22 | log.Fatalln("Error marshalling struct:", err) 23 | } 24 | 25 | fmt.Println(string(jsonData)) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /gocourse/intermediate/structs.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | firstName string 7 | lastName string 8 | age int 9 | address Address 10 | PhoneHomeCell 11 | } 12 | 13 | type PhoneHomeCell struct { 14 | home string 15 | cell string 16 | } 17 | 18 | type Address struct { 19 | city string 20 | country string 21 | } 22 | 23 | func (p Person) fullName() string { 24 | return p.firstName + " " + p.lastName 25 | } 26 | 27 | func (p *Person) incrementAgeByOne() { 28 | p.age++ 29 | } 30 | 31 | func main() { 32 | 33 | p1 := Person{ 34 | firstName: "John", 35 | lastName: "Doe", 36 | age: 30, 37 | address: Address{ 38 | city: "London", 39 | country: "U.K.", 40 | }, 41 | PhoneHomeCell: PhoneHomeCell{ 42 | home: "465456454", 43 | cell: "45456464544", 44 | }, 45 | } 46 | 47 | p2 := Person{ 48 | firstName: "Jane", 49 | age: 25, 50 | } 51 | 52 | p3 := Person{ 53 | firstName: "Jane", 54 | age: 25, 55 | } 56 | // p2.address.city = "New York" 57 | // p2.address.country = "USA" 58 | 59 | fmt.Println(p1.firstName) 60 | fmt.Println(p2.firstName) 61 | fmt.Println(p1.fullName()) 62 | fmt.Println(p1.address) 63 | fmt.Println(p2.address.country) 64 | fmt.Println(p1.cell) 65 | fmt.Println(p1.address.city) 66 | fmt.Println("Are p3 and p2 equal:", p3 == p2) 67 | 68 | // Anonymous Structs 69 | user := struct { 70 | username string 71 | email string 72 | }{ 73 | username: "user123", 74 | email: "pseudoemail@example.org", 75 | } 76 | 77 | fmt.Println(user.username) 78 | fmt.Println("Before increment", p1.age) 79 | p1.incrementAgeByOne() 80 | fmt.Println("After increment", p1.age) 81 | 82 | } 83 | -------------------------------------------------------------------------------- /gocourse/intermediate/temp_files_dirs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func checkError(err error) { 9 | if err != nil { 10 | panic(err) 11 | } 12 | } 13 | 14 | func main() { 15 | 16 | // tempFileName := "temporaryFile" 17 | 18 | // tempFile, err := os.CreateTemp("", tempFileName) 19 | // checkError(err) 20 | 21 | // fmt.Println("Temporary file created:", tempFile.Name()) 22 | 23 | // defer os.Remove(tempFile.Name()) 24 | // defer tempFile.Close() 25 | 26 | tempDir, err := os.MkdirTemp("", "GoCourseTempDir") 27 | checkError(err) 28 | 29 | defer os.RemoveAll(tempDir) 30 | 31 | fmt.Println("Temporary directory created:", tempDir) 32 | } 33 | -------------------------------------------------------------------------------- /gocourse/intermediate/time_formatting.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | // Mon Jan 2 15:04:05 MST 2006 11 | 12 | layout := "2006-01-02T15:04:05Z07:00" 13 | str := "2024-07-04T14:30:18Z" 14 | 15 | t, err := time.Parse(layout, str) 16 | if err != nil { 17 | fmt.Println("Error parsing time:", err) 18 | return 19 | } 20 | fmt.Println(t) 21 | 22 | str1 := "Jul 03, 2024 03:18 PM" 23 | layout1 := "Jan 02, 2006 03:04 PM" 24 | 25 | t1, err := time.Parse(layout1, str1) 26 | fmt.Println(t1) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /gocourse/intermediate/type_conversion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var a int = 32 8 | b := int32(a) 9 | c := float64(b) 10 | // d := bool("correct") 11 | 12 | e := 3.14 13 | f := int(e) 14 | fmt.Println(f, c) 15 | 16 | // Type(value) 17 | 18 | g := "Hello @ こんにちは 🧑 привет" 19 | var h []byte 20 | h = []byte(g) 21 | fmt.Println(h) 22 | i := []byte{255, 120, 72} 23 | j := string(i) 24 | fmt.Println(j) 25 | } 26 | -------------------------------------------------------------------------------- /gocourse/intermediate/url_parsing.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | ) 7 | 8 | func main() { 9 | 10 | // [scheme://][userinfo@]host[:port][/path][?query][#fragment] 11 | 12 | rawURL := "https://example.com:8080/path?query=param#fragment" 13 | 14 | parsedURL, err := url.Parse(rawURL) 15 | if err != nil { 16 | fmt.Println("Error parsing URL:", err) 17 | return 18 | } 19 | 20 | fmt.Println("Scheme:", parsedURL.Scheme) 21 | fmt.Println("Host:", parsedURL.Host) 22 | fmt.Println("Port:", parsedURL.Port()) 23 | fmt.Println("Path:", parsedURL.Path) 24 | fmt.Println("Raw Query:", parsedURL.RawQuery) 25 | fmt.Println("Fragment:", parsedURL.Fragment) 26 | // fmt.Println("Scheme:", parsedURL.Scheme) 27 | 28 | rawURL1 := "https://example.com/path?name=John&age=30" 29 | 30 | parseURL1, err := url.Parse(rawURL1) 31 | if err != nil { 32 | fmt.Println("Error parsing URL:", err) 33 | return 34 | } 35 | 36 | queryParams := parseURL1.Query() 37 | fmt.Println(queryParams) 38 | fmt.Println("Name:", queryParams.Get("name")) 39 | fmt.Println("Age:", queryParams.Get("age")) 40 | 41 | // Building URL 42 | baseURL := &url.URL{ 43 | Scheme: "https", 44 | Host: "example.com", 45 | Path: "/path", 46 | } 47 | 48 | query := baseURL.Query() 49 | query.Set("name", "John") 50 | query.Set("age", "30") 51 | baseURL.RawQuery = query.Encode() 52 | 53 | fmt.Println("Built URL:", baseURL.String()) 54 | 55 | values := url.Values{} 56 | 57 | // Add key-value pairs to the values object 58 | values.Add("name", "Jane") 59 | values.Add("age", "30") 60 | values.Add("city", "London") 61 | values.Add("country", "UK") 62 | 63 | // Encode 64 | encodedQuery := values.Encode() 65 | 66 | fmt.Println(encodedQuery) 67 | 68 | // Build a URL 69 | baseURL1 := "https://example.com/search" 70 | fullURL := baseURL1 + "?" + encodedQuery 71 | 72 | fmt.Println(fullURL) 73 | } 74 | -------------------------------------------------------------------------------- /gocourse/intermediate/writeString.txt: -------------------------------------------------------------------------------- 1 | Hello Go! 2 | 3 | 4 | -------------------------------------------------------------------------------- /gocourse/intermediate/writing_files.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | 10 | file, err := os.Create("output.txt") 11 | if err != nil { 12 | fmt.Println("Error creating file.", file) 13 | return 14 | } 15 | defer file.Close() 16 | 17 | // write data to file 18 | data := []byte("Hello World!\n\n\n") 19 | _, err = file.Write(data) 20 | if err != nil { 21 | fmt.Println("Error writing to file:", err) 22 | return 23 | } 24 | 25 | fmt.Println("Data has been written to file successfully.") 26 | 27 | file, err = os.Create("writeString.txt") 28 | if err != nil { 29 | fmt.Println("Error creating file:", err) 30 | return 31 | } 32 | defer file.Close() 33 | 34 | _, err = file.WriteString("Hello Go!\n\n\n") 35 | if err != nil { 36 | fmt.Println("Error writing to file:", err) 37 | return 38 | } 39 | 40 | fmt.Println("Writing to writeString.txt complete.") 41 | 42 | } 43 | -------------------------------------------------------------------------------- /gocourse/intermediate/zap_log.go: -------------------------------------------------------------------------------- 1 | package intermediate 2 | 3 | import ( 4 | "log" 5 | 6 | "go.uber.org/zap" 7 | ) 8 | 9 | func main() { 10 | 11 | logger, err := zap.NewProduction() 12 | if err != nil { 13 | log.Println("Error in intializing Zap logger") 14 | } 15 | 16 | defer logger.Sync() 17 | 18 | logger.Info("This is an info message.") 19 | 20 | logger.Info("User logged in", zap.String("username", "John Doe"), zap.String("method", "GET")) 21 | } 22 | -------------------------------------------------------------------------------- /gocourse/mac/cvp.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | // func printNumbers() { 11 | // for i := range 5 { 12 | // fmt.Println(time.Now()) 13 | // fmt.Println(i) 14 | // time.Sleep(500 * time.Millisecond) 15 | // } 16 | // } 17 | 18 | // func printLetters() { 19 | // for _, letter := range "ABCDE" { 20 | // fmt.Println(time.Now()) 21 | // fmt.Println(string(letter)) 22 | // time.Sleep(500 * time.Millisecond) 23 | // } 24 | // } 25 | 26 | func heavyTask(id int, wg *sync.WaitGroup) { 27 | defer wg.Done() 28 | fmt.Printf("Task %d is starting\n", id) 29 | for range 100_000_000 { 30 | } 31 | fmt.Println(time.Now()) 32 | fmt.Printf("Task %d is finished.\n", id) 33 | } 34 | 35 | func main() { 36 | 37 | // go printNumbers() 38 | // go printLetters() 39 | // time.Sleep(3 * time.Second) 40 | numThreads := 12 41 | 42 | runtime.GOMAXPROCS(numThreads) 43 | var wg sync.WaitGroup 44 | 45 | for i := range numThreads { 46 | wg.Add(1) 47 | go heavyTask(i, &wg) 48 | } 49 | 50 | wg.Wait() 51 | } 52 | -------------------------------------------------------------------------------- /gocourse/mac/deadlocks.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | 11 | var mu1, mu2 sync.Mutex 12 | 13 | go func() { 14 | mu1.Lock() 15 | fmt.Println("Goroutine 1 locked mu1") 16 | time.Sleep(time.Second) 17 | mu2.Lock() 18 | fmt.Println("Goroutine 1 locked mu2") 19 | mu1.Unlock() 20 | mu2.Unlock() 21 | fmt.Println("Goroutine1 finished") 22 | }() 23 | 24 | go func() { 25 | mu1.Lock() 26 | fmt.Println("Goroutine 2 locked mu2") 27 | time.Sleep(time.Second) 28 | mu2.Lock() 29 | fmt.Println("Goroutine 2 locked mu1") 30 | mu2.Unlock() 31 | mu1.Unlock() 32 | fmt.Println("Goroutine2 finished") 33 | }() 34 | 35 | time.Sleep(3 * time.Second) 36 | fmt.Println("Main function completed") 37 | // select {} 38 | } 39 | -------------------------------------------------------------------------------- /gocourse/mac/for_select.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | 10 | ticker := time.NewTicker(1 * time.Second) 11 | quit := make(chan string) 12 | 13 | go func() { 14 | time.Sleep(5 * time.Second) 15 | close(quit) 16 | }() 17 | 18 | for { 19 | select { 20 | case <-ticker.C: 21 | fmt.Println("Tick") 22 | case <-quit: 23 | fmt.Println("Quitting...") 24 | return 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gocourse/mac/race_conditions.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // go run -race 9 | 10 | type counter struct { 11 | mu sync.Mutex 12 | count int 13 | } 14 | 15 | func (c *counter) increment() { 16 | c.mu.Lock() 17 | defer c.mu.Unlock() 18 | c.count++ 19 | } 20 | 21 | func (c *counter) getValue() int { 22 | c.mu.Lock() 23 | defer c.mu.Unlock() 24 | return c.count 25 | } 26 | 27 | func main() { 28 | 29 | var wg sync.WaitGroup 30 | counter := &counter{} 31 | numGoroutines := 10 32 | 33 | // wg.Add(numGoroutines) 34 | for range numGoroutines { 35 | wg.Add(1) 36 | go func() { 37 | defer wg.Done() 38 | for range 1000 { 39 | counter.increment() 40 | // counter.count++ 41 | } 42 | }() 43 | } 44 | 45 | wg.Wait() 46 | fmt.Printf("Final counter value: %d\n", counter.getValue()) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /gocourse/mac/rw_mutex.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | var ( 10 | rwmu sync.RWMutex 11 | counter int 12 | ) 13 | 14 | func readCounter(wg *sync.WaitGroup) { 15 | defer wg.Done() 16 | rwmu.RLock() 17 | fmt.Println("Read Counter:", counter) 18 | rwmu.RUnlock() 19 | } 20 | 21 | func writeCounter(wg *sync.WaitGroup, value int) { 22 | defer wg.Done() 23 | rwmu.Lock() 24 | counter = value 25 | fmt.Printf("Written value %d for counter.\n", value) 26 | rwmu.Unlock() 27 | } 28 | 29 | func main() { 30 | var wg sync.WaitGroup 31 | for range 5 { 32 | wg.Add(1) 33 | go readCounter(&wg) 34 | } 35 | 36 | wg.Add(1) 37 | time.Sleep(time.Second) 38 | go writeCounter(&wg, 18) 39 | 40 | wg.Wait() 41 | } 42 | -------------------------------------------------------------------------------- /gocourse/mac/sync_new_cond.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | const bufferSize = 5 10 | 11 | type buffer struct { 12 | items []int 13 | mu sync.Mutex 14 | cond *sync.Cond 15 | } 16 | 17 | func newBuffer(size int) *buffer { 18 | b := &buffer{ 19 | items: make([]int, 0, size), 20 | } 21 | b.cond = sync.NewCond(&b.mu) 22 | return b 23 | } 24 | 25 | func (b *buffer) produce(item int) { 26 | b.mu.Lock() 27 | defer b.mu.Unlock() 28 | 29 | for len(b.items) == bufferSize { 30 | b.cond.Wait() 31 | } 32 | 33 | b.items = append(b.items, item) 34 | fmt.Println("Produced:", item) 35 | b.cond.Signal() 36 | } 37 | 38 | func (b *buffer) consume() int { 39 | b.mu.Lock() 40 | defer b.mu.Unlock() 41 | for len(b.items) == 0 { 42 | b.cond.Wait() 43 | // This function stops doing anything and waits for other function to append to the slice 44 | } 45 | item := b.items[0] 46 | b.items = b.items[1:] 47 | fmt.Println("Consumed:", item) 48 | b.cond.Signal() 49 | return item 50 | } 51 | 52 | func producer(b *buffer, wg *sync.WaitGroup) { 53 | defer wg.Done() 54 | for i := range 20 { 55 | b.produce(i + 100) 56 | time.Sleep(100 * time.Millisecond) 57 | } 58 | } 59 | 60 | func consumer(b *buffer, wg *sync.WaitGroup) { 61 | defer wg.Done() 62 | for range 20 { 63 | b.consume() 64 | time.Sleep(200 * time.Millisecond) 65 | } 66 | } 67 | 68 | func main() { 69 | buffer := newBuffer(bufferSize) 70 | var wg sync.WaitGroup 71 | 72 | wg.Add(2) 73 | go producer(buffer, &wg) 74 | go consumer(buffer, &wg) 75 | 76 | wg.Wait() 77 | } 78 | -------------------------------------------------------------------------------- /gocourse/mac/sync_once.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var once sync.Once 9 | 10 | func initialize() { 11 | fmt.Println("This will not be repeated no matter how mahy times you call this function using once.Do.") 12 | } 13 | 14 | func main() { 15 | 16 | var wg sync.WaitGroup 17 | for i := range 5 { 18 | wg.Add(1) 19 | go func() { 20 | defer wg.Done() 21 | fmt.Println("Goroutine # ", i) 22 | once.Do(initialize) 23 | // initialize() 24 | }() 25 | } 26 | wg.Wait() 27 | } 28 | -------------------------------------------------------------------------------- /gocourse/mac/sync_pool.go: -------------------------------------------------------------------------------- 1 | package mac 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | type person struct { 9 | name string 10 | age int 11 | } 12 | 13 | func main() { 14 | var pool = sync.Pool{ 15 | // New: func() interface{} { 16 | // fmt.Println("Creating a new Person.") 17 | // return &person{} 18 | // }, 19 | } 20 | pool.Put(&person{name: "John", age: 81}) 21 | 22 | // Get an object from the pool 23 | person1 := pool.Get().(*person) 24 | // person1.name = "John" 25 | // person1.age = 18 26 | // fmt.Println("Got Person:", person1) 27 | 28 | fmt.Printf("Person1 - Name: %s, Age: %d\n", person1.name, person1.age) 29 | 30 | pool.Put(person1) 31 | fmt.Println("Returned Person to pool") 32 | 33 | person2 := pool.Get().(*person) 34 | fmt.Println("Got person2:", person2) 35 | 36 | // person3 := pool.Get().(*person) 37 | person3 := pool.Get() 38 | if person3 != nil { 39 | fmt.Println("Got person3:", person3) 40 | person3.(*person).name = "Jane" 41 | pool.Put(person3) 42 | } else { 43 | fmt.Println("Sync Pool is empty") 44 | } 45 | 46 | // Returning object to the pool again 47 | pool.Put(person2) 48 | fmt.Println("Returned Persons to pool") 49 | 50 | person4 := pool.Get().(*person) 51 | fmt.Println("Got person4: ", person4) 52 | 53 | person5 := pool.Get().(*person) 54 | fmt.Println("Got person5:", person5) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/RUST/rust_api/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/RUST/rust_api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_api" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | # actix dependencies 8 | actix-web = "4.0" 9 | serde = { version = "1.0", features = ["derive"] } 10 | serde_json = "1.0" 11 | # rocket dedpendencies 12 | #serde = { version = "1.0", features = ["derive"] } 13 | #rocket = { version = "0.5", features = ["json"] } 14 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/RUST/wrk_benchmarking.lua: -------------------------------------------------------------------------------- 1 | wrk.method = "POST" 2 | wrk.body = '{"name": "JohnDoe"}' 3 | wrk.headers["Content-Type"] = "application/json" -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/benchmark_ghz.json: -------------------------------------------------------------------------------- 1 | { 2 | "proto": "/home/codeovation/cert/grpc_cert/main.proto", 3 | "call": "mainapi.Greeter.Greet", 4 | "concurrency": 100, 5 | "data": { "name": "JohnDoe" }, 6 | "max-duration": "20s", 7 | "host": "localhost:50051", 8 | "cert": "/home/codeovation/cert/grpc_cert/cert.pem", 9 | "key": "/home/codeovation/cert/grpc_cert/key.pem", 10 | "cacert": "/home/codeovation/cert/grpc_cert/cert.pem", 11 | "root-cert": "/home/codeovation/cert/grpc_cert/cert.pem" 12 | } -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDezCCAmOgAwIBAgIUe0huEu/GoUBpOPQtFKYO+lyjtzMwDQYJKoZIhvcNAQEL 3 | BQAwWzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 4 | DVNhbiBGcmFuY2lzY28xCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3Qw 5 | HhcNMjQwODA0MDkyMDE3WhcNMjUwODA0MDkyMDE3WjBbMQswCQYDVQQGEwJVUzET 6 | MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkG 7 | A1UECwwCSVQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD 8 | ggEPADCCAQoCggEBALh1/PFnVQjQOmKjAox74WVT+6nDlWerwK4873drpeHx4FKm 9 | r722zFbuczyu170tcqQeImmIcSCWDXFJ8TQ0dnxSplmg8ydBlCurudW0bGSxi2ao 10 | Rf5QvdyP0y4R3N05IbSAL4Ys43jgHHVNaC8+Sxj59g8yMSuCJKVhKYFcMgG3VDI6 11 | yz8QCy7ejuD5Zv8z/CuF5iD8iUXkjti7ENw6rfPTGSg9GWEctsaGc+y57uSTzPnl 12 | kXx9MK2/Fqjb5qOgcgwGXzwhPQLqTwVbA1QMQngFMnLbAUNq1LuapxyfEP9e4Bgq 13 | y5wFZCkvOnVpXP0ahqMCEAWYnkmskYlCcNnuGikCAwEAAaM3MDUwFAYDVR0RBA0w 14 | C4IJbG9jYWxob3N0MB0GA1UdDgQWBBR6YnDWlIDv5l6okjcrJc38DNTFVTANBgkq 15 | hkiG9w0BAQsFAAOCAQEAinjfEnSudmlGwd9kZc+Sb0lDox9Go73Ym5i5XpVok1mw 16 | 1AnZW+fQTncjatYzR0ZcuP9l655vFpVZfeLOJevXOw28ez5jVHabRxqBNE/jsjTP 17 | wFqtExnGhrJZjObMfHWlOBiHr1OncUwJ3hvubsQmEjdDIlZGCp1VuzF0GlmCFf0V 18 | J3ZELOW5vtzBCBlU5IRomWWn8AwQPcLSCzSXiRx4vCI9oWICsILDeZ5EULwujwqz 19 | Ht2/YRx5bkgTx0fxw7KXkU+l5wCmNRt5ultsCj1EbgpfpkKybgkVk9qElngGO09a 20 | NS/23fXgeoJuU+ObNJTQD7HWllRKz2BPvpCw2g4Yqg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/go.mod: -------------------------------------------------------------------------------- 1 | module grpcgatewayproject 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect 7 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 // indirect 8 | github.com/iancoleman/strcase v0.3.0 // indirect 9 | github.com/lyft/protoc-gen-star/v2 v2.0.3 // indirect 10 | github.com/spf13/afero v1.10.0 // indirect 11 | golang.org/x/mod v0.17.0 // indirect 12 | golang.org/x/net v0.26.0 // indirect 13 | golang.org/x/sys v0.21.0 // indirect 14 | golang.org/x/text v0.16.0 // indirect 15 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 16 | google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a // indirect 17 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a // indirect 18 | google.golang.org/grpc v1.65.0 // indirect 19 | google.golang.org/protobuf v1.34.2 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4dfzxZ1UI0Dpi 3 | owKMe+FlU/upw5Vnq8CuPO93a6Xh8eBSpq+9tsxW7nM8rte9LXKkHiJpiHEglg1x 4 | SfE0NHZ8UqZZoPMnQZQrq7nVtGxksYtmqEX+UL3cj9MuEdzdOSG0gC+GLON44Bx1 5 | TWgvPksY+fYPMjErgiSlYSmBXDIBt1QyOss/EAsu3o7g+Wb/M/wrheYg/IlF5I7Y 6 | uxDcOq3z0xkoPRlhHLbGhnPsue7kk8z55ZF8fTCtvxao2+ajoHIMBl88IT0C6k8F 7 | WwNUDEJ4BTJy2wFDatS7mqccnxD/XuAYKsucBWQpLzp1aVz9GoajAhAFmJ5JrJGJ 8 | QnDZ7hopAgMBAAECggEACd1AEjtvurGX+F+16oP9a7PFXjC4CVE6qUFXn6VBZlx5 9 | ndyNbVxx1PxEwVaq8XzqsogXWFlpjfqNls9YzMKOy4XdS3xl7xAnYlEj9kpYZDzH 10 | svewtobkKwADT7q40EPBNQEzNBOryR0C/erjyr2kD8kzirXTwfs1sSUJroHwUqhp 11 | 02ByvlaRM3wLEjdflVWf572Ku6SFSYUp5YW8R8Mqd+qR9s6TLkcezO/F/j+oMZ/A 12 | yBlVD44fHSFA5y6mJZany+KNatPsH/2hOaYgMNfVvozF0Vb/Vy6hION4zr+sN56G 13 | UL5N7wzDGuYZy4LoD2yMDkvW/KVo1soNbPwcDp6kmQKBgQDqWl+JdvscBj9n3tqD 14 | ZFROXW6qzGI3FyS2tLG/hxy8iWLilUhGZSFS26U5w1SF34OQWhbA7wBKz25fAeDF 15 | 5hZUZchqy14gJq/lTFjmFIECqfaWoxGA8X4UY3HafNe97df9KXPhtHbmfAGa5aw7 16 | aOj+jGkdp1WRu6soWOqZUjzqwwKBgQDJf9dNwJWHI15xNBmYguATSYd+DmM5u9cd 17 | iFSRpjBuV4RI+nJdqOIJrYdDwN6JNllArUnidQEcK+lU0HRur9iDoUxSnfPWZu9h 18 | J/BNiJZoGQ+zqjscPA/jS5mzevow4t6kp2B5zXPwk9D/6ZUJQURRY39ibuMnUtKA 19 | ACrFEb7gowKBgARx4FwAGLUoXS2AKY7SaVLvLLkqlTZMRxL8DF8AlgfxZyG7CRrk 20 | siQbLGATF1hOq/Uh8EqKfevtUT+WDohSW9wP7iQwZUGg2jc0In+CpgvB435p61wR 21 | uH10gWVOdt0QVMdlcOA4BwVKFtG0R3b8/2ZMjXXVhab080MZpKFx0Nv3AoGBALMD 22 | B1VFJdKEIpAxuBedFdMsvNnJkG+nKIpNJsyqt1YgHB71mQsKUZ5FculHfKysAwkJ 23 | qp0sU4sim83Ez9vSD2mJsBOpzgoJMtu+rqdDFFRxB1kXgCIqXfcRoAAq3gD2XNQs 24 | +vHbDAiMWd4xNz2cpUQlP/NEDjxOQUKEY3rmtAw/AoGARyRcQ8gbpzmhHNeckZgq 25 | VVL528fa+2AuAJegwRfDjEVOn44ZQZtrV24uoVBYwl/3dEvBbIWihJeh8iEH/L/W 26 | iwDdqo37FESdJVZNtI1TPS1NgZU5zLYhXV1clLNb8/YIC3DVlf4mKgeJuPah6kT7 27 | j/innmRIfQhFYdASUHQqr3U= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/proto/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package mainapi; 4 | 5 | option go_package = "/proto;mainapipb"; 6 | 7 | import "validate/validate.proto"; 8 | import "google/api/annotations.proto"; 9 | 10 | service Greeter { 11 | rpc Greet (HelloRequest) returns (HelloResponse) { 12 | option (google.api.http) = { 13 | post: "/v1/greet" 14 | body: "*" 15 | }; 16 | } 17 | } 18 | 19 | message HelloRequest { 20 | //string name = 1; 21 | string name = 1 [(validate.rules).string = {min_len: 5, max_len: 50}, (validate.rules).string.pattern = "[a-zA-Z]+"]; // Add validation rules 22 | } 23 | 24 | message HelloResponse { 25 | string message = 1; 26 | } -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway with TLS/wrk_benchmarking.lua: -------------------------------------------------------------------------------- 1 | wrk.method = "POST" 2 | wrk.body = '{"name":"JohnDoe"}' 3 | wrk.headers["Content-Type"] = "application/json" 4 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway/go.mod: -------------------------------------------------------------------------------- 1 | module grpcgatewayproject 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v1.0.4 7 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 8 | google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a 9 | google.golang.org/grpc v1.65.0 10 | google.golang.org/protobuf v1.34.2 11 | ) 12 | 13 | require ( 14 | golang.org/x/net v0.26.0 // indirect 15 | golang.org/x/sys v0.21.0 // indirect 16 | golang.org/x/text v0.16.0 // indirect 17 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway/proto/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package mainapi; 4 | 5 | option go_package = "/proto;mainapipb"; 6 | 7 | import "validate/validate.proto"; 8 | import "google/api/annotations.proto"; 9 | 10 | service Greeter { 11 | rpc Greet (HelloRequest) returns (HelloResponse) { 12 | option (google.api.http) = { 13 | post: "/v1/greet" 14 | body: "*" 15 | }; 16 | } 17 | } 18 | 19 | message HelloRequest { 20 | //string name = 1; 21 | string name = 1 [(validate.rules).string = {min_len: 5, max_len: 50}, (validate.rules).string.pattern = "[a-zA-Z]+"]; // Add validation rules 22 | } 23 | 24 | message HelloResponse { 25 | string message = 1; 26 | } -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/gRPC_gateway/wrk_benchmarking.lua: -------------------------------------------------------------------------------- 1 | wrk.method = "POST" 2 | wrk.body = '{"name":"John Doe"}' 3 | wrk.headers["Content-Type"] = "application/json" 4 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/rest_api_non_tls/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | "regexp" 8 | ) 9 | 10 | type HelloRequest struct { 11 | Name string `json:"name"` 12 | } 13 | 14 | type HelloResponse struct { 15 | Message string `json:"message"` 16 | } 17 | 18 | func greetHandler(w http.ResponseWriter, r *http.Request) { 19 | log.Println("Starting greet handler") 20 | if r.Method != http.MethodPost { 21 | log.Println("Wrong method") 22 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 23 | return 24 | } 25 | 26 | var req HelloRequest 27 | if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 28 | log.Println("Bad request") 29 | http.Error(w, "Bad request", http.StatusBadRequest) 30 | return 31 | } 32 | 33 | // Validation 34 | if len(req.Name) < 5 || len(req.Name) > 50 || !regexp.MustCompile("^[a-zA-Z]+$").MatchString(req.Name) { 35 | log.Println(req.Name) 36 | log.Println(len(req.Name)) 37 | log.Println(!regexp.MustCompile("^[a-zA-Z]+$").MatchString(req.Name)) 38 | log.Println("Validation failed") 39 | http.Error(w, "Invalid request: name must be 5-50 characters long and contain only letters", http.StatusBadRequest) 40 | return 41 | } 42 | 43 | resp := HelloResponse{Message: "Hello, " + req.Name} 44 | w.Header().Set("Content-Type", "application/json") 45 | w.WriteHeader(http.StatusOK) 46 | json.NewEncoder(w).Encode(resp) 47 | log.Println("Sent response") 48 | } 49 | 50 | func main() { 51 | http.HandleFunc("/v1/greet", greetHandler) 52 | log.Println("HTTP server is running on port :8000...") 53 | if err := http.ListenAndServe(":8000", nil); err != nil { 54 | log.Fatalf("Failed to serve HTTP: %v", err) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /grpc_practice/benchmarking-Lecture305/rest_api_non_tls/wrk_benchmarking.lua: -------------------------------------------------------------------------------- 1 | wrk.method = "POST" 2 | wrk.body = '{"name": "John Doe"}' 3 | wrk.headers["Content-Type"] = "application/json" -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDezCCAmOgAwIBAgIUBqHTI9XIR0L3wmsT73kWrBAMpKowDQYJKoZIhvcNAQEL 3 | BQAwWzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 4 | DVNhbiBGcmFuY2lzY28xCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3Qw 5 | HhcNMjQwODI5MDc0ODQ5WhcNMjUwODI5MDc0ODQ5WjBbMQswCQYDVQQGEwJVUzET 6 | MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkG 7 | A1UECwwCSVQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD 8 | ggEPADCCAQoCggEBAMVbILJAuXG6BWQ2AHTatwekngFDL59PDG6BScU7HnjT7vVD 9 | gshbwFg9t2q9VlS+hPWwKAioktfJ0G5Ywxn96SXTZoQ80FX3Uo9sVgBFwqFqq6br 10 | HUgyIxcu8yHxqIieuqlVojpNpcVgKrfOp258AiV+YYQxIZiSP3iLAsU2ifc0cLE9 11 | J1Yqzo1Ft2S+gAu4BrHZRfK7lUpfDfb6TKbi2KJQ2PQm3ia3G0bBeTu2L1BKJxtU 12 | Z0SChxgtznahCjZyUO+oVe3b58i15B8x1zMmUiBS8dYcROFY7XNN8Hy4ju30kE50 13 | ZzQHPhRw+rry4S3PIYA2woBo09mNYgv3mji83EUCAwEAAaM3MDUwFAYDVR0RBA0w 14 | C4IJbG9jYWxob3N0MB0GA1UdDgQWBBSTC7cxGAKKdMIA9DhirMKo/1YJvzANBgkq 15 | hkiG9w0BAQsFAAOCAQEAB0hYVkBZTB4maMd2KrykLPL5xLWySNg42q04sHqouOuf 16 | 2KL1pHsqn3nysnLqeGLr+b6WlUDEmFwyrdS7nOg4pU8HUK93+39SEG2VSSyuWifU 17 | 9rvolWnNKmqloC8Xcs9ZVzzptEZuaOV1ZGbTDsrU5igBrt1MydW5b6M9++ze0yx0 18 | 6XNqtIPXFdRd+LVM4faUaNeL+a4x3u2JHeGABFbu8SSRIxDEUYSvp42BN1HGa5GC 19 | ObKuln2VdHslzDTukDq4pCCNyPg+ZYuhPoLj9MK6zhGkwZScOL5iQRbOO62a+DKQ 20 | 8jmsXxnUsJXI6dwDTOClVUENzlKbO1cf5GVQ0FmRKg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/commands.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. main.proto 2 | 3 | 4 | go get google.golang.org/grpc 5 | go get github.com/grpc-ecosystem/grpc-gateway/v2/runtime@v2.21.0 6 | 7 | protoc --go_out=. --go-grpc_out=. proto/main.proto 8 | 9 | protoc -I=proto --go_out=. --go-grpc_out=. --grpc-gateway_out=. --validate_out=lang=go:. main.proto 10 | 11 | 12 | go install \ 13 | github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ 14 | 15 | 16 | github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 (exclude) 17 | 18 | 19 | go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest 20 | 21 | wget -P proto/google/api https://raw.githubusercontent.com/googleapis/googleapis/master/google/api/annotations.proto (assuming you are at project folder root) 22 | 23 | curl -o annotations.proto https://raw.githubusercontent.com/googleapis/googleapis/master/google/api/annotations.proto 24 | curl -o http.proto https://raw.githubusercontent.com/googleapis/googleapis/master/google/api/http.proto -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/go.mod: -------------------------------------------------------------------------------- 1 | module grpcgatewayproject 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v1.1.0 7 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 8 | google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a 9 | google.golang.org/grpc v1.65.0 10 | google.golang.org/protobuf v1.34.2 11 | ) 12 | 13 | require ( 14 | golang.org/x/net v0.26.0 // indirect 15 | golang.org/x/sys v0.21.0 // indirect 16 | golang.org/x/text v0.16.0 // indirect 17 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDFWyCyQLlxugVk 3 | NgB02rcHpJ4BQy+fTwxugUnFOx540+71Q4LIW8BYPbdqvVZUvoT1sCgIqJLXydBu 4 | WMMZ/ekl02aEPNBV91KPbFYARcKhaqum6x1IMiMXLvMh8aiInrqpVaI6TaXFYCq3 5 | zqdufAIlfmGEMSGYkj94iwLFNon3NHCxPSdWKs6NRbdkvoALuAax2UXyu5VKXw32 6 | +kym4tiiUNj0Jt4mtxtGwXk7ti9QSicbVGdEgocYLc52oQo2clDvqFXt2+fIteQf 7 | MdczJlIgUvHWHEThWO1zTfB8uI7t9JBOdGc0Bz4UcPq68uEtzyGANsKAaNPZjWIL 8 | 95o4vNxFAgMBAAECggEAEMeCrCUcnzK1qqN8vnKqBRhV5r2TmvPZlrufTgmMubEr 9 | K+clg2tpmxcENSsL4ACixVDI1pOeiII8GmWpkNgprnGe0bdp7yUr+822Mie8OIUd 10 | Ov/aaXz5xsrTGRu2vIbiT+tb86EOaw2WFDKZwacBd7abC+YxeQtWIiWPgrz0VfQU 11 | 8FcPIqZ32yyDYLfN67MUDJGm107ekjM//WSVMjqhjGpMcSSvmwv+HdI6yiuwr+iu 12 | tcJ3xX7gpQa/Cp7FWzYTZ6z9llrnH2P9Q2HKEGfhoJs7lKD+mjWX7z0m3aucyuQI 13 | uOtjJoymdhwWUqeF/zdm2qCG7LsIGeYydxbc8zzjgQKBgQD9r+G1Xn3xngmtkMan 14 | DInvBV8Dx+sEVAmyaVEv1ls3zszM33TgdymHsc7kdL8fiKNGaN/FEWGp8tRZhgKy 15 | PvkBpat/taK7LFVj5hGTr95UNK0V20WL/bRGu7vAQvks39A5+glBIzVRl1R+WDJN 16 | m3qlHtsLA6XyG3vxo8o4ZGY2XQKBgQDHJ8Q4vA7iX1IodkerQmVrrPNk21hKV9W3 17 | aW4vbjeyJR6QPc8tS8f2vM+iuc2UqxqJSpFqhGtg6u/IT7sykbAjeEfxctNLYT3r 18 | wtFbfJNuL2v2FRehZwi17qdo4fj5vT4VabtFlhEYpuUmQKs6f4VGcNLqhPD4q/PV 19 | m8HfEXOPCQKBgQDsGf8Uz4ajkpQrRyy7V/4fyH3vhOaDtrr3ovD+dp+axwrwOaAL 20 | MJwkQCXvlYAzFvXul7h7LnwYsXlUgFaOEfGpyMheKWv0i4RFX2BIdUuUTxov101Y 21 | xpw7oIlSnIJPc1XWP5DRYLVE5HSsyeS3OdbhSmBOVezh8RZfhDK2XSqLuQKBgQCZ 22 | IRuAICE1r+NFF0UeCoxfEXmIKBun9gdu4lMFhzKt+Fqav9vH0UfskNr6HPFUiYd6 23 | 3uoWw8CooZxDIgMm69xKOZbfsNGEWT26RG6jcJMPmsjhSvCDeuy4rsrsGyxMIlVV 24 | M5n59Fwq31C8a+b8sMZyFhgmmJeMLPLsYLnd4dY/uQKBgQDf4gEwevhN9QLKuK4n 25 | rWRfsXckgURI4we4VkA4+XNh+tlSAJFWynCvOtk+UvHiX4YqCXzh7FRPwveyJZ77 26 | r+nrwwWYSSyPpLcJbcFWlRPT/Kzk6Es1frdPf7TmBE/5/0kA6vPH2rv/JPnaYsld 27 | QBmBwg/1SXoOHAkZ8c0DRwf4YQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/proto/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_Gateway_RESTComboAPI/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "validate/validate.proto"; 4 | import "google/api/annotations.proto"; 5 | 6 | option go_package = "/proto/gen;mainapipb"; 7 | 8 | package mainapi; 9 | 10 | service Greeter { 11 | rpc Greet (HelloRequest) returns (HelloResponse){ 12 | option (google.api.http) = { 13 | post: "/v1/greet" 14 | body: "*" 15 | }; 16 | }; 17 | } 18 | 19 | message HelloRequest { 20 | string name = 1 [(validate.rules).string = {min_len: 5, max_len: 50}, (validate.rules).string.pattern = "[a-zA-Z]+$"]; // Added validation rules 21 | } 22 | 23 | message HelloResponse { 24 | string message = 1; 25 | } -------------------------------------------------------------------------------- /grpc_practice/gRPC_protovalidate/commands.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. main.proto 2 | 3 | 4 | go get google.golang.org/grpc 5 | 6 | 7 | protoc --go_out=. --go-grpc_out=. proto/main.proto 8 | 9 | protoc -I=proto --go_out=. --go-grpc_out=. --validate_out=lang=go:. main.proto -------------------------------------------------------------------------------- /grpc_practice/gRPC_protovalidate/go.mod: -------------------------------------------------------------------------------- 1 | module grpcprotovalidate 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/envoyproxy/protoc-gen-validate v1.1.0 7 | google.golang.org/grpc v1.65.0 8 | google.golang.org/protobuf v1.34.2 9 | ) 10 | 11 | require ( 12 | golang.org/x/net v0.26.0 // indirect 13 | golang.org/x/sys v0.21.0 // indirect 14 | golang.org/x/text v0.16.0 // indirect 15 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_protovalidate/go.sum: -------------------------------------------------------------------------------- 1 | github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= 2 | github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 6 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 7 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 8 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 10 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 11 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= 12 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 13 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= 14 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 15 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 16 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 17 | -------------------------------------------------------------------------------- /grpc_practice/gRPC_protovalidate/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "validate/validate.proto"; 4 | 5 | option go_package = "/proto/gen;mainapipb"; 6 | 7 | package mainapi; 8 | 9 | service Greeter { 10 | rpc Greet (HelloRequest) returns (HelloResponse); 11 | } 12 | 13 | message HelloRequest { 14 | string name = 1 [(validate.rules).string = {min_len: 5, max_len: 50}, (validate.rules).string.pattern = "[a-zA-Z]+$"]; // Added validation rules 15 | } 16 | 17 | message HelloResponse { 18 | string message = 1; 19 | } -------------------------------------------------------------------------------- /grpc_practice/gRPC_protovalidate/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log" 6 | "net" 7 | 8 | pb "grpcprotovalidate/proto/gen" 9 | 10 | "google.golang.org/grpc" 11 | "google.golang.org/grpc/codes" 12 | "google.golang.org/grpc/reflection" 13 | "google.golang.org/grpc/status" 14 | ) 15 | 16 | // server is used to implement mainapi.GreeterServer. 17 | type server struct { 18 | pb.UnimplementedGreeterServer 19 | } 20 | 21 | // Greet implements mainapi.GreeterServer 22 | func (s *server) Greet(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) { 23 | // Validate the incoming request 24 | err := req.Validate() 25 | if err != nil { 26 | log.Printf("Validation failed: %v", err) 27 | // Return an invalid argument error if validation fails 28 | return nil, status.Errorf(codes.InvalidArgument, "Invalid request: %v", err) 29 | } 30 | 31 | return &pb.HelloResponse{Message: "Hello, " + req.GetName()}, nil 32 | } 33 | 34 | func main() { 35 | // Create a listener on TCP port 50051 36 | listener, err := net.Listen("tcp", ":50051") 37 | if err != nil { 38 | log.Fatalf("Failed to listen: %v", err) 39 | } 40 | 41 | // Create a gRPC server 42 | grpcServer := grpc.NewServer() 43 | pb.RegisterGreeterServer(grpcServer, &server{}) 44 | 45 | reflection.Register(grpcServer) 46 | 47 | log.Println("Server is running on port :50051...") 48 | // Start the server 49 | if err := grpcServer.Serve(listener); err != nil { 50 | log.Fatalf("Failed to serve: %v", err) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /grpc_practice/grpc_client/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDezCCAmOgAwIBAgIUBqHTI9XIR0L3wmsT73kWrBAMpKowDQYJKoZIhvcNAQEL 3 | BQAwWzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 4 | DVNhbiBGcmFuY2lzY28xCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3Qw 5 | HhcNMjQwODI5MDc0ODQ5WhcNMjUwODI5MDc0ODQ5WjBbMQswCQYDVQQGEwJVUzET 6 | MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkG 7 | A1UECwwCSVQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD 8 | ggEPADCCAQoCggEBAMVbILJAuXG6BWQ2AHTatwekngFDL59PDG6BScU7HnjT7vVD 9 | gshbwFg9t2q9VlS+hPWwKAioktfJ0G5Ywxn96SXTZoQ80FX3Uo9sVgBFwqFqq6br 10 | HUgyIxcu8yHxqIieuqlVojpNpcVgKrfOp258AiV+YYQxIZiSP3iLAsU2ifc0cLE9 11 | J1Yqzo1Ft2S+gAu4BrHZRfK7lUpfDfb6TKbi2KJQ2PQm3ia3G0bBeTu2L1BKJxtU 12 | Z0SChxgtznahCjZyUO+oVe3b58i15B8x1zMmUiBS8dYcROFY7XNN8Hy4ju30kE50 13 | ZzQHPhRw+rry4S3PIYA2woBo09mNYgv3mji83EUCAwEAAaM3MDUwFAYDVR0RBA0w 14 | C4IJbG9jYWxob3N0MB0GA1UdDgQWBBSTC7cxGAKKdMIA9DhirMKo/1YJvzANBgkq 15 | hkiG9w0BAQsFAAOCAQEAB0hYVkBZTB4maMd2KrykLPL5xLWySNg42q04sHqouOuf 16 | 2KL1pHsqn3nysnLqeGLr+b6WlUDEmFwyrdS7nOg4pU8HUK93+39SEG2VSSyuWifU 17 | 9rvolWnNKmqloC8Xcs9ZVzzptEZuaOV1ZGbTDsrU5igBrt1MydW5b6M9++ze0yx0 18 | 6XNqtIPXFdRd+LVM4faUaNeL+a4x3u2JHeGABFbu8SSRIxDEUYSvp42BN1HGa5GC 19 | ObKuln2VdHslzDTukDq4pCCNyPg+ZYuhPoLj9MK6zhGkwZScOL5iQRbOO62a+DKQ 20 | 8jmsXxnUsJXI6dwDTOClVUENzlKbO1cf5GVQ0FmRKg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /grpc_practice/grpc_client/go.mod: -------------------------------------------------------------------------------- 1 | module simplegrpcclient 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | google.golang.org/grpc v1.66.0 7 | google.golang.org/protobuf v1.34.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.26.0 // indirect 12 | golang.org/x/sys v0.21.0 // indirect 13 | golang.org/x/text v0.16.0 // indirect 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /grpc_practice/grpc_client/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 4 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 5 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 6 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 7 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 8 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 9 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= 10 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 11 | google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= 12 | google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= 13 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 14 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | -------------------------------------------------------------------------------- /grpc_practice/grpc_client/proto/farewell/farewell.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package farewell; 4 | 5 | option go_package = "/proto/gen/farewell;farewellpb"; 6 | 7 | /* 8 | service AufWiedersehen { 9 | rpc BidGoodBye(GoodByeRequest) returns (GoodByeResponse); 10 | } 11 | */ 12 | 13 | message GoodByeRequest { 14 | string name = 1; 15 | } 16 | 17 | message GoodByeResponse { 18 | string message = 2; 19 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_client/proto/greeter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package calculator; 4 | 5 | option go_package = "/proto/gen;mainapipb"; 6 | 7 | /* 8 | service AufWiedersehen { 9 | rpc BidGoodBye(GoodByeRequest) returns (GoodByeResponse); 10 | } 11 | 12 | message GoodByeRequest { 13 | string name = 1; 14 | } 15 | 16 | message GoodByeResponse { 17 | string message = 2; 18 | } 19 | */ 20 | 21 | message HelloRequest{ 22 | string name = 1; 23 | } 24 | 25 | message HelloResponse { 26 | string message = 1; 27 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_client/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "greeter.proto"; 4 | import "farewell/farewell.proto"; 5 | 6 | package calculator; 7 | 8 | option go_package = "/proto/gen;mainapipb"; 9 | 10 | service Calculate { 11 | rpc Add (AddRequest) returns (AddResponse); 12 | } 13 | 14 | service Greeter { 15 | rpc Greet (HelloRequest) returns (HelloResponse); 16 | rpc Add (HelloRequest) returns (HelloResponse); // This does not work. Duplicate 17 | } 18 | 19 | service BidFarewell { 20 | rpc BidGoodBye(farewell.GoodByeRequest) returns (farewell.GoodByeResponse); 21 | } 22 | 23 | message AddRequest { 24 | int32 a = 1; 25 | int32 b = 2; 26 | } 27 | 28 | message AddResponse { 29 | int32 sum = 1; 30 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_server/cert.conf: -------------------------------------------------------------------------------- 1 | [req] 2 | distinguished_name = req_distinguished_name 3 | req_extensions = req_ext 4 | x509_extensions = v3_ca # The extensions to add to the self-signed cert 5 | 6 | [req_distinguished_name] 7 | countryName = Country Name (2 letter code) 8 | countryName_default = US 9 | stateOrProvinceName = State or Province Name (full name) 10 | stateOrProvinceName_default = California 11 | localityName = Locality Name (eg, city) 12 | localityName_default = San Francisco 13 | organizationalUnitName = Organizational Unit Name (eg, section) 14 | organizationalUnitName_default = IT 15 | commonName = Common Name (eg, fully qualified host name) 16 | commonName_default = localhost 17 | commonName_max = 64 18 | 19 | [req_ext] 20 | subjectAltName = @alt_names 21 | 22 | [v3_ca] 23 | subjectAltName = @alt_names 24 | 25 | [alt_names] 26 | DNS.1 = localhost 27 | -------------------------------------------------------------------------------- /grpc_practice/grpc_server/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDezCCAmOgAwIBAgIUBqHTI9XIR0L3wmsT73kWrBAMpKowDQYJKoZIhvcNAQEL 3 | BQAwWzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 4 | DVNhbiBGcmFuY2lzY28xCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3Qw 5 | HhcNMjQwODI5MDc0ODQ5WhcNMjUwODI5MDc0ODQ5WjBbMQswCQYDVQQGEwJVUzET 6 | MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkG 7 | A1UECwwCSVQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD 8 | ggEPADCCAQoCggEBAMVbILJAuXG6BWQ2AHTatwekngFDL59PDG6BScU7HnjT7vVD 9 | gshbwFg9t2q9VlS+hPWwKAioktfJ0G5Ywxn96SXTZoQ80FX3Uo9sVgBFwqFqq6br 10 | HUgyIxcu8yHxqIieuqlVojpNpcVgKrfOp258AiV+YYQxIZiSP3iLAsU2ifc0cLE9 11 | J1Yqzo1Ft2S+gAu4BrHZRfK7lUpfDfb6TKbi2KJQ2PQm3ia3G0bBeTu2L1BKJxtU 12 | Z0SChxgtznahCjZyUO+oVe3b58i15B8x1zMmUiBS8dYcROFY7XNN8Hy4ju30kE50 13 | ZzQHPhRw+rry4S3PIYA2woBo09mNYgv3mji83EUCAwEAAaM3MDUwFAYDVR0RBA0w 14 | C4IJbG9jYWxob3N0MB0GA1UdDgQWBBSTC7cxGAKKdMIA9DhirMKo/1YJvzANBgkq 15 | hkiG9w0BAQsFAAOCAQEAB0hYVkBZTB4maMd2KrykLPL5xLWySNg42q04sHqouOuf 16 | 2KL1pHsqn3nysnLqeGLr+b6WlUDEmFwyrdS7nOg4pU8HUK93+39SEG2VSSyuWifU 17 | 9rvolWnNKmqloC8Xcs9ZVzzptEZuaOV1ZGbTDsrU5igBrt1MydW5b6M9++ze0yx0 18 | 6XNqtIPXFdRd+LVM4faUaNeL+a4x3u2JHeGABFbu8SSRIxDEUYSvp42BN1HGa5GC 19 | ObKuln2VdHslzDTukDq4pCCNyPg+ZYuhPoLj9MK6zhGkwZScOL5iQRbOO62a+DKQ 20 | 8jmsXxnUsJXI6dwDTOClVUENzlKbO1cf5GVQ0FmRKg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /grpc_practice/grpc_server/commands.txt: -------------------------------------------------------------------------------- 1 | go install google.golang.org/protobuf/cmd/protoc-gen-go 2 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc 3 | 4 | 5 | protoc --go_out=. --go-grpc_out=. proto/main.proto 6 | 7 | protoc -I=proto --go_out=. --go-grpc_out=. proto/main.proto proto/greeter.proto 8 | protoc -I=proto --go_out=. --go-grpc_out=. proto/main.proto proto/greeter.proto proto/farewell/farewell.proto 9 | 10 | go get google.golang.org/grpc -------------------------------------------------------------------------------- /grpc_practice/grpc_server/go.mod: -------------------------------------------------------------------------------- 1 | module simplegrpcserver 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | google.golang.org/grpc v1.66.0 7 | google.golang.org/protobuf v1.34.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.26.0 // indirect 12 | golang.org/x/sys v0.21.0 // indirect 13 | golang.org/x/text v0.16.0 // indirect 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /grpc_practice/grpc_server/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 4 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 5 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 6 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 7 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 8 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 9 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= 10 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 11 | google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= 12 | google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= 13 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 14 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | -------------------------------------------------------------------------------- /grpc_practice/grpc_server/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDFWyCyQLlxugVk 3 | NgB02rcHpJ4BQy+fTwxugUnFOx540+71Q4LIW8BYPbdqvVZUvoT1sCgIqJLXydBu 4 | WMMZ/ekl02aEPNBV91KPbFYARcKhaqum6x1IMiMXLvMh8aiInrqpVaI6TaXFYCq3 5 | zqdufAIlfmGEMSGYkj94iwLFNon3NHCxPSdWKs6NRbdkvoALuAax2UXyu5VKXw32 6 | +kym4tiiUNj0Jt4mtxtGwXk7ti9QSicbVGdEgocYLc52oQo2clDvqFXt2+fIteQf 7 | MdczJlIgUvHWHEThWO1zTfB8uI7t9JBOdGc0Bz4UcPq68uEtzyGANsKAaNPZjWIL 8 | 95o4vNxFAgMBAAECggEAEMeCrCUcnzK1qqN8vnKqBRhV5r2TmvPZlrufTgmMubEr 9 | K+clg2tpmxcENSsL4ACixVDI1pOeiII8GmWpkNgprnGe0bdp7yUr+822Mie8OIUd 10 | Ov/aaXz5xsrTGRu2vIbiT+tb86EOaw2WFDKZwacBd7abC+YxeQtWIiWPgrz0VfQU 11 | 8FcPIqZ32yyDYLfN67MUDJGm107ekjM//WSVMjqhjGpMcSSvmwv+HdI6yiuwr+iu 12 | tcJ3xX7gpQa/Cp7FWzYTZ6z9llrnH2P9Q2HKEGfhoJs7lKD+mjWX7z0m3aucyuQI 13 | uOtjJoymdhwWUqeF/zdm2qCG7LsIGeYydxbc8zzjgQKBgQD9r+G1Xn3xngmtkMan 14 | DInvBV8Dx+sEVAmyaVEv1ls3zszM33TgdymHsc7kdL8fiKNGaN/FEWGp8tRZhgKy 15 | PvkBpat/taK7LFVj5hGTr95UNK0V20WL/bRGu7vAQvks39A5+glBIzVRl1R+WDJN 16 | m3qlHtsLA6XyG3vxo8o4ZGY2XQKBgQDHJ8Q4vA7iX1IodkerQmVrrPNk21hKV9W3 17 | aW4vbjeyJR6QPc8tS8f2vM+iuc2UqxqJSpFqhGtg6u/IT7sykbAjeEfxctNLYT3r 18 | wtFbfJNuL2v2FRehZwi17qdo4fj5vT4VabtFlhEYpuUmQKs6f4VGcNLqhPD4q/PV 19 | m8HfEXOPCQKBgQDsGf8Uz4ajkpQrRyy7V/4fyH3vhOaDtrr3ovD+dp+axwrwOaAL 20 | MJwkQCXvlYAzFvXul7h7LnwYsXlUgFaOEfGpyMheKWv0i4RFX2BIdUuUTxov101Y 21 | xpw7oIlSnIJPc1XWP5DRYLVE5HSsyeS3OdbhSmBOVezh8RZfhDK2XSqLuQKBgQCZ 22 | IRuAICE1r+NFF0UeCoxfEXmIKBun9gdu4lMFhzKt+Fqav9vH0UfskNr6HPFUiYd6 23 | 3uoWw8CooZxDIgMm69xKOZbfsNGEWT26RG6jcJMPmsjhSvCDeuy4rsrsGyxMIlVV 24 | M5n59Fwq31C8a+b8sMZyFhgmmJeMLPLsYLnd4dY/uQKBgQDf4gEwevhN9QLKuK4n 25 | rWRfsXckgURI4we4VkA4+XNh+tlSAJFWynCvOtk+UvHiX4YqCXzh7FRPwveyJZ77 26 | r+nrwwWYSSyPpLcJbcFWlRPT/Kzk6Es1frdPf7TmBE/5/0kA6vPH2rv/JPnaYsld 27 | QBmBwg/1SXoOHAkZ8c0DRwf4YQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /grpc_practice/grpc_server/proto/farewell/farewell.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package farewell; 4 | 5 | option go_package = "/proto/gen/farewell;farewellpb"; 6 | 7 | /* 8 | service AufWiedersehen { 9 | rpc BidGoodBye(GoodByeRequest) returns (GoodByeResponse); 10 | } 11 | */ 12 | 13 | message GoodByeRequest { 14 | string name = 1; 15 | } 16 | 17 | message GoodByeResponse { 18 | string message = 2; 19 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_server/proto/greeter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package calculator; 4 | 5 | option go_package = "/proto/gen;mainapipb"; 6 | 7 | /* 8 | service AufWiedersehen { 9 | rpc BidGoodBye(GoodByeRequest) returns (GoodByeResponse); 10 | } 11 | 12 | message GoodByeRequest { 13 | string name = 1; 14 | } 15 | 16 | message GoodByeResponse { 17 | string message = 2; 18 | } 19 | */ 20 | 21 | message HelloRequest{ 22 | string name = 1; 23 | } 24 | 25 | message HelloResponse { 26 | string message = 1; 27 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_server/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "greeter.proto"; 4 | import "farewell/farewell.proto"; 5 | 6 | package calculator; 7 | 8 | option go_package = "/proto/gen;mainapipb"; 9 | 10 | service Calculate { 11 | rpc Add (AddRequest) returns (AddResponse); 12 | } 13 | 14 | service Greeter { 15 | rpc Greet (HelloRequest) returns (HelloResponse); 16 | rpc Add (HelloRequest) returns (HelloResponse); 17 | } 18 | 19 | service BidFarewell { 20 | rpc BidGoodBye(farewell.GoodByeRequest) returns (farewell.GoodByeResponse); 21 | } 22 | 23 | message AddRequest { 24 | int32 a = 1; 25 | int32 b = 2; 26 | } 27 | 28 | message AddResponse { 29 | int32 sum = 1; 30 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_stream_client/commands.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. main.proto 2 | 3 | 4 | go get google.golang.org/grpc 5 | 6 | 7 | protoc --go_out=. --go-grpc_out=. proto/main.proto -------------------------------------------------------------------------------- /grpc_practice/grpc_stream_client/go.mod: -------------------------------------------------------------------------------- 1 | module grpcstreamclient 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | google.golang.org/grpc v1.66.0 7 | google.golang.org/protobuf v1.34.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.26.0 // indirect 12 | golang.org/x/sys v0.21.0 // indirect 13 | golang.org/x/text v0.16.0 // indirect 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /grpc_practice/grpc_stream_client/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 4 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 5 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 6 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 7 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 8 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 9 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= 10 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 11 | google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= 12 | google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= 13 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 14 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | -------------------------------------------------------------------------------- /grpc_practice/grpc_stream_client/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package calculator; 4 | 5 | option go_package = "/proto/gen;mainpb"; 6 | 7 | service Calculator { 8 | rpc Add (AddRequest) returns (AddResponse); // Unary RPC 9 | rpc GenerateFibonacci (FibonacciRequest) returns (stream FibonacciResponse); // Server side stream 10 | rpc SendNumbers (stream NumberRequest) returns (NumberResponse); // Client side stream 11 | rpc Chat (stream ChatMessage) returns (stream ChatMessage); // Bi-Directional stream 12 | } 13 | 14 | message ChatMessage { 15 | string message = 1; 16 | } 17 | 18 | message NumberRequest{ 19 | int32 number = 1; 20 | } 21 | 22 | message NumberResponse { 23 | int32 sum = 1; 24 | } 25 | 26 | message AddRequest { 27 | int32 a = 1; 28 | int32 b = 2; 29 | } 30 | 31 | message AddResponse { 32 | int32 sum = 1; 33 | } 34 | 35 | message FibonacciRequest { 36 | int32 n = 1; // Number of fibonacci numbers to generate 37 | } 38 | 39 | message FibonacciResponse { 40 | int32 number = 1; // Individual Fibonacci number 41 | } -------------------------------------------------------------------------------- /grpc_practice/grpc_streams/commands.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. main.proto 2 | 3 | 4 | go get google.golang.org/grpc 5 | 6 | 7 | protoc --go_out=. --go-grpc_out=. proto/main.proto -------------------------------------------------------------------------------- /grpc_practice/grpc_streams/go.mod: -------------------------------------------------------------------------------- 1 | module grpcstreams 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | google.golang.org/grpc v1.66.0 7 | google.golang.org/protobuf v1.34.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.26.0 // indirect 12 | golang.org/x/sys v0.21.0 // indirect 13 | golang.org/x/text v0.16.0 // indirect 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /grpc_practice/grpc_streams/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 4 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 5 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 6 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 7 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 8 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 9 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= 10 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 11 | google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= 12 | google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= 13 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 14 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | -------------------------------------------------------------------------------- /grpc_practice/grpc_streams/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package calculator; 4 | 5 | option go_package = "/proto/gen;mainpb"; 6 | 7 | service Calculator { 8 | rpc Add (AddRequest) returns (AddResponse); // Unary RPC 9 | rpc GenerateFibonacci (FibonacciRequest) returns (stream FibonacciResponse); // Server side stream 10 | rpc SendNumbers (stream NumberRequest) returns (NumberResponse); // Client side stream 11 | rpc Chat (stream ChatMessage) returns (stream ChatMessage); // Bi-Directional stream 12 | } 13 | 14 | message ChatMessage { 15 | string message = 1; 16 | } 17 | 18 | message NumberRequest{ 19 | int32 number = 1; 20 | } 21 | 22 | message NumberResponse { 23 | int32 sum = 1; 24 | } 25 | 26 | message AddRequest { 27 | int32 a = 1; 28 | int32 b = 2; 29 | } 30 | 31 | message AddResponse { 32 | int32 sum = 1; 33 | } 34 | 35 | message FibonacciRequest { 36 | int32 n = 1; // Number of fibonacci numbers to generate 37 | } 38 | 39 | message FibonacciResponse { 40 | int32 number = 1; // Individual Fibonacci number 41 | } -------------------------------------------------------------------------------- /modernroutes/go.mod: -------------------------------------------------------------------------------- 1 | module modernroutes 2 | 3 | go 1.22.5 4 | -------------------------------------------------------------------------------- /modernroutes/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | 10 | mux := http.NewServeMux() 11 | 12 | // Method based routing 13 | mux.HandleFunc("POST /items/create", func(w http.ResponseWriter, r *http.Request) { 14 | fmt.Fprintf(w, "Item created") 15 | }) 16 | 17 | // Method based routing 18 | mux.HandleFunc("DELETE /items/create", func(w http.ResponseWriter, r *http.Request) { 19 | fmt.Fprintf(w, "Item deleted") 20 | }) 21 | 22 | // Wildcard in pattern - path parameter 23 | mux.HandleFunc("GET /teachers/{id}", func(w http.ResponseWriter, r *http.Request) { 24 | fmt.Fprintf(w, "Teacher ID: %s", r.PathValue("id")) 25 | }) 26 | 27 | // Wildcard with "..." 28 | mux.HandleFunc("/files/{path...}", func(w http.ResponseWriter, r *http.Request) { 29 | fmt.Fprintf(w, "Path: %s", r.PathValue("path")) 30 | }) 31 | 32 | mux.HandleFunc("/path1/{param1}", func(w http.ResponseWriter, r *http.Request) { 33 | fmt.Fprintf(w, "Param1: %s", r.PathValue("param1")) 34 | }) 35 | 36 | // mux.HandleFunc("/{param2}/path2", func(w http.ResponseWriter, r *http.Request) { 37 | // fmt.Fprintf(w, "Param2: %s", r.PathValue("param2")) 38 | // }) 39 | 40 | mux.HandleFunc("/path1/path2", func(w http.ResponseWriter, r *http.Request) { 41 | fmt.Fprintf(w, "Nothin to see here") 42 | }) 43 | 44 | http.ListenAndServe(":8080", mux) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /proto_buf_practice/command.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. proto/main.proto 2 | 3 | 4 | protoc -I=proto --go_out=. proto/main.proto proto/user/user.proto proto/order.proto 5 | 6 | 7 | 8 | source: https://github.com/protocolbuffers/protobuf/issues/2497 9 | 10 | "We dropped required fields in proto3 because required fields are generally considered harmful and violating protobuf's compatibility semantics. The whole idea of using protobuf is that it allows you to add/remove fields from your protocol definition while still being fully forward/backward compatible with newer/older binaries. Required fields break this though. You can never safely add a required field to a .proto definition, nor can you safely remove an existing required field because both of these actions break wire compatibility. For example, if you add a required field to a .proto definition, binaries built with the new definition won't be able to parse data serialized using the old definition because the required field is not present in old data. In a complex system where .proto definitions are shared widely across many different components of the system, adding/removing required fields could easily bring down multiple parts of the system. We have seen production issues caused by this multiple times and it's pretty much banned everywhere inside Google for anyone to add/remove required fields. For this reason we completely removed required fields in proto3. 11 | 12 | After the removal of "required", "optional" is just redundant so we removed "optional" as well." -------------------------------------------------------------------------------- /proto_buf_practice/proto/main.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | import "user/user.proto"; 6 | import "order.proto"; 7 | 8 | option go_package = "/proto/gen;mainpb"; 9 | 10 | service Greeter { 11 | rpc SayHello (HelloRequest) returns (HelloResponse); 12 | rpc Orders (user.User) returns (Order); 13 | } 14 | 15 | message HelloRequest { 16 | string name = 1; 17 | int32 age = 2; 18 | } 19 | 20 | message HelloResponse { 21 | string conf_message = 1; 22 | repeated string data = 2; // return value ["test1", "test2", "test3"] 23 | } 24 | 25 | message UserProfile { 26 | string username = 1; 27 | string email = 2; 28 | } -------------------------------------------------------------------------------- /proto_buf_practice/proto/order.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | import "user/user.proto"; 6 | 7 | option go_package = "/proto/gen;mainpb"; 8 | 9 | message Order { 10 | string id = 1; 11 | user.User user = 2; 12 | Address address = 3; 13 | } 14 | 15 | message Address { 16 | string address_line = 1; 17 | string city = 2; 18 | string state = 3; 19 | } -------------------------------------------------------------------------------- /proto_buf_practice/proto/user/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "/proto/gen/user;userpb"; 4 | 5 | package user; 6 | 7 | message User { 8 | string id = 1; 9 | } -------------------------------------------------------------------------------- /rest_api_go/MailHog.txt: -------------------------------------------------------------------------------- 1 | go install github.com/mailhog/MailHog@latest 2 | ~/go/bin/MailHog 3 | 4 | UI for incoming emails: http://localhost:8025/ 5 | 6 | -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/macOS/rest_api_macOS_arm64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/macOS/rest_api_macOS_arm64 -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_NONTLS_WO_Mdlwrs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_NONTLS_WO_Mdlwrs -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_NONTLS_With_Mdlwrs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_NONTLS_With_Mdlwrs -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_TLS_WO_Mdlwrs_http2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_TLS_WO_Mdlwrs_http2 -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_withMdlwrs_http2_TLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/rest_api_linux_X86-64_withMdlwrs_http2_TLS -------------------------------------------------------------------------------- /rest_api_go/cmd/api/binaries/win/rest_api_windows_X86-64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/binaries/win/rest_api_windows_X86-64 -------------------------------------------------------------------------------- /rest_api_go/cmd/api/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDcTCCAlkCFDvyOiSh1J2ZQkUyqwCK8irDOc7ZMA0GCSqGSIb3DQEBCwUAMHUx 3 | CzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMG 4 | A1UECgwMT3JnYW5pemF0aW9uMRwwGgYDVQQLDBNPcmdhbml6YXRpb25hbCBVbml0 5 | MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjQwODE4MTAzMDMxWhcNMjUwODE4MTAz 6 | MDMxWjB1MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENp 7 | dHkxFTATBgNVBAoMDE9yZ2FuaXphdGlvbjEcMBoGA1UECwwTT3JnYW5pemF0aW9u 8 | YWwgVW5pdDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC 9 | AQ8AMIIBCgKCAQEAoRn8kWeeQj7AWu9h5VV5g6RUn+9iwQ2o3Kvp4h6K8EWGDwnT 10 | DCzvftaoNlOcbyoXIlVweke+/F8yDmPmV3E2a5i0IaDeOGha2tch1zQIMCgOO5x+ 11 | cgt7ZL96DDAmrKSQMIK62TDF1OEIFjT8C7dYlMmEbY7KB0FOVWufD3shgfDjgKzp 12 | oOs1dRxQdlwFB9PL6WuCVDSBisAVRW7q9pf3T70afpD9SkH4tpbgeeFm2u8ExLEn 13 | hpnQwa5GbkCA1Cv/MY4o0xhhIdGv3tVoRGsLJ8kqhkYbbW4otVv8b3xpuRgCQr5C 14 | avELxN/P4CmclcbuYLPG+crlh48+fGdm8n6zIQIDAQABMA0GCSqGSIb3DQEBCwUA 15 | A4IBAQCP1ZyL7XyTq4Ukd6lW7LSwy6uTpCifncgZWzaSN3i5JNMkzjG/Wr4SToPh 16 | B35c0ibqrfWY7b0p7+6gAiOrwIAjWsnGN6FGdWy8sI4kn6VweqcjwBvjIjBIOnfg 17 | 9Mtby5/+iAcgRUh7agZnhBoC0NH9fxSCwg+qpEWDWuZqqsVmG4VL/nJQBtkzAUU+ 18 | xY9nKUzmqGF82RmeOOpDxbnHB62p3KcjMfCsGks2VUnjNUk2szDYznhQHiPziUZJ 19 | qmhBbSxPET1cggliHNLvuPpaRPVJvNileQUdPsJrSDWcEuremJikelrKKjX/MvK/ 20 | lB3+TFs8taXWtvVV+/syHfgB/5w5 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /rest_api_go/cmd/api/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChGfyRZ55CPsBa 3 | 72HlVXmDpFSf72LBDajcq+niHorwRYYPCdMMLO9+1qg2U5xvKhciVXB6R778XzIO 4 | Y+ZXcTZrmLQhoN44aFra1yHXNAgwKA47nH5yC3tkv3oMMCaspJAwgrrZMMXU4QgW 5 | NPwLt1iUyYRtjsoHQU5Va58PeyGB8OOArOmg6zV1HFB2XAUH08vpa4JUNIGKwBVF 6 | bur2l/dPvRp+kP1KQfi2luB54Wba7wTEsSeGmdDBrkZuQIDUK/8xjijTGGEh0a/e 7 | 1WhEawsnySqGRhttbii1W/xvfGm5GAJCvkJq8QvE38/gKZyVxu5gs8b5yuWHjz58 8 | Z2byfrMhAgMBAAECggEABXIy8xltJLEpYImaJh4TGwupnrSBgqQ7EqavI+lDaib3 9 | hreezlkQiZmpGxkNf0aNfKglwsR9JNv0/b6L0WXu4IlLgZ2GFaMVezNtnfBQ3Ivm 10 | G0bJkYJo2/mLHzFbhVeU1kb9GQ2Iio9G7jVBVgYPNQxw8SE0HDWtd77JJEVV1yYn 11 | TAlkddeL8LAgFKNoeJASL45gPh0r672rC1AapLq8Wip0c+VWhurwj8McamLKGqjo 12 | /vOj3jAa6RQjhMwkHKxygkRT0u9o6nDqbTFf/fBok6SvJoFzaElFHFUPiLxriHWG 13 | 3ZIR8BiK2rq87aN161hwQ75PNMdBCc+ABqtwhAqmVwKBgQDcSlPO484m3sVbqmYq 14 | qRlmhcYzkF6VIw4OlPocHGpJy7FSIdrPp3qZc+9UZeq/WTV+rstevWspTAfEmBSl 15 | gxIEQ+QitoNIF7bKIMBgfWz6t7enEampmHpridZoTkSk0qeEUO7gjjP1gNE3hCs0 16 | zvPmOOYVg1ibQPbvMnfiJKbvGwKBgQC7N2yEYbaILREEiezT2EgH8+b2i0i3yEjX 17 | 1gzvHB0He4SEqtjo6X+72ZmaWUT/gOoJXaNdOqeuUEOzePZPWZZn7LNuP8xKORht 18 | rIqjcaus8ZG9UuquhpbKj9tU8plR06fcR44nUTb/WwpqyhFKgduR3pgkTwx0VA1S 19 | j/ZuKJZ+cwKBgCaLTsy1aV29vtSCJSwzuEELCRn+mb4Iiy4b/QMsKaDN5jHTwKBy 20 | 0m3FLkwbJQ7kAgsvdGAYTobESdupLHulSmK6qlE0lBXqKE6HmoGHkKjxuk2eNox5 21 | JHpqfLx1bWdVgIATVSivWQIMzw6irpin2V8f94ouGDPaExrZPsav2RGfAoGANPiO 22 | lLpM+iS+LumTf7EvWEizbcilD5L0wVUIHdN3hzl0mlD4xJXklVMROfHOKvjfvzym 23 | T2ecMB73uN0d2/++JbN8ZVJZzBpxhf6Oz4YHDAzhro66Zh0gpzmi1ls59EQNt67r 24 | UsaQ6BlrTiHUWJ97b79qjsNrA7MQfe7LzAlh428CgYEAoKnPX7Oindi51B1yYTl7 25 | enk2XTgLR6rGeJhXYJNqV+MdYwJZEUl71jW1LDNMxg8Tp2V3YVFNhw9ghcJ/W1ot 26 | 43XEWGarjTQ1YgA4KKBJAegebG6Dsz4j/lRKTMlBZI0oElE5GEtjljcm0Kl3ct94 27 | rN6MWn9NSvQ9Ot/nEE5ZSOc= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /rest_api_go/cmd/api/obfuscated/rest_api_obf_linux_X86-64_TLS_With_Mdlwars: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/obfuscated/rest_api_obf_linux_X86-64_TLS_With_Mdlwars -------------------------------------------------------------------------------- /rest_api_go/cmd/api/obfuscated/rest_api_obf_linux_x86-64_NONTLS_WO_Mdlwars: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeovation/GoBootcamp/f164f2f2c2f6cae43e72ac94df3502be88148bb0/rest_api_go/cmd/api/obfuscated/rest_api_obf_linux_x86-64_NONTLS_WO_Mdlwars -------------------------------------------------------------------------------- /rest_api_go/go.mod: -------------------------------------------------------------------------------- 1 | module restapi 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/go-sql-driver/mysql v1.8.1 7 | github.com/joho/godotenv v1.5.1 8 | ) 9 | 10 | require ( 11 | filippo.io/edwards25519 v1.1.0 // indirect 12 | github.com/aymerick/douceur v0.2.0 // indirect 13 | github.com/go-mail/mail/v2 v2.3.0 // indirect 14 | github.com/golang-jwt/jwt/v5 v5.2.1 // indirect 15 | github.com/gorilla/css v1.0.1 // indirect 16 | github.com/microcosm-cc/bluemonday v1.0.27 // indirect 17 | golang.org/x/crypto v0.26.0 // indirect 18 | golang.org/x/net v0.26.0 // indirect 19 | golang.org/x/sys v0.23.0 // indirect 20 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /rest_api_go/helpful_commands.txt: -------------------------------------------------------------------------------- 1 | openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem -config openssl.cnf 2 | 3 | 4 | h2load --h1 -n 1000 -c 100 -m 10 -D 20s -H "Cookie: Bearer=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ3NTgwODYsInJvbGUiOiJhZG1pbiIsInVpZCI6MTIsInVzZXIiOiJhbGljZS5zbWl0aCJ9.eG8AdOqsz9G9XcxOda1VH-w-y-0-DCtJnouiAJIFkS4" -H "Origin: https://localhost:3000" 'http://localhost:3000/students?page=1&limit=300' && echo "SOURCE_CODE_HTTP1.1_NON-TLS_WO_MDLWRS" 5 | 6 | h2load --h1 -n 1000 -c 100 -m 10 -D 20s -H "Cookie: Bearer=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ3NTgwODYsInJvbGUiOiJhZG1pbiIsInVpZCI6MTIsInVzZXIiOiJhbGljZS5zbWl0aCJ9.eG8AdOqsz9G9XcxOda1VH-w-y-0-DCtJnouiAJIFkS4" -H "Origin: https://localhost:3000" 'http://localhost:3000/students?page=1&limit=300' && echo "SOURCE_CODE_HTTP1.1_NON-TLS_WO_MDLWRS" 7 | 8 | h2load -n 1000 -c 100 -m 10 -D 20s -H "Cookie: Bearer=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ3NTgwODYsInJvbGUiOiJhZG1pbiIsInVpZCI6MTIsInVzZXIiOiJhbGljZS5zbWl0aCJ9.eG8AdOqsz9G9XcxOda1VH-w-y-0-DCtJnouiAJIFkS4" -H "Origin: https://localhost:3000" 'https://localhost:3000/students?page=1&limit=300' && echo "OBF_HTTP_TLS_WITH_MDLWRS" 9 | 10 | h2load -n 1000 -c 100 -m 10 -D 20s -H "Cookie: Bearer=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ3NTgwODYsInJvbGUiOiJhZG1pbiIsInVpZCI6MTIsInVzZXIiOiJhbGljZS5zbWl0aCJ9.eG8AdOqsz9G9XcxOda1VH-w-y-0-DCtJnouiAJIFkS4" -H "Origin: https://localhost:3000" 'https://localhost:3000/students?page=1&limit=300' && echo "SOURCE-CODE_HTTP2_TLS_WITH_MDLWRS" 11 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/handlers/helpers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "errors" 5 | "reflect" 6 | "restapi/pkg/utils" 7 | "strings" 8 | ) 9 | 10 | func CheckBlankFields(value interface{}) error { 11 | val := reflect.ValueOf(value) 12 | for i := 0; i < val.NumField(); i++ { 13 | field := val.Field(i) 14 | if field.Kind() == reflect.String && field.String() == "" { 15 | return utils.ErrorHandler(errors.New("all fields are required"), "All fields are required") 16 | } 17 | } 18 | return nil 19 | } 20 | 21 | func GetFieldNames(model interface{}) []string { 22 | val := reflect.TypeOf(model) 23 | fields := []string{} 24 | 25 | for i := 0; i < val.NumField(); i++ { 26 | field := val.Field(i) 27 | fieldToAdd := strings.TrimSuffix(field.Tag.Get("json"), ",omitempty") 28 | fields = append(fields, fieldToAdd) 29 | } 30 | return fields 31 | } 32 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/compression.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "compress/gzip" 5 | "fmt" 6 | "net/http" 7 | "strings" 8 | ) 9 | 10 | func Compression(next http.Handler) http.Handler { 11 | fmt.Println("Compression Middleware...") 12 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 13 | fmt.Println("Compression Middleware being returned...") 14 | 15 | // Check of the client accepts gzip encoding 16 | if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { 17 | next.ServeHTTP(w, r) 18 | } 19 | 20 | // Set the respone header 21 | w.Header().Set("Content-Encoding", "gzip") 22 | gz := gzip.NewWriter(w) 23 | defer gz.Close() 24 | 25 | // Wrap the ResponseWriter 26 | w = &gzipResponseWriter{ResponseWriter: w, Writer: gz} 27 | 28 | next.ServeHTTP(w, r) 29 | fmt.Println("Sent response from Compression Middleware") 30 | }) 31 | } 32 | 33 | // gzipResponseWriter wraps http.ResponseWriter to write gzipped responses 34 | type gzipResponseWriter struct { 35 | http.ResponseWriter 36 | Writer *gzip.Writer 37 | } 38 | 39 | func (g *gzipResponseWriter) Write(b []byte) (int, error) { 40 | return g.Writer.Write(b) 41 | } 42 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/cors.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | // api is hosted at www.myapi.com 9 | // frontend server is at www.myfrontend.com 10 | 11 | // Allowed origins 12 | var allowedOrigins = []string{ 13 | "https://my-origin-url.com", 14 | "https://www.myfrontend.com", 15 | "https://localhost:3000", 16 | } 17 | 18 | func Cors(next http.Handler) http.Handler { 19 | fmt.Println("Cors Middleware...") 20 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 21 | fmt.Println("Cors Middleware being returned...") 22 | origin := r.Header.Get("Origin") 23 | // fmt.Println(origin) 24 | 25 | if isOriginAllowed(origin) { 26 | w.Header().Set("Access-Control-Allow-Origin", origin) 27 | 28 | } else { 29 | http.Error(w, "Not allowed by CORS", http.StatusForbidden) 30 | return 31 | } 32 | 33 | // Set other CORS headers 34 | w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") 35 | w.Header().Set("Access-Control-Expose-Headers", "Authorization") 36 | w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE") 37 | w.Header().Set("Access-Control-Allow-Credentials", "true") 38 | w.Header().Set("Access-Control-Max-Age", "3600") 39 | 40 | // Handle preflight request 41 | if r.Method == http.MethodOptions { 42 | return 43 | } 44 | 45 | next.ServeHTTP(w, r) 46 | fmt.Println("Cors Middleware ends...") 47 | }) 48 | } 49 | 50 | func isOriginAllowed(origin string) bool { 51 | for _, allowedOrigin := range allowedOrigins { 52 | if origin == allowedOrigin { 53 | return true 54 | } 55 | } 56 | return false 57 | } 58 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/exclude_routes.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strings" 7 | ) 8 | 9 | func MiddlewaresExcludePaths(middleware func(http.Handler) http.Handler, excludedPaths ...string) func(http.Handler) http.Handler { 10 | fmt.Println("MiddlewaresExcludePaths initialized") 11 | return func(next http.Handler) http.Handler { 12 | fmt.Println("============= MiddlewaresExcludePaths RAN") 13 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 14 | for _, path := range excludedPaths { 15 | if strings.HasPrefix(r.URL.Path, path) { 16 | next.ServeHTTP(w, r) 17 | return 18 | } 19 | } 20 | middleware(next).ServeHTTP(w, r) 21 | fmt.Println("Sent response from MiddlewaresExcludePaths") 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/rate_limiter.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | type rateLimiter struct { 11 | mu sync.Mutex 12 | visitors map[string]int 13 | limit int 14 | resetTime time.Duration 15 | } 16 | 17 | func NewRateLimiter(limit int, resetTime time.Duration) *rateLimiter { 18 | rl := &rateLimiter{ 19 | visitors: make(map[string]int), 20 | limit: limit, 21 | resetTime: resetTime, 22 | } 23 | // start the reset routine 24 | go rl.resetVisitorCount() 25 | return rl 26 | } 27 | 28 | func (rl *rateLimiter) resetVisitorCount() { 29 | for { 30 | time.Sleep(rl.resetTime) 31 | rl.mu.Lock() 32 | rl.visitors = make(map[string]int) 33 | rl.mu.Unlock() 34 | } 35 | } 36 | 37 | func (rl *rateLimiter) Middleware(next http.Handler) http.Handler { 38 | fmt.Println("Rate Limiter Middleware...") 39 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 40 | fmt.Println("Rate Limiter Middleware being returned...") 41 | rl.mu.Lock() 42 | defer rl.mu.Unlock() 43 | 44 | visitorIP := r.RemoteAddr // You might want to extract the IP in a more sophisticated way 45 | rl.visitors[visitorIP]++ 46 | // fmt.Printf("Vistor count from %v is %v\n", visitorIP, rl.visitors[visitorIP]) 47 | 48 | if rl.visitors[visitorIP] > rl.limit { 49 | http.Error(w, "Too many requests", http.StatusTooManyRequests) 50 | return 51 | } 52 | next.ServeHTTP(w, r) 53 | fmt.Println("Rate Limiter ends...") 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/response_time.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func ResponseTimeMiddleware(next http.Handler) http.Handler { 10 | fmt.Println("Response Time Middleware...") 11 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 12 | fmt.Println("Response Time Middleware being returned...") 13 | // fmt.Println("Received Request in ResponseTime") 14 | start := time.Now() 15 | 16 | //Create a custom ResponseWriter to capture the status code 17 | wrappedWriter := &responseWriter{ResponseWriter: w, status: http.StatusOK} 18 | 19 | // Calculate the duration 20 | duration := time.Since(start) 21 | w.Header().Set("X-Response-Time", duration.String()) 22 | next.ServeHTTP(wrappedWriter, r) 23 | 24 | // Log the request details 25 | duration = time.Since(start) 26 | fmt.Printf("Method: %s, URL: %s, Status: %d, Duration: %v\n", r.Method, r.URL, wrappedWriter.status, duration.String()) 27 | fmt.Println("Sent Response from Response Time Middleware") 28 | }) 29 | } 30 | 31 | // responseWriter 32 | type responseWriter struct { 33 | http.ResponseWriter 34 | status int 35 | } 36 | 37 | func (rw *responseWriter) WriteHeader(code int) { 38 | rw.status = code 39 | rw.ResponseWriter.WriteHeader(code) 40 | } 41 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/middlewares/security_headers.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | func SecurityHeaders(next http.Handler) http.Handler { 9 | fmt.Println("SecurityHeaders Middleware...") 10 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 11 | fmt.Println("SecurityHeaders Middleware being returned...") 12 | w.Header().Set("X-DNS-Prefetch-Control", "off") 13 | 14 | w.Header().Set("X-Frame-Options", "DENY") 15 | w.Header().Set("X-XSS-Protection", "1; mode=block") 16 | w.Header().Set("X-Content-Type-Options", "nosniff") 17 | w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload") 18 | w.Header().Set("Content-Security-Policy", "default-src 'self'") 19 | w.Header().Set("Referrer-Policy", "no-referrer") 20 | w.Header().Set("X-Powered-By", "Django") 21 | w.Header().Set("Server", "") 22 | w.Header().Set("X-Permitted-Cross-Domain-Policies", "none") 23 | w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0") 24 | w.Header().Set("Cross-Origin-Resource-Policy", "same-origin") 25 | w.Header().Set("Cross-Origin-Opener-Policy", "same-origin") 26 | w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp") 27 | w.Header().Set("Permissions-Policy", "geolocation=(self), microphone=()") 28 | 29 | next.ServeHTTP(w, r) 30 | fmt.Println("SecurityHeaders Middleware ends...") 31 | }) 32 | } 33 | 34 | // BASIC MIDDLEWARE SKELETON 35 | // func securityHeaders(next http.Handler) http.Handler { 36 | // return http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { 37 | // next.ServeHTTP(w, r) 38 | // }) 39 | // } 40 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/router/execs_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | "restapi/internal/api/handlers" 6 | ) 7 | 8 | func execsRouter() *http.ServeMux { 9 | mux := http.NewServeMux() 10 | 11 | mux.HandleFunc("GET /execs", handlers.GetExecsHandler) 12 | mux.HandleFunc("POST /execs", handlers.AddExecsHandler) 13 | mux.HandleFunc("PATCH /execs", handlers.PatchExecsHandler) 14 | 15 | mux.HandleFunc("GET /execs/{id}", handlers.GetOneExecHandler) 16 | mux.HandleFunc("PATCH /execs/{id}", handlers.PatchOneExecHandler) 17 | mux.HandleFunc("DELETE /execs/{id}", handlers.DeleteOneExecHandler) 18 | mux.HandleFunc("POST /execs/{id}/updatepassword", handlers.UpdatePasswordHandler) 19 | 20 | mux.HandleFunc("POST /execs/login", handlers.LoginHandler) 21 | mux.HandleFunc("POST /execs/logout", handlers.LogoutHandler) 22 | mux.HandleFunc("POST /execs/forgotpassword", handlers.ForgotPasswordHandler) 23 | mux.HandleFunc("POST /execs/resetpassword/reset/{resetcode}", handlers.ResetPasswordHandler) 24 | 25 | return mux 26 | } 27 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | func MainRouter() *http.ServeMux { 8 | 9 | tRouter := teachersRouter() 10 | sRouter := studentsRouter() 11 | sRouter.Handle("/", execsRouter()) 12 | tRouter.Handle("/", sRouter) 13 | return tRouter 14 | } 15 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/router/students_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | "restapi/internal/api/handlers" 6 | ) 7 | 8 | func studentsRouter() *http.ServeMux { 9 | 10 | mux := http.NewServeMux() 11 | mux.HandleFunc("GET /students", handlers.GetStudentsHandler) 12 | mux.HandleFunc("POST /students", handlers.AddStudentHandler) 13 | mux.HandleFunc("PATCH /students", handlers.PatchStudentsHandler) 14 | mux.HandleFunc("DELETE /students", handlers.DeleteStudentsHandler) 15 | 16 | mux.HandleFunc("GET /students/{id}", handlers.GetOneStudentHandler) 17 | mux.HandleFunc("PUT /students/{id}", handlers.UpdateStudentHandler) 18 | mux.HandleFunc("PATCH /students/{id}", handlers.PatchOneStudentHandler) 19 | mux.HandleFunc("DELETE /students/{id}", handlers.DeleteOneStudentHandler) 20 | 21 | return mux 22 | } 23 | -------------------------------------------------------------------------------- /rest_api_go/internal/api/router/teachers_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | "restapi/internal/api/handlers" 6 | ) 7 | 8 | func teachersRouter() *http.ServeMux { 9 | 10 | mux := http.NewServeMux() 11 | 12 | mux.HandleFunc("GET /teachers", handlers.GetTeachersHandler) 13 | mux.HandleFunc("POST /teachers", handlers.AddTeacherHandler) 14 | mux.HandleFunc("PATCH /teachers", handlers.PatchTeachersHandler) 15 | mux.HandleFunc("DELETE /teachers", handlers.DeleteTeachersHandler) 16 | 17 | mux.HandleFunc("GET /teachers/{id}", handlers.GetOneTeacherHandler) 18 | mux.HandleFunc("PUT /teachers/{id}", handlers.UpdateTeacherHandler) 19 | mux.HandleFunc("PATCH /teachers/{id}", handlers.PatchOneTeacherHandler) 20 | mux.HandleFunc("DELETE /teachers/{id}", handlers.DeleteOneTeacherHandler) 21 | 22 | mux.HandleFunc("GET /teachers/{id}/students", handlers.GetStudentsByTeacherId) 23 | mux.HandleFunc("GET /teachers/{id}/studentcount", handlers.GetStudentCountByTeacherId) 24 | 25 | return mux 26 | 27 | } 28 | -------------------------------------------------------------------------------- /rest_api_go/internal/models/exec.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "database/sql" 4 | 5 | type Exec struct { 6 | ID int `json:"id,omitempty" db:"id,omitempty"` 7 | FirstName string `json:"first_name,omitempty" db:"first_name,omitempty"` 8 | LastName string `json:"last_name,omitempty" db:"last_name,omitempty"` 9 | Email string `json:"email,omitempty" db:"email,omitempty"` 10 | Username string `json:"username,omitempty" db:"username,omitempty"` 11 | Password string `json:"password,omitempty" db:"password,omitempty"` 12 | PasswordChangedAt sql.NullString `json:"password_changed_at,omitempty" db:"password_changed_at,omitempty"` 13 | UserCreatedAt sql.NullString `json:"user_created_at,omitempty" db:"user_created_at,omitempty"` 14 | PasswordResetToken sql.NullString `json:"password_reset_token,omitempty" db:"password_reset_token,omitempty"` 15 | PasswordTokenExpires sql.NullString `json:"password_token_expires,omitempty" db:"password_token_expires,omitempty"` 16 | InactiveStatus bool `json:"inactive_status,omitempty" db:"inactive_status,omitempty"` 17 | Role string `json:"role,omitempty" db:"role,omitempty"` 18 | } 19 | 20 | type UpdatePasswordRequest struct { 21 | CurrentPassword string `json:"current_password"` 22 | NewPassword string `json:"new_password"` 23 | } 24 | 25 | type UpdatePasswordResponse struct { 26 | Token string `json:"token"` 27 | PasswordUpdated bool `json:"password_updated"` 28 | } 29 | -------------------------------------------------------------------------------- /rest_api_go/internal/models/student.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Student struct { 4 | ID int `json:"id,omitempty" db:"id,omitempty"` 5 | FirstName string `json:"first_name,omitempty" db:"first_name,omitempty"` 6 | LastName string `json:"last_name,omitempty" db:"last_name,omitempty"` 7 | Email string `json:"email,omitempty" db:"email,omitempty"` 8 | Class string `json:"class,omitempty" db:"class,omitempty"` 9 | } 10 | -------------------------------------------------------------------------------- /rest_api_go/internal/models/teacher.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Teacher struct { 4 | ID int `json:"id,omitempty" db:"id,omitempty"` 5 | FirstName string `json:"first_name,omitempty" db:"first_name,omitempty"` 6 | LastName string `json:"last_name,omitempty" db:"last_name,omitempty"` 7 | Email string `json:"email,omitempty" db:"email,omitempty"` 8 | Class string `json:"class,omitempty" db:"class,omitempty"` 9 | Subject string `json:"subject,omitempty" db:"subject,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /rest_api_go/internal/repository/sqlconnect/sqlconfig.go: -------------------------------------------------------------------------------- 1 | package sqlconnect 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "os" 7 | 8 | _ "github.com/go-sql-driver/mysql" 9 | ) 10 | 11 | func ConnectDb() (*sql.DB, error) { 12 | // err := godotenv.Load() 13 | // if err != nil { 14 | // return nil, err 15 | // } 16 | 17 | user := os.Getenv("DB_USER") 18 | password := os.Getenv("DB_PASSWORD") 19 | dbname := os.Getenv("DB_NAME") 20 | dbport := os.Getenv("DB_PORT") 21 | host := os.Getenv("HOST") 22 | // connectionString := "root:root@tcp(127.0.0.1:3306)/" + dbname 23 | connectionString := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", user, password, host, dbport, dbname) 24 | db, err := sql.Open("mysql", connectionString) 25 | if err != nil { 26 | // panic(err) 27 | return nil, err 28 | } 29 | return db, nil 30 | } 31 | -------------------------------------------------------------------------------- /rest_api_go/pkg/utils/authorize_user.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "errors" 4 | 5 | type ContextKey string 6 | 7 | func AuthorizeUser(userRole string, allowedRoles ...string) (bool, error) { 8 | for _, allowedRole := range allowedRoles { 9 | if userRole == allowedRole { 10 | return true, nil 11 | } 12 | } 13 | 14 | return false, errors.New("user not authorized") 15 | } 16 | -------------------------------------------------------------------------------- /rest_api_go/pkg/utils/error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | func ErrorHandler(err error, message string) error { 10 | errorLogger := log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) 11 | errorLogger.Println(message, err) 12 | return fmt.Errorf(message) 13 | } 14 | -------------------------------------------------------------------------------- /rest_api_go/pkg/utils/jwt.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "time" 6 | 7 | "github.com/golang-jwt/jwt/v5" 8 | ) 9 | 10 | func SignToken(userId int, username, role string) (string, error) { 11 | jwtSecret := os.Getenv("JWT_SECRET") 12 | jwtExpiresIn := os.Getenv("JWT_EXPIRES_IN") 13 | 14 | claims := jwt.MapClaims{ 15 | "uid": userId, 16 | "user": username, 17 | "role": role, 18 | } 19 | 20 | if jwtExpiresIn != "" { 21 | duration, err := time.ParseDuration(jwtExpiresIn) 22 | if err != nil { 23 | return "", ErrorHandler(err, "Internal error") 24 | } 25 | claims["exp"] = jwt.NewNumericDate(time.Now().Add(duration)) 26 | } else { 27 | claims["exp"] = jwt.NewNumericDate(time.Now().Add(15 * time.Minute)) 28 | } 29 | 30 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 31 | 32 | signedToken, err := token.SignedString([]byte(jwtSecret)) 33 | if err != nil { 34 | return "", ErrorHandler(err, "Internal error") 35 | } 36 | 37 | return signedToken, nil 38 | } 39 | -------------------------------------------------------------------------------- /rest_api_go/pkg/utils/middlewaresutil.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "net/http" 4 | 5 | // Middleware is a function that wraps an http.Handler with additional functionality 6 | type Middleware func(http.Handler) http.Handler 7 | 8 | func ApplyMiddlewares(handler http.Handler, middlewares ...Middleware) http.Handler { 9 | for _, middleware := range middlewares { 10 | handler = middleware(handler) 11 | } 12 | return handler 13 | } 14 | -------------------------------------------------------------------------------- /rest_api_go/pkg/utils/password.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/subtle" 6 | "encoding/base64" 7 | "errors" 8 | "fmt" 9 | "strings" 10 | 11 | "golang.org/x/crypto/argon2" 12 | ) 13 | 14 | func VerifyPassword(password, encodedHash string) error { 15 | parts := strings.Split(encodedHash, ".") 16 | if len(parts) != 2 { 17 | return ErrorHandler(errors.New("invalid encoded hash format"), "internal server error") 18 | } 19 | 20 | saltBase64 := parts[0] 21 | hashedPasswordBase64 := parts[1] 22 | 23 | salt, err := base64.StdEncoding.DecodeString(saltBase64) 24 | if err != nil { 25 | return ErrorHandler(err, "internal server error") 26 | } 27 | 28 | hashedPassword, err := base64.StdEncoding.DecodeString(hashedPasswordBase64) 29 | if err != nil { 30 | return ErrorHandler(err, "internal error") 31 | } 32 | 33 | hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) 34 | 35 | if len(hash) != len(hashedPassword) { 36 | return ErrorHandler(errors.New("hash length mismatch"), "incorrect password") 37 | } 38 | 39 | if subtle.ConstantTimeCompare(hash, hashedPassword) == 1 { 40 | return nil 41 | } 42 | return ErrorHandler(errors.New("incorrect password"), "incorrect password") 43 | } 44 | 45 | func HashPassword(password string) (string, error) { 46 | if password == "" { 47 | return "", ErrorHandler(errors.New("password is blank"), "please enter password") 48 | } 49 | salt := make([]byte, 16) 50 | _, err := rand.Read(salt) 51 | if err != nil { 52 | return "", ErrorHandler(errors.New("failed to generate salt"), "internal error") 53 | } 54 | 55 | hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) 56 | saltBase64 := base64.StdEncoding.EncodeToString(salt) 57 | hashBase64 := base64.StdEncoding.EncodeToString(hash) 58 | 59 | encodedHash := fmt.Sprintf("%s.%s", saltBase64, hashBase64) 60 | return encodedHash, nil 61 | } 62 | -------------------------------------------------------------------------------- /subrouting/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | 10 | mux := http.NewServeMux() 11 | // mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { 12 | // fmt.Fprintf(w, "Root handler") 13 | // }) 14 | 15 | mux.HandleFunc("GET /users", func(w http.ResponseWriter, r *http.Request) { 16 | fmt.Fprintf(w, "Users handler") 17 | }) 18 | mux.HandleFunc("GET /items", func(w http.ResponseWriter, r *http.Request) { 19 | fmt.Fprintf(w, "Items handler") 20 | }) 21 | 22 | // "/app/users" 23 | // "/app/items" 24 | 25 | app := http.NewServeMux() 26 | app.Handle("/app/", http.StripPrefix("/app", mux)) 27 | 28 | server := http.Server{ 29 | Addr: ":8080", 30 | Handler: mux, 31 | } 32 | fmt.Println("Server started on port 8080") 33 | server.ListenAndServe() 34 | 35 | } 36 | --------------------------------------------------------------------------------