├── 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 |
--------------------------------------------------------------------------------