یک هکر کلاهسفید قصد دارد سایتهای مختلف برای برای آسیبپذیری [Log4jShell](https://thehackernews.com/2021/12/apache-log4j-vulnerability-log4shell.html) بررسی کند. همانطور که میدانید، این یک آسیبپذیری از نوع *RCE* است و میتواند بسیار مخرب باشد؛ بنابراین باید به سرعت تشخیص داده شود.
این هکر برای بررسی یک سایت، باید تمام مسیرهای ممکن آن را بررسی کند. برای این که از روی آدرس سایت تمام مسیرهای آن را پیدا کند، از [*HATEOAS*](https://en.wikipedia.org/wiki/HATEOAS) استفاده میکند (فرض کنیم همهی سایتها *HATEOAS* دارند).
# جزئیات پروژه
پروژهی اولیه را از [این لینک](/problemset/assignments/4367/download_problem_initial_project/126109/) دانلود کنید. ساختار فایلهای پروژه بهصورت زیر است:
```
log4j
├── go.mod
├── go.sum
├── main.go
├── main_sample_test.go
└── utils.go
```
هکر تاکنون یک تابع `Retrieve` در فایل `utils.go` نوشته که با دریافت آدرس یک مسیر، مسیرهای دیگری که از این مسیر امکان رفتن بهصورت **مستقیم** دارند را به او میدهد. مثلاً به ازای ورودی `snapp.ir/`، آدرسهای زیر را برمیگرداند:
+ `snapp.ir/blog`
+ `snapp.ir/contact`
+ `snapp.ir/about`
و به ازای ورودی `snapp.ir/blog`، آدرس های زیر را برمیگرداند:
+ `snapp.ir/blog/post1`
+ `snapp.ir/blog/post2`
نسخهی اصلی این تابع که هکر پیادهسازی کرده، به آدرس موردنظر درخواست *HTTP* ارسال میکند و نتیجه را پردازش کرده و لینک مسیرها را استخراج گرده و برمیگرداند. همانطور که حدس میزنید، هر بار اجرای این تابع با توجه به این که از شبکه استفاده میکند تا به سرور دسترسی پیدا کند، بسیار زمانبر است.
علاوه بر تابع `Retrieve`، یک تابع به نام `Hack` نوشته که قرار است به شکل بازگشتی، از ریشهی یک سایت شروع کرده و تمام مسیرهایی که به شکل مستقیم یا غیرمستقیم میتوان به آنها رسید را پیدا کند (به شکل بدون ترتیب). پیادهسازی اولیهای نیز از این تابع در اختیار ما قرار گرفته، اما متأسفانه با توجه به کندی تابع `Retrieve`، بسیار کند است.
```go
package main
func Hack(start string) []string {
finalResult := []string{}
tempResult := Retrieve(start)
finalResult = append(finalResult, tempResult...)
for _, v := range tempResult {
finalResult = append(finalResult, Hack(v)...)
}
return finalResult
}
```
هکر کلاهسفید از شما خواسته تا بدون تغییر عملکرد و امضا، تابع `Hack` را برایش سریعتر کنید. با توجه به این که تابع `Retrieve` تابع ایمنی در مقابل همروندی است، میخواهیم از امکانات همروندی *Go* استفاده کنیم تا زمان اجرای تابع `Hack` کمینه شود.
# نکات
+ در این سؤال حق استفاده از پکیج `runtime` زبان *Go* را ندارید.
+ داوری این سؤال ممکن است اندکی بیشتر از سایر سؤالات طول بکشد.
+ تابع `Retrieve` را در فایل ارسالی قرار ندهید.
+ شما تنها مجاز به اعمال تغییرات در فایل `main.go` هستید.
+ در صورت نیاز، میتوانید توابع دیگری نیز در فایل `main.go` تعریف کنید.
# آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، فایل `main.go` را آپلود کنید.