<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های mrbardia72</title>
        <link>https://virgool.io/feed/@bardiiia</link>
        <description>Go Developer(gopher-academy.ir)</description>
        <language>fa</language>
        <pubDate>2026-04-15 04:41:13</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/28542/avatar/i6rDJp.png?height=120&amp;width=120</url>
            <title>mrbardia72</title>
            <link>https://virgool.io/@bardiiia</link>
        </image>

                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@bardiiia/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7%DB%8C-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B9-ugp8kmgkqwav</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/sete98ngf7ii-35QeW.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۱۵,۹۷۱ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۲۱۳ مرتبه پسندیدند و  ۱۰ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۴۹ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۱,۵۸۸ بار خوانده شدند و ۴۹۸,۵۹۲ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۶۸۳۵۶۴۶ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۹,۴۷۳ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۶۸۳۵۶۴۶ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Thu, 25 Mar 2021 11:55:05 +0430</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 9</title>
                <link>https://virgool.io/CodeLovers/gin-web-framework-part-9-f5aonzltgk4b</link>
                <description>Gin Web Framework part 9درود دوستان امروز میخوام در مورد بخش هشتم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش هشتم از این مقالهRun multiple service using GinGraceful shutdown or restartBuild a single binary with templatesBind form-data request with custom structTry to bind body into different structshttp2 server pushDefine format for the log of routesSet and get a cookieTestingمیریم واسه توضیح هر بخشقسمت اول Run multiple service using Ginاگه چندتا سرویس داشته باشید به صورت زیر باید عمل کند. توضیحات در ادامه این کدpackage main

import (
	&amp;quotlog&amp;quot
	&amp;quotnet/http&amp;quot
	&amp;quottime&amp;quot
	&amp;quotgithub.com/gin-gonic/gin&amp;quot
	&amp;quotgolang.org/x/sync/errgroup&amp;quot
)

var (
	g errgroup.Group
)

func r01() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET(&amp;quot/&amp;quot, func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				&amp;quotcode&amp;quot:  http.StatusOK,
				&amp;quoterror&amp;quot: &amp;quotWelcome server 01&amp;quot,
			},
		)
	})
	return e
}

func r02() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET(&amp;quot/&amp;quot, func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				&amp;quotcode&amp;quot:  http.StatusOK,
				&amp;quoterror&amp;quot: &amp;quotWelcome server 02&amp;quot,
			},
		)
	})
	return e
}

func main() {
	server01 := &amp;http.Server{
		Addr:         &amp;quot:8080&amp;quot,
		Handler:      r01(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	server02 := &amp;http.Server{
		Addr:         &amp;quot:8081&amp;quot,
		Handler:      r02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	g.Go(func() error {
		err := server01.ListenAndServe()
		if err != nil &amp;&amp; err != http.ErrServerClosed {
			log.Fatal(err)
		}
		return err
	})

	g.Go(func() error {
		err := server02.ListenAndServe()
		if err != nil &amp;&amp; err != http.ErrServerClosed {
			log.Fatal(err)
		}
		return err
	})

	if err := g.Wait(); err != nil {
		log.Fatal(err)
	}
}اول از همه برای اجرا کردن چندین سرویس باید از کتابحانه x/sync/errgroup استفاده کرد که توی خط ۱۲ اومدیم یه نمونه ازش ساختیم. بعدش اومدیم دوتا روت تعریف کردیم به اسم های r01  و  r02  توی تابع اصلی اومدیم برای هرکدومشون یه پورت جداگانه درنظر گرفتیم و بعدش در همین تابع اصلی با استفاده از کتابخانه ای که در این فایل تعریف کردیم یعنی x/sync/errgroup اومدیم تابعی به این صورت g.Go(func() error  تعریف کردیم از نمونه ای که از این کتابخانه توی خط ۱۲ تعریف کرده بودیم توی بتن این تابع اومدیم نوع سرویس های که شخصی کردیم رو بهش پاس میدیم جهت اجرا شدنقسمت دوم Graceful shutdown or restartچگونه سیگنال‌های ورودی سیستم عامل را برای انجام graceful shutdown در یک وب سرور نوشته‌می‌شوند و ما آن‌ها را به زبان Go مدیریت کنیم.واسه توضیحات بیشتر این مقاله ویرگولی رو بخونید.چندتا کتابخونه توی این زمینه هستن که عبارتنداز:manners: A polite Go HTTP server that shuts down gracefully.graceful: Graceful is a Go package enabling graceful shutdown of an http.Handler server.grace: Graceful restart &amp; zero downtime deploy for Go servers.endless: Zero downtime restarts for go servers (Drop in replacement for http.ListenAndServe)قسمت سوم Build a single binary with templatesواسه اینکه بخواید از فایل html خود یه فایل باینری بسازید کافیه مراحل زیر رو به ترتیب برید. برای اطلاعات بیشتر و همچنین یه مثال ساده به این لینک یه سری بزنیدPrepare Packagesgo get github.com/gin-gonic/gin
go get github.com/jessevdk/go-assets-builderGenerate assets.gogo-assets-builder html -o assets.goBuild the servergo build -o assets-in-binaryRun./assets-in-binaryقسمت چهارم Bind form-data request with custom structاگه بخواید استراکچر خودتون رو بسازید به صورت زیر می تونید استراکچر شخصی برای اطلاعات بسازید کد زیر دیگه واضح هست انتظار دارم  دیگه اینو بلد باشیدtype StructA struct {
    FieldA string `form:&amp;quotfield_a&amp;quot`
}

type StructB struct {
    NestedStruct StructA
    FieldB string `form:&amp;quotfield_b&amp;quot`
}

type StructC struct {
    NestedStructPointer *StructA
    FieldC string `form:&amp;quotfield_c&amp;quot`
}

type StructD struct {
    NestedAnonyStruct struct {
        FieldX string `form:&amp;quotfield_x&amp;quot`
    }
    FieldD string `form:&amp;quotfield_d&amp;quot`
}

func GetDataB(c *gin.Context) {
    var b StructB
    c.Bind(&amp;b)
    c.JSON(200, gin.H{
        &amp;quota&amp;quot: b.NestedStruct,
        &amp;quotb&amp;quot: b.FieldB,
    })
}

func GetDataC(c *gin.Context) {
    var b StructC
    c.Bind(&amp;b)
    c.JSON(200, gin.H{
        &amp;quota&amp;quot: b.NestedStructPointer,
        &amp;quotc&amp;quot: b.FieldC,
    })
}

func GetDataD(c *gin.Context) {
    var b StructD
    c.Bind(&amp;b)
    c.JSON(200, gin.H{
        &amp;quotx&amp;quot: b.NestedAnonyStruct,
        &amp;quotd&amp;quot: b.FieldD,
    })
}

func main() {
    r := gin.Default()
    r.GET(&amp;quot/getb&amp;quot, GetDataB)
    r.GET(&amp;quot/getc&amp;quot, GetDataC)
    r.GET(&amp;quot/getd&amp;quot, GetDataD)

    r.Run()
}نحوه اجرا:$ curl &amp;quothttp://localhost:8080/getb?field_a=hello&amp;field_b=world&amp;quot
{&amp;quota&amp;quot:{&amp;quotFieldA&amp;quot:&amp;quothello&amp;quot},&amp;quotb&amp;quot:&amp;quotworld&amp;quot}

$ curl &amp;quothttp://localhost:8080/getc?field_a=hello&amp;field_c=world&amp;quot
{&amp;quota&amp;quot:{&amp;quotFieldA&amp;quot:&amp;quothello&amp;quot},&amp;quotc&amp;quot:&amp;quotworld&amp;quot}

$ curl &amp;quothttp://localhost:8080/getd?field_x=hello&amp;field_d=world&amp;quot
{&amp;quotd&amp;quot:&amp;quotworld&amp;quot,&amp;quotx&amp;quot:{&amp;quotFieldX&amp;quot:&amp;quothello&amp;quot}}قسمت پنجم Try to bind body into different structsفرض کنید یه استراکچر دارید که تایپ های مختلف برای ارسال رو پوشش میده و میخواید هم از json و هم از xml اون استراکچر استفاده کنید. برای این کار از متد c.ShouldBindBodyWith استفاده می کنیمبه صورت کد زیر:type formA struct {
  Foo string `json:&amp;quotfoo&amp;quot xml:&amp;quotfoo&amp;quot binding:&amp;quotrequired&amp;quot`
}

type formB struct {
  Bar string `json:&amp;quotbar&amp;quot xml:&amp;quotbar&amp;quot binding:&amp;quotrequired&amp;quot`
} 
func SomeHandler(c *gin.Context) {
  objA := formA{}
  objB := formB{}

  if errA := c.ShouldBindBodyWith(&amp;objA, binding.JSON); errA == nil {
    c.String(http.StatusOK, `the body should be formA`)

  } else if errB := c.ShouldBindBodyWith(&amp;objB, binding.JSON); errB == nil {
    c.String(http.StatusOK, `the body should be formB JSON`)

  } else if errB2 := c.ShouldBindBodyWith(&amp;objB, binding.XML); errB2 == nil {
    c.String(http.StatusOK, `the body should be formB XML`)
  } else {
    // TODO : YOUR CODE
  }
}قسمت شیشم http2 server pushاین روش در واقع طراحی شده http2 هست که در شکل زیر نماینگر این ارتباط از نوع  http2 هستhttps://blog.golang.org/h2pushدر شکل این توضبح دیگه خیلی واضح هست پس من توضیح نمیدم میرم سر اصل قضیهاینم نمونه کد:package main

import (
	&amp;quothtml/template&amp;quot
	&amp;quotlog&amp;quot
	&amp;quotgithub.com/gin-gonic/gin&amp;quot
)

var html = template.Must(template.New(&amp;quothttps&amp;quot).Parse(`
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Https Test&lt;/title&gt;
  &lt;script src=&amp;quot/assets/app.js&amp;quot&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1 style=&amp;quotcolor:red;&amp;quot&gt;Welcome, Ginner!&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
`))

func main() {
	r := gin.Default()
	r.Static(&amp;quot/assets&amp;quot, &amp;quot./assets&amp;quot)
	r.SetHTMLTemplate(html)
	r.GET(&amp;quot/&amp;quot, func(c *gin.Context) {
		if pusher := c.Writer.Pusher(); pusher != nil {
			if err := pusher.Push(&amp;quot/assets/app.js&amp;quot, nil); err != nil {
				log.Printf(&amp;quotFailed to push: %v&amp;quot, err)
			}
		}
		c.HTML(200, &amp;quothttps&amp;quot, gin.H{
			&amp;quotstatus&amp;quot: &amp;quotsuccess&amp;quot,
		})
	})
	r.RunTLS(&amp;quot:8080&amp;quot, &amp;quot./testdata/server.pem&amp;quot, &amp;quot./testdata/server.key&amp;quot)
}برای استفاده از چنین قابلیتی از متد c.Writer.Pusher استفاده می کنیم اگه به شکل نگاه کنید می فهمید نخوه ارتباط با اجزای مختلف یه سایت که چگونه اونا رو برای کاربر نمایش میده یعنی با یه req ما می تونیم از سمت سرور چندین res رو داشته باشیم.قسمت هفتم Define format for the log of routesبرای اینکه بتونیم یه لاگ اختصاصی از عملکرد سرویس هامون داشته باشیم یعنی زمانی که اجرا می کنید توی کنسول چنین چیزی داشته باشید[GIN-debug] POST   /foo            --&gt; main.main.func1 (3 handlers)[GIN-debug] GET    /bar             --&gt; main.main.func2 (3 handlers)[GIN-debug] GET    /status          --&gt; main.main.func3 (3 handlers)باید از متد gin.DebugPrintRouteFunc استفاده کنیم که توی کد زیر نشون دادیمimport (
	&amp;quotlog&amp;quot
	&amp;quotnet/http&amp;quot
	&amp;quotgithub.com/gin-gonic/gin&amp;quot
)

func main() {
	r := gin.Default()
	gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
		log.Printf(&amp;quotendpoint %v %v %v %v\n&amp;quot, httpMethod, absolutePath, handlerName, nuHandlers)
	}

	r.POST(&amp;quot/foo&amp;quot, func(c *gin.Context) {
		c.JSON(http.StatusOK, &amp;quotfoo&amp;quot)
	})

	r.GET(&amp;quot/bar&amp;quot, func(c *gin.Context) {
		c.JSON(http.StatusOK, &amp;quotbar&amp;quot)
	})

	r.GET(&amp;quot/status&amp;quot, func(c *gin.Context) {
		c.JSON(http.StatusOK, &amp;quotok&amp;quot)
	})

	// Listen and Server in http://0.0.0.0:8080
	r.Run()
}قسمت هشتم Set and get a cookieنحوه ست کردن و دریافت کوگیimport (
    &amp;quotfmt&amp;quot
    &amp;quotgithub.com/gin-gonic/gin&amp;quot
)

func main() {

    router := gin.Default()
    router.GET(&amp;quot/cookie&amp;quot, func(c *gin.Context) {
        cookie, err := c.Cookie(&amp;quotgin_cookie&amp;quot)
        if err != nil {
            cookie = &amp;quotNotSet&amp;quot
            c.SetCookie(&amp;quotgin_cookie&amp;quot, &amp;quottest&amp;quot, 3600, &amp;quot/&amp;quot, &amp;quotlocalhost&amp;quot, false, true)
        }
        fmt.Printf(&amp;quotCookie value: %s \n&amp;quot, cookie)
    })
    router.Run()
}برای ست کردن کوکی در خط ۱۰ ما یه کوکی تعریف کردیم و بهش یه نام اختصاص دادیم توی خط ۱۲ یع مقدار بهش دادیم و توی ۱۳ اومدیم گفتیم که این کوکی رو توی این آدرس و توی این پورت ست کنپایان اموزش فرم ورک gin اگه سوالی داشتید زیر هر پست برامون کامنت کنید</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sat, 26 Dec 2020 10:36:20 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 8</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-8-zw0dohvafo0b</link>
                <description>Gin Web Framework part 8درود دوستان امروز میخوام در مورد بخش هشتم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش هشتم از این مقالهMultitemplateRedirectsCustom MiddlewareUsing BasicAuth() middlewareGoroutines inside a middlewareCustom HTTP configurationSupport Let&#x27;s Encryptمیریم واسه توضیح هر بخشقسمت اول Multitemplateاین فرم ورک به طور پیش فرض از html.Template استفاده می کند و همچنین می توانید از multitemplate render هم استفاده کنید که یک  رندر HTML سفارشی برای پشتیبانی از چند الگو است.قسمت دوم Redirectsبرای ریدایرکت کردن مورد استفاده قرار می گیره به صورت زیرr.GET(&amp;quot/test&amp;quot, func(c *gin.Context) {
	c.Redirect(http.StatusMovedPermanently, &amp;quothttp://www.google.com/&amp;quot)
})برای استفاده از این خاصیت از متد c.rediectاستفاده می کنیمr.POST(&amp;quot/test&amp;quot, func(c *gin.Context) {
	c.Redirect(http.StatusFound, &amp;quot/foo&amp;quot)
})قسمت سوم Custom Middlewareواسه دورس کردن یک میدلوریر سفارشی به صورت زیر عمل می کنیم. این کد رو در نظر بگیریدfunc MyLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()

		// Set example variable
		c.Set(&amp;quotexample&amp;quot, &amp;quot12345&amp;quot)

		// before request
		c.Next()

		// after request
		latency := time.Since(t)
		log.Print(latency)

		// access the status we are sending
		status := c.Writer.Status()
		log.Println(status)
	}
}

func main() {
	r := gin.New()
	r.Use(MyLogger())
	r.GET(&amp;quot/test&amp;quot, func(c *gin.Context) {
		example := c.MustGet(&amp;quotexample&amp;quot).(string)
		// it would print: &amp;quot12345&amp;quot
		log.Println(example)
	})
	r.Run(&amp;quot:8080&amp;quot)
}ما در اینجا یه متد تعریف کردیم به mylogger  که کار خاصی انجام نمیده فقط یه عدد از نوع رشته رو برامون چاپ می کنه ما توی خط ۶ یه متغییر از نوع رشته تعریف کردیم با مقدار ۱۲۳۴۵ و اون مقدار رو توی تابع اصلی خط ۲۵ با متد mustget اون مقدار رو دریافت و چاپ می کندقسمت چهارم Using BasicAuth() middlewareنحوه استفاده از basicauth   var secrets = gin.H{
	&amp;quotbardia&amp;quot:    gin.H{&amp;quotemail&amp;quot: &amp;quotbardia@iran.new&amp;quot, &amp;quotphone&amp;quot: &amp;quot123456&amp;quot},
	&amp;quoterfan&amp;quot: gin.H{&amp;quotemail&amp;quot: &amp;quoterfan@iran.new&amp;quot, &amp;quotphone&amp;quot: &amp;quot654321&amp;quot},
	&amp;quotomid&amp;quot:   gin.H{&amp;quotemail&amp;quot: &amp;quotomid@iran.new&amp;quot, &amp;quotphone&amp;quot: &amp;quot123654&amp;quot},
}

func main() {
	r := gin.Default()
	authorized := r.Group(&amp;quot/admin&amp;quot, gin.BasicAuth(gin.Accounts{
		&amp;quotbardia&amp;quot:    &amp;quotbardia34&amp;quot,
		&amp;quoterfan&amp;quot: &amp;quoterfan1234&amp;quot,
		&amp;quotomid&amp;quot:   &amp;quothello2&amp;quot,
	}))

	authorized.GET(&amp;quot/secrets&amp;quot, func(c *gin.Context) {
		user := c.MustGet(gin.AuthUserKey).(string)
		if secret, ok := secrets[user]; ok {
			c.JSON(http.StatusOK, gin.H{&amp;quotuser&amp;quot: user, &amp;quotsecret&amp;quot: secret})
		} else {
			c.JSON(http.StatusOK, gin.H{&amp;quotuser&amp;quot: user, &amp;quotsecret&amp;quot: &amp;quotNO SECRET :(&amp;quot})
		}
	})
	r.Run(&amp;quot:8080&amp;quot)
}خوب ما اومدیم توی خط اول یه سری داده ایجاد کردیم نحوه ایجاد یه سری داده در فرم ورک جین به این صورت هست. خوب بعدش توی خط هشت اومدبم گفتیم هر اندپونتی که از طرف admin بیاد رو اعتبارسنجی کن ببین اون کاربرهای که توی خط اول تعریف کردیم هست یا نه که این چو کردن رو توی خط ۱۶ انجام میده در صورت بودن اون کاربر توی لیست مدنظر ما که توی خط اول هست اجازه ورود به بخش secrets رو داره توی خط نه تابع gin.basicaurh کارش همون ساخت یک mapهست همون کار map رو می کنهقسمت پنجم Goroutines inside a middlewareدو روش تعریف گورتینگ به صورت سنکرون و آسنکرون برای این کار هست. کافیه که ما از متد copy که توی خط چهار می باشد استفاده کنیم این روش میاد یک کپی فقط خواندنی ازش(همون url) ایجاد می کنه براخلاف اون چیزی هست که توی خط ۱۳ تعریف کردیم یعنی برای استفاده از c.request.url.path میاد به صورت ccp.request.url.path استفاده می کند. در اون قسمت c.request.url.path  میاد از contextاستفاده می مند برای بدست آوردن آدرسfunc main() {
	r := gin.Default()
	r.GET(&amp;quot/long_async&amp;quot, func(c *gin.Context) {
		cCp := c.Copy()
		go func() {
			time.Sleep(5 * time.Second)
			log.Println(&amp;quotDone! in path &amp;quot + cCp.Request.URL.Path)
		}()
	})

	r.GET(&amp;quot/long_sync&amp;quot, func(c *gin.Context) {
		time.Sleep(5 * time.Second)
		log.Println(&amp;quotDone! in path &amp;quot + c.Request.URL.Path)
	})
	r.Run(&amp;quot:8080&amp;quot)
}قسمت ششم Custom HTTP configurationنحوه استفاده از  http.listenandserveدر حالت عادی به صورت زیر func main() {
	router := gin.Default()
	http.ListenAndServe(&amp;quot:8080&amp;quot, router)
}اما برای شخصی سازی بیشتر به صورت زیر عمل کنیدfunc main() {
	router := gin.Default()

	s := &amp;http.Server{
		Addr:           &amp;quot:8080&amp;quot,
		Handler:        router,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 &lt;&lt; 20,
	}
	s.ListenAndServe()
}قسمت هفتم Support Let&#x27;s Encryptنحوه ارتباط با پروتکل https با استفاده از کتابخانه autolts در خط چهار و نحوه استغاده ازش توی خط ۱۳ ذکر شدهpackage main
import (
	&amp;quotlog&amp;quot
	&amp;quotgithub.com/gin-gonic/autotls&amp;quot
	&amp;quotgithub.com/gin-gonic/gin&amp;quot
)

func main() {
	r := gin.Default()
	r.GET(&amp;quot/ping&amp;quot, func(c *gin.Context) {
		c.String(200, &amp;quotpong&amp;quot)
	})
	log.Fatal(autotls.Run(r, &amp;quotexample1.com&amp;quot, &amp;quotexample2.com&amp;quot))
}نحوه شخصی سازی هم به صورت زیر در خط ۱۵package main
import (
	&amp;quotlog&amp;quot
	&amp;quotgithub.com/gin-gonic/autotls&amp;quot
	&amp;quotgithub.com/gin-gonic/gin&amp;quot
	&amp;quotgolang.org/x/crypto/acme/autocert&amp;quot
)

func main() {
	r := gin.Default()
	r.GET(&amp;quot/ping&amp;quot, func(c *gin.Context) {
		c.String(200, &amp;quotpong&amp;quot)
	})

	m := autocert.Manager{
		Prompt:     autocert.AcceptTOS,
		HostPolicy: autocert.HostWhitelist(&amp;quotexample1.com&amp;quot, &amp;quotexample2.com&amp;quot),
		Cache:      autocert.DirCache(&amp;quot/var/www/.cache&amp;quot),
	}
	log.Fatal(autotls.RunWithManager(r, &amp;m))
}</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Mon, 21 Dec 2020 13:03:02 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 7</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-7-whmbyucdxbqs</link>
                <description>Gin Web Framework part 7درود دوستان امروز میخوام در مورد بخش هقتم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش هقتم از این مقالهServing static filesServing static filesServing data from fileServing data from readerHTML renderingCustom Template rendererCustom Template Funcsمیریم واسه توضیح هر بخشقسمت اول Serving static filesبه کد های زیر دقت کنیدr.Static(&amp;quot/assets&amp;quot, &amp;quot./assets&amp;quot)
r.StaricFS(&amp;quot/more_static&amp;quot, http.Dir(&amp;quotmy_file_system&amp;quot))
 r.StaticFile&#40;&amp;quot/favicon.ico&amp;quot, &amp;quot./resources/favicon.ico&amp;quot&#41;خط اول تابع static مسیر یا روت اصلی رو برامون براگذاری میکنه به قول معروف فایل رو از ریشه برامون بارگذاری می کندخط دوم تابع staticfs مسیر های دیگه ای که اگه نیاز داریم رو برامون بارگذاری می کنهخط سوم تابع staticfile برای بارگذاری فایل خاصی از مسیر خاصی می باشد.قسمت دوم Serving data from filefunc main() {
	router := gin.Default()
	router.GET(&amp;quot/local/file&amp;quot, func(c *gin.Context) {
		c.File&#40;&amp;quotlocal/file.go&amp;quot&#41;
	})
	var fs http.FileSystem = // ...
	router.GET(&amp;quot/fs/file&amp;quot, func(c *gin.Context) {
		c.FileFromFS(&amp;quotfs/file.go&amp;quot, fs)
	})
}توی خط چهارم اگر به فایلی که توی ریشه هست رو بخواهیم بفرستم باید از تابع c.file استفاده کنیمتوی خط هشت اگر ما بخوایم یه فایلی رو از یه آدرس مشخص که توی خط شیش ذکر کردیم بفرستم به روتی که توی خط هفت تعریف کردیم از این تابع filefromfs استفاده می کنیمقسمت سوم Serving data from readerfunc main() {
	router := gin.Default()
	router.GET(&amp;quot/someDataFromReader&amp;quot, func(c *gin.Context) {
		response, err := http.Get(&amp;quothttps://raw.githubusercontent.com/gin-gonic/logo/master/color.png&amp;quot)
		if err != nil || response.StatusCode != http.StatusOK {
			c.Status(http.StatusServiceUnavailable)
			return
		}
		reader := response.Body
 		defer reader.Close()
		contentLength := response.ContentLength
		contentType := response.Header.Get(&amp;quotContent-Type&amp;quot)
		extraHeaders := map[string]string{
			&amp;quotContent-Disposition&amp;quot: `attachment; filename=&amp;quotgopher.png&amp;quot`,
		}
		c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
	})
	router.Run(&amp;quot:8080&amp;quot)
}اگر بخوایم یه سری اطلاعات رو توی هدر بنویسیم از متدی که در خط ۱۷ هست رو تعریف می کنیم شمای این متد به صورت زیر هستfunc (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) { 
c.Render(code, render.Reader{
 Headers:       extraHeaders, 
ContentType:   contentType, 
ContentLength: contentLength, 
Reader:        reader,	
})
}قسمت چهارم HTML renderingبه کدهای زیر توجه کنید در ادامه توضیح خواهم دادfunc main() {
	router := gin.Default()
	router.LoadHTMLGlob(&amp;quottemplates/**/*&amp;quot)
	router.GET(&amp;quot/posts/index&amp;quot, func(c *gin.Context) {
		c.HTML(http.StatusOK, &amp;quotposts/index.tmpl&amp;quot, gin.H{
			&amp;quottitle&amp;quot: &amp;quotPosts&amp;quot,
		})
	})
	router.GET(&amp;quot/users/index&amp;quot, func(c *gin.Context) {
		c.HTML(http.StatusOK, &amp;quotusers/index.tmpl&amp;quot, gin.H{
			&amp;quottitle&amp;quot: &amp;quotUsers&amp;quot,
		})
	})
	router.Run(&amp;quot:8080&amp;quot)
}خط سوم تابع loadhtmlglob مسیر فایل های tmpl و نشون میدهtemplates/posts/index.tmpl{{ define &amp;quotposts/index.tmpl&amp;quot }}
&lt;html&gt;&lt;h1&gt;
	{{ .title }}
&lt;/h1&gt;
&lt;p&gt;Using posts/index.tmpl&lt;/p&gt;
&lt;/html&gt;
{{ end }}templates/users/index.tmpl{{ define &amp;quotusers/index.tmpl&amp;quot }}
&lt;html&gt;&lt;h1&gt;
	{{ .title }}
&lt;/h1&gt;
&lt;p&gt;Using users/index.tmpl&lt;/p&gt;
&lt;/html&gt;
{{ end }}خط ۵ و ۱۰ فایل مدنظر ما رو نمایش میده با استفاده از متد c.html و ۶ و ۱۱ ما یه رشته رو داریم میفرستیم داخل اون tmpl های خودمون و برای نمایش اون مقدار داخل فایل tmpl باید از {{.namefiled}} استفاده کنیمقسمت پنجم Custom Template rendererهمچنین می توانید از کتابخانه &quot;html/template&quot; به صورت زیر استفاده کنیدimport &amp;quothtml/template&amp;quot
func main() {
	router := gin.Default()
	html := template.Must(template.ParseFiles(&amp;quotfile1&amp;quot, &amp;quotfile2&amp;quot))
	router.SetHTMLTemplate(html)
	router.Run(&amp;quot:8080&amp;quot)
}قسمت شیشم Custom Template Funcsاگر بخوایم نوع فرمت نمایش توی خروجی رو سفارشی کنیم به صورت زیر یعنی فرض کنید که یه تاریخ زمانی دارید ولی فقط میخواید تاریخ رو نشون بدیدmain.goimport (
    &amp;quotfmt&amp;quot
    &amp;quothtml/template&amp;quot
    &amp;quotnet/http&amp;quot
    &amp;quottime&amp;quot

    &amp;quotgithub.com/gin-gonic/gin&amp;quot
)

func formatAsDate(t time.Time) string {
    year, month, day := t.Date()
    return fmt.Sprintf(&amp;quot%d d/ d&amp;quot, year, month, day)
}

func main() {
    router := gin.Default()
    router.Delims(&amp;quot{[{&amp;quot, &amp;quot}]}&amp;quot)
    router.SetFuncMap(template.FuncMap{
        &amp;quotformatAsDate&amp;quot: formatAsDate,
    })
    router.LoadHTMLFiles(&amp;quot./testdata/template/raw.tmpl&amp;quot)

    router.GET(&amp;quot/raw&amp;quot, func(c *gin.Context) {
        c.HTML(http.StatusOK, &amp;quotraw.tmpl&amp;quot, gin.H{
            &amp;quotnow&amp;quot: time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
        })
    })

    router.Run(&amp;quot:8080&amp;quot)
}raw.tmplDate: {[{.now | formatAsDate}]}Result:Date: 2017/07/01</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sun, 20 Dec 2020 11:13:04 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 6</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-6-iblmkeucpkj6</link>
                <description>Gin Web Framework part 6درود دوستان امروز میخوام در مورد بخش شیش از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش شیش از این مقالهBind HeaderProtoBuf renderingSecureJSONJSONPAsciiJSONPureJSONمیریم واسه توضیح هر بخشقسمت اول Bind Headerدر این روش زمانی که شما می خواید داده ای رو به هدر خود اضافه کنید از این روش استفاده می کنید. به تکه کد زیر توجه کنیدtype testHeader struct { 
Rate int `header:&amp;quotRate&amp;quot` 
Domain string `header:&amp;quotDomain&amp;quot` 
} 
func main() { 
r := gin.Default() 
r.GET(&amp;quot/&amp;quot, func(c *gin.Context) { 
h := testHeader{}
 if err := c.ShouldBindHeader(&amp;h); err != nil { 
c.JSON(200, err)
 } 
fmt.Printf(&amp;quot%#v\n&amp;quot, h)
 c.JSON(200, gin.H{&amp;quotRate&amp;quot: h.Rate, &amp;quotDomain&amp;quot: h.Domain})
 })توی خط اول ما یه struct تعریف کردیم و روبه روی هر فیلد از واژه header استغاده کردیم چون میخوام این فیلد ها رو توی هدر استفاده کنیم.توی خط ۹ ما از تابع ShouldBindHeader استفاده می کنیم جهت بررسی هدر مون که توی struct تعریف کردیمتست و خروجی: curl -H &quot;rate:300&quot; -H &quot;domain:music&quot; 127.0.0.1:8080/ output {&quot;Domain&quot;:&quot;music&quot;,&quot;Rate&quot;:300}قسمت دوم  ProtoBuf renderingتوی این قسمت با یه ساختار دیگه به نام protobuf آشنا میشیم و نحوه کارش توی این فرم ورک خوب اگه در مورد این ساختار داده ای جدید چیزی نمی دونید باید بگم (البته ساده میگم بعد خودتون برید در موردش بخونید) یک ساختار داده ای هست که تمام داده های شما رو تبدیل به باینری می کندنمونه کدr.GET(&amp;quot/someProtoBuf&amp;quot, func(c *gin.Context) 
{ 
reps := []int64{int64(1), int64(2)}
label := &amp;quotgopher&amp;quot 
data := &amp;protoexample.Test{ 
Label: &amp;label, 
Reps: reps, 
} 
c.ProtoBuf(http.StatusOK, data) 
})همانطور که مشاهد می کنید ما برای کار با این ساختار از تابعی به نام protobuf که در خط ۹ می باشد استفاده می کنیم.قسمت سوم SecureJSONاستفاده از SecureJSON برای جلوگیری از json hijackingاگر ساختار داده ای ما آرایه باشد ، پیش فرض &quot;while (1)&quot; را به بدن پاسخ اضافه می کند.به کد زیر دقت کنیدfunc main() { 
r := gin.Default()
 r.SecureJsonPrefix(&amp;quot)]}&#039;,\n&amp;quot) 
r.GET(&amp;quot/someJSON&amp;quot, func(c *gin.Context) { 
names := []string{&amp;quotbardia&amp;quot, &amp;quotkazemi&amp;quot, &amp;quotgolang&amp;quot} 
c.SecureJSON(http.StatusOK, names)
 }
)}ما برای این کار از SecureJsonPrefix که در خط ۳ هست استفاده کردیمخروجی به صورت زیرwhile(1);[&quot;bardia&quot;,&quot;kazemi&quot;,&quot;golang&quot;]قسمت چهارم JSONPدر واقع JSONP (مخفف JSON with Padding – به معنی JSON به همراه padding) متدی برای ارسال داده های JSON است که مشکلات بین-دامنه ای را حل می کند.به تکه کد زیر دقت کنید:r.GET(&amp;quot/JSONP&amp;quot, func(c *gin.Context) { 
data := gin.H{ &amp;quotbardia&amp;quot: &amp;quotkazemi&amp;quot, }
 c.JSONP(http.StatusOK, data) 
}) 
}خروجی به صورت زیرcurl http://127.0.0.1:8080/JSONP?callback=golang golang({\&quot;bardia\&quot;:\&quot;kazemi\&quot;})orcurl http://127.0.0.1:8080/JSONP?callback=cplusplus  cplusplus({\&quot;erfan\&quot;:\&quot;kazemi\&quot;})توی خط ۳ ما از jsonp برای این کار استغاده کردیم. که خروجی گویای تعریف jsonp می باشد.قسمت چهارم AsciiJSONبا استفاده از AsciiJSON ما می توانیم کارکتر های که کد اسکی ندارند رو تو خروجی چاپ و استغاده کنیمکد زیرr.GET(&quot;/someJSON&quot;, func(c *gin.Context) { data := gin.H{ &quot;lang&quot;: &quot;GO语言&quot;, &quot;persian&quot;:&quot;کوروش کبیر&quot;&quot;tag&quot;: &quot;&lt;br&gt;&quot;, }قسمت پنجم PureJSONرمز نگاری کارکتری های خاص به کارکترهای بامعنی جهت استفاده در سند های html به صورت زیرکد:r.GET(&amp;quot/purejson&amp;quot, func(c *gin.Context) { 
c.PureJSON(200, gin.H{ &amp;quothtml&amp;quot: &amp;quot&lt;b&gt;Hello, gopher academy!&lt;/b&gt;&amp;quot, })
 })</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sun, 13 Dec 2020 12:03:06 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 5</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-5-r45puocd0prn</link>
                <description>Gin Web Framework part 5درود دوستان امروز میخوام در مورد بخش پنجم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش پنجم از این مقالهControlling Log output coloringModel binding and validationCustom ValidatorsOnly Bind Query StringBind Uriمیریم واسه توضیح هر بخشقسمت اول Controlling Log output coloringاگه میخواید لاگ های که توی کنسول می افته رنگی باشه از کد زیر ابتدای فایل اصلی gin.ForceConsoleColor()و اگر می خواید غیر فعال شه کد زیرgin.DisableConsoleColor()قسمت دوم Model binding and validationاین فرم ورک از استانداردهای همچون JSON, XML, YAML پشتیبانی می کند و از کتابخانه validator برای اعتبار سنجی استفاده می کند.همچنین این فرم ورک دو روش برای bind کردن دارهروش Type - Must bindاستفاده از متد های Bind​ , ​ BindJSON​ , ​ BindXML​ , ​ BindQuery​ , ​ BindYAML​ , ​ BindHeaderنحوه رفتار به این صورت هست اگر در درخواست ما خطای وجود داشته باشد با استفاده از c.AbortWithError(400,err).SetType(ErrorTypeBind)​ اون خطار رو  توی هدر Content-Type​  ​ text/plain; charset=utf-8 ارسال می کند.روش Type - Should bindاستفاده از متدهای  ShouldBind​,ShouldBindJSON​,ShouldBindXML​,ShouldBindQuery​,ShouldBindYAML​,ShouldBindHeaderاگر خطای در درخواست وجود داشته باشد، خطا برمی گردد و این توسعه دهنده است که مسئولیت رسیدگی مناسب به درخواست و خطا رو دارد. .و هنگام استفاده از این روش ، جین سعی می کند بسته به عنوان نوع محتوا ، هدر را ست کند.به تک کد زیر توجه کنیدtype Login struct { 
User string `form:&amp;quotuser&amp;quot json:&amp;quotuser&amp;quot xml:&amp;quotuser&amp;quot binding:&amp;quotrequired&amp;quot` 
Password string `form:&amp;quotpassword&amp;quot json:&amp;quotpassword&amp;quot xml:&amp;quotpassword&amp;quot binding:&amp;quotrequired&amp;quot` 
}در کد بالا ما یه struct تعریف کردیم با دو فیلد از نوع string که هر دو ویژگی ساختار XML و JSON رو دارند که توی کد فوق مشخص کردیم و نوع اعتبارسنجی برای هردو فیلد رو اجباری کردیم.اگه میخواید خروجی JSON بگیرید کد زیرrouter.POST(&amp;quot/loginJSON&amp;quot, func(c *gin.Context) { 
var json Login 
if err := c.ShouldBindJSON(&amp;json); err != nil { 
c.JSON(http.StatusBadRequest, gin.H{&amp;quoterror&amp;quot: err.Error()
}) 
return 
} 
if json.User != &amp;quotmanu&amp;quot || json.Password != &amp;quot123&amp;quot {
 c.JSON(http.StatusUnauthorized, gin.H{&amp;quotstatus&amp;quot: &amp;quotunauthorized&amp;quot})
 return
 }
 c.JSON(http.StatusOK, gin.H{&amp;quotstatus&amp;quot: &amp;quotyou are logged in&amp;quot}) 
})با استفاده از متد ShouldBindJSON میاد ساختار JSON رو چک می کند اگر ساختار JSON اشباه بود توی خط چهارم خطای از نوع کد StatusBadRequest بر میگردونه و اما اگر دورست بود توی خط ۱۲ پیغام مناسب به همراه کد StatusOK رو برمی گردونه و اگر اشتباه بود توی خط نه این مورد رو مشخص کردیم.اما اگر برای ساختار XMLبود بجای این تابع ShouldBindJSON  تابعShouldBindXML رو جایگزین کنیدقسمت سوم Custom Validatorsنحوه اعتبار سنجی سفارشیpackage main 
import ( 
&amp;quotnet/http&amp;quot
 &amp;quottime&amp;quot 
&amp;quotgithub.com/gin-gonic/gin&amp;quot 
&amp;quotgithub.com/gin-gonic/gin/binding&amp;quot 
&amp;quotgithub.com/go-playground/validator/v10&amp;quot 
)
 type Booking struct {
 CheckIn time.Time `form:&amp;quotcheck_in&amp;quot binding:&amp;quotrequired,bookabledate&amp;quot time_format:&amp;quot2006-01-02&amp;quot` 
CheckOut time.Time `form:&amp;quotcheck_out&amp;quot binding:&amp;quotrequired,gtfield=CheckIn&amp;quot time_format:&amp;quot2006-01-02&amp;quot` 
} 
var bookableDate validator.Func = func(fl validator.FieldLevel) bool { 
date, ok := fl.Field().Interface().(time.Time) 
if ok {
today := time.Now() 
if today.After(date) { 
return false 
}
} 
return true 
}
func main() { 
route := gin.Default()
 if v, ok := binding.Validator.Engine().(*validator.Validate); ok { 
v.RegisterValidation(&amp;quotbookabledate&amp;quot, bookableDate) 
}
 route.GET(&amp;quot/bookable&amp;quot, getBookable) route.Run(&amp;quot:8085&amp;quot)
 }خوب توی خط ۹ ما یه ساختار تعریف کردیم و توی خط ۱۵ تا ۲۴ اومدبم اعتبارسنجی خودمون رو دورس کردیم برای این کار ما نیاز به کتابخونه اصلی داریم که توی خط ۷ تعریف کردیم و توی تابع اعتبار سنجی خودمون تعریف کردیم این تایع اعتباری سنجی ما توی خط ۲۸ می باشد به نام bookableDateقسمت چهارم Only Bind Query Stringیه زمانی هست که می خوای اطلاعات رو به صورت رشته توی کنسول نشون بدی و به صورت جزيی یعنی فرض کن یه ساختار داری با ۱۵ تا فیلد ولی فقط دو تاش رو میخوای که  توی خط ۴و ۵ نشون دادیمvar person Person
 if c.ShouldBindQuery(&amp;person) == nil { 
log.Println(&amp;quot====== Only Bind By Query String ======&amp;quot) 
log.Println(person.Name) 
log.Println(person.Address)
 }</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Fri, 11 Dec 2020 18:27:41 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 4</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-4-ijjg9mer54hb</link>
                <description>Gin Web Framework part 4درود دوستان امروز میخوام در مورد بخش چهارم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش چهارم از این مقالهGrouping routesBlank Gin without middleware by defaultUsing middlewareCustom Recovery behaviorHow to write log fileCustom Log Formatمیریم واسه توضیح هر بخشقسمت اول Grouping routes// Simple group: user
v1 := router.Group(&amp;quot/v1&amp;quot){
v1.POST(&amp;quot/login&amp;quot, loginEndpoint)
v1.POST(&amp;quot/submit&amp;quot, submitEndpoint)
v1.PUT(&amp;quot/change&amp;quot, changeEndpoint)
}
// Simple group: food
v2 := router.Group(&amp;quot/v2&amp;quot){
v2.GET(&amp;quot/list&amp;quot, llistEndpoint)
v2.GET(&amp;quot/search&amp;quot, searchEndpoint)
v2.POST(&amp;quot/save&amp;quot, saveEndpoint)
}یه زمانی پیش میاد توی برنامه نوشته شده تون تعداد روت های زیاد داشته باشید و بخواید مدیریت بهتری روی روت هاتون داشته باشید توی این فرم ورک می تونید از router.group همین طور که مشاهده می کنید در کد بالا استفاده کنید به خط ۲و۸ دقت کنید که apiهای food و user رو ازم هم جدا کردیم.قسمت دوم Blank Gin without middleware by defaultاگر بخواید از مدلویرهای Logger and Recovery استفاده نکنید از کد زیر در ابتدا برنامه تون استفاده کنیدr := gin.New()اما اگر بخواید از مدلویرهای Logger and Recovery استفاده کنید از کد زیر در ابتدا برنامه تون استفاده کنیدr := gin.Default()قسمت سوم Using middlewareدر صورتی که بخواهید از Logger یا Recovery استفاده کنید به صورت زیر r.use استفاده کنیدr.Use(gin.Logger())r.Use(gin.Recovery())اگر بخواهیم به مجموعه از روت هامون میدلویر اختصاص بدیم به صورت زیرauthorized := r.Group(&quot;/&quot;, AuthRequired())قسمت چهارم Custom Recovery behaviorخوب توی روش های بالا ما میدلیور خود فرم ورک رو استفاده می کردیم اما اگر بخواهیم یک نوع میدلویر از نوع recovery رو کاستوم کنیم به صورت زیر استفاده می کنیمr.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { i
f err, ok := recovered.(string); ok { 
c.String(http.StatusInternalServerError, fmt.Sprintf(&amp;quoterror: %s&amp;quot, err)) 
} 
c.AbortWithStatus(http.StatusInternalServerError) 
}
))قسمت پنجم How to write log fileگاهی اواقات نیازه ما لاگ ها رو اصلن بجای اینکه توی دیتابیس خاصی داشته باشیم توی فایل داشته باشیمfunc main() {
f, _ := os.Create(&amp;quotgin.log&amp;quot)
gin.DefaultWriter = io.MultiWriter(f)
router := gin.Default()
router.GET(&amp;quot/ping&amp;quot, func(c *gin.Context) {
c.String(200, &amp;quotpong&amp;quot)
})
router.Run(&amp;quot:8080&amp;quot)
}خوب اگه با گولنگ و این فرم ورک(البته تا اینجای کار)آشنا باشید قشنگ میفهمید که کد بالا یه فایل رو ایجاد می کنه و با استفاده از خط سوم میاد تمام فعل و انفعالات رو توی فایل مدنظر ذخیره می کنه به همین راحتیقسمت شش Custom Log Formatاگه بخوایم یک لاگ شخصی دورس کنیم یعنی بگیم مثلن من میخوام لاگ هام چنین چیزهای (که در کد زیر هست) داشته باشم. به صورت زیر و با استفاده از متدی که در خط اول هست gin.LoggerWithFormatter(func(param gin.LogFormatterParams) یک استرینگ دورس کنیم از لاگ ها که نیاز داریم این لاگ ها توی خط ۴ تا ۱۲ تعریف شدهrouter.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) 
string { 
return fmt.Sprintf(&amp;quot%s - [%s] \&amp;quot%s %s %s %d %s \&amp;quot%s\&amp;quot %s\&amp;quot\n&amp;quot, 
param.ClientIP, 
param.TimeStamp.Format(time.RFC1123), 
param.Method, 
param.Path, 
param.Request.Proto, 
param.StatusCode,
param.Latency, 
param.Request.UserAgent(), 
param.ErrorMessage, ) 
}
))</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Wed, 09 Dec 2020 20:16:08 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 3</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-3-c37fq4nuxwna</link>
                <description>Gin Web Framework part 3درود دوستان امروز میخوام در مورد بخش سوم از سری مقالات فرم ورک Gin صحبت کنیمفهرست بخش سوم از این مقالهMultipart/Urlencoded FormMap as querystring or postform parametersUpload files (Single file)Upload files (Multiple files)میریم واسه توضیح هر بخشقسمت اول Multipart/Urlencoded Formrouter.POST(&amp;quot/form_post&amp;quot, func(c *gin.Context) {
message := c.PostForm(&amp;quotmessage&amp;quot)
nick := c.DefaultPostForm(&amp;quotnick&amp;quot, &amp;quotanonymous&amp;quot)
})
فرض کنید یه فرم دارید به اسم مثلن form.html و یه تکست باکس به اسم message دارید و میخواید اطلاعات رو از این فرم  بفرستید سمت سرور. خوب کافی هست از c.postform استفاده کنید که در خط شماره  دو می باشد. اما واسه اختیاری کردن فیلد یعنی زمانی که فیلدی خالی بود یه متن یا چیزی  توی فرم برای ما بفرست از دستور ی که در خط چهار هست استفاده می کنیم.قسمت دوم Map as querystring or postform parametersاین شمای رو در نظر بگیریدPOST /post?ids[a]=1234&amp;ids[b]=hello HTTP/1.1Content-Type: application/x-www-form-urlencodednames[first]=thinkerou&amp;names[second]=tianouکد زیر:router.POST(&amp;quot/post&amp;quot, func(c *gin.Context) {
 ids := c.QueryMap(&amp;quotids&amp;quot) 
names := c.PostFormMap(&amp;quotnames&amp;quot) 
fmt.Printf(&amp;quotids: %v; names: %v&amp;quot, ids, names) 
})خروجی مربوط به QueryMap در خط دومids: map[b:hello a:1234]خروجی مربوط به PostFormMap در خط سومnames: map[second:tianou first:thinkerou]خوب الان میخوام توضیح بدم در مورد کدها فوقتوی این روش تمام داده های که قرار ارسال بشه به صورت یک مپ درآمده و ارسال میشه که در خروجی های بالا مثلن names ما یک key داریم و یک value که در اینجا value های ما دادهای ارسالی ما هستن و داخل آکولاد اگر مشاهده کنبد کلید های ما هستن(شمای کلی رو نگاه کنید)قسمت سوم Upload files Single fileآپلود فایل به صورت تکینمونه کد:router.MaxMultipartMemory = 8 &lt;&lt; 20 // 8 MiB 
router.POST(&amp;quot/upload&amp;quot, func(c *gin.Context) {
file, _ := c.FormFile&#40;&amp;quotfile&amp;quot&#41;
log.Println(file.Filename)
var dst string = &amp;quotdir/file/upload/
c.SaveUploadedFile&#40;file, dst&#41;
})برای آپلود فایل به صورت تکی از متدی که در خط سوم می باشد استفاده می کنیم. پارامتری که میگیره نام اون فرم آپلود  می باشد. خوب توی خط اول ما سایز فایل رو مشخص کردیم و توی خط پنج آپلود عکس توی یه فلود ر خاص رو مشخص کردیمتست با curl:curl -X POST http://localhost:8080/upload \-F &quot;file=@/Users/appleboy/test.zip&quot; \-H &quot;Content-Type: multipart/form-data&quot;قسمت چهارم Upload files Multiple fileآپلود فایل به صورت چندتایینمونه کد:router.POST(&amp;quot/upload&amp;quot, func(c *gin.Context) {
form, _ := c.MultipartForm()
files := form.File[&amp;quotupload[]&amp;quot]
for _, file := range files {
c.SaveUploadedFile&#40;file, dst&#41;
}
})برای آپلود فایل به صورت چندتایی از متدی که در خط دوم (MultipartForm) می باشد استفاده می کنیم. توی خط سوم پارامتری که میگیره نام اون فرم آپلود می باشد. که قرار چندتایی فایل آپلود بشه بخاطر همین توی آرایه هست و بعدش توی یه حلقه for اون فایل های دریافتی رو توی یه مسیر خاص با استفاده از متدی که توی خط پنج هست (aveuploadfile) انجام میشه.تست با curl:curl -X POST http://localhost:8080/upload \ -F &quot;upload[]=@/Users/appleboy/test1.zip&quot; \ -F &quot;upload[]=@/Users/appleboy/test2.zip&quot; \ -H &quot;Content-Type: multipart/form-data&quot;</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Tue, 08 Dec 2020 22:21:47 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 2</title>
                <link>https://virgool.io/@bardiiia/gin-web-framework-part-2-kqxz7b6uhwhb</link>
                <description>Gin Web Framework part 2درود دوستان امروز میخوام در مورد بخش دوم از سری مقالات فرم ورک Gin صحبت کنیمتوی مقاله قبل یه چی یادم رفته بود اونم این بود که چه پروژه های دارن از این فرم ورک استفاده می کنندgorush: A push notification server written in Go.fnproject: The container native, cloud agnostic serverless platform.photoprism: Personal photo management powered by Go and Google TensorFlow.krakend: Ultra performant API Gateway with middlewares.picfit: An image resizing server written in Go.gotify: A simple server for sending and receiving messages in real-time per web socket.cds: Enterprise-Grade Continuous Delivery &amp; DevOps Automation Open Source Platform.فهرست  بخش دوم از این مقالهUsing GET, POST, PUT, PATCH, DELETE and OPTIONSParameters in pathQuerystring parametersمیریم واسه توضیح هر بخشقسمت اول Using GET, POST, PUT, PATCH, DELETE and OPTIONSنحوه تعریف نوع درخواست ها مون رو مشخص می کنیم به صورت زیرfunc main() {
router := gin.Default()
router.GET(&amp;quot/someGet&amp;quot, getting)
router.POST(&amp;quot/somePost&amp;quot, posting)
router.PUT(&amp;quot/somePut&amp;quot, putting)
router.DELETE(&amp;quot/someDelete&amp;quot, deleting)
router.PATCH(&amp;quot/somePatch&amp;quot, patching)
router.HEAD(&amp;quot/someHead&amp;quot, head)
router.OPTIONS(&amp;quot/someOptions&amp;quot, options)
router.Run()توی  خط اول  برای  شروع کار حتما باید یه نمونه از این فرم ورک رو نمونه برداری کنیم ابن خط درواقع میدلویر پیش فرض این فرم ورک رو برام ست می کنه که کار این میدلویر logger and recovery می باشدتوی خط ۳ تا ۹ نوع درخواست مون رو مشخص می کنیم که GET, POST, PUT, PATCH, DELETE می باشدفک نکونم دیگه نیاز به توضیح بیشتری باشه چون همه چی واضح هستخوب خط ۱۰ برنامه ما رو رروی پورت پیش فرض ۸۰۸۰ تنظیم می کند اگر نیاز به تغییر این پورت دارید به صورت زیر می توایند تغییر دهیدrouter.Run(&quot;:4030&quot;)قسمت دوم Parameters in pathنحوه پاس دادن پارمتر از طریق آدرس یا url به صورت زیر انجام می شود.روش اول: در این روش که روش ساده ای هم هست روش ارسال یه پارامتر به آدرس هستrouter.GET(&amp;quot/user/:name&amp;quot, func(c *gin.Context) {
          name := c.Param(&amp;quotname&amp;quot)
          c.String(http.StatusOK, &amp;quotHello %s&amp;quot, name)
})در روش فوق ما با ارسال یه رشته به آدرس بالا (user/:name/)که جایگزین اون  name ما هست میشینه که به صورت زیر می باشد -  عنوان مثال/user/:name/user/bardia/uaer/gopherروش دوم: مفهوم این کد ریدایرکت هست که زیر این کد توضیح میدمrouter.GET(&amp;quot/user/:name/*action&amp;quot, func(c *gin.Context) {
name := c.Param(&amp;quotname&amp;quot)
action := c.Param(&amp;quotaction&amp;quot)
message := name + &amp;quot is &amp;quot + action
c.String( message)
})خوب توی کد فوق اگر ما بخواهیم که آدرس مدنظر ما با الگوی که بالا توی خط اول تعریف کردیم نبود به آدرس دیگری ریدایرکت بشهمثلن  یعنی یه کاربری توی پنل خودش هست و فقط به آدرس های زیر از پنل خودش می تونه بره/user/bardia/post/user/bardia/category/user/bardia/task/user/bardia/commentحل فرض کنید قرار به آدرس زیر بره/user/bardia/installچون چنین آدرس موجود نیست اصلن توی سیستم ریدایرکت میشه به آدرس user/bardiaروش سوم: چک کردن آدرس ورودیrouter.POST(&amp;quot/user/:name/*action&amp;quot, func(c *gin.Context) {
c.FullPath() ==&amp;quot/user/:name/*action&amp;quot // true
})در روش فوق زمانی که ما بخواهیم آدرس ورودی رو چک کنیم ببینیم همون آدرس مورد انتظار هست از تابع fullpath در بدنه تابع درخواست کننده استفاده می کنیم.قسمت سوم Querystring parametersدرواقع Query String هر مقداریست که بعد از علامت سوال (“?”) در انتهای URL قرار می‌گیرد که می‌تواند یک یا تعداد بیشتری پارامتر باشد. ‏مثلا app.gopher.academy/?q=app یک URL همراه با Query String می‌باشد که مقدار q هم همراه با URL به سرور داده می‌شود که در اینجا برابر با app استساختار Query Stringhttps://derak.cloud/کد مربوطه در این فرم ورکrouter.GET(&amp;quot/welcome&amp;quot, func(c *gin.Context) { 
firstname := c.DefaultQuery(&amp;quotfirstname&amp;quot, &amp;quotgopher&amp;quot)
 lastname := c.Query(&amp;quotlastname&amp;quot) 
c.String(http.StatusOK, &amp;quotHello %s %s&amp;quot, firstname, lastname) 
}) قرار یه آدرس به صورت زیر داشته باشیمwelcome?firstname=Jane&amp;lastname=Doeخوب برای اینکه آدرس ما به صورت یک querystring باشه از متد به اسم c.Query که توی خط ۳ نوشتم انجام میشهاما خط دوم یه متدی داره به اسم defaultquery که زمانی استفاده میشه که ما بخوایم بگیم یه پارمتری رو اختیاری کنیم یعنی اگع کاربر چیزی نفرستاد یا خالی بود به صورت پیش فرض عبارت gopher رو بفرست</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sun, 06 Dec 2020 19:39:57 +0330</pubDate>
            </item>
                    <item>
                <title>Gin Web Framework part 1</title>
                <link>https://virgool.io/golangpub/gin-web-framework-part-1-qiizbzxmemwv</link>
                <description>Gin Web Framework part 1توی این دوره یا مجموعه مقالاتی که قرار منتشر کنم. میخوام در مورد Gin Web Framework صحبت کنم. در واقع می خوام از صفر تا صد این فرم ورک رو بهتون اموزش بدم.فرم ورک Gin چیست؟این فرم ورک با زبان گو نوشته شده است?. و  از  API های فرم ورک martini و با عملکرد بسیار بهتر و به لطف httprouter تا 40 برابر سریعتر بهره می برد. اگر به عملکرد و بهره وری خوب نیاز دارید.?? جین را دوست❤️ خواهید داشت.(البته ابن جمله از خودم نبود? از سایت اصلی بود)ویژگی ها این فرم ورک:Fastمسیریابی مبتنی بر درخت Radix ، استفاده memory foot printMiddleware supportدرخواست HTTP ورودی را می توان با زنجیره ای از میان افزارها و اقدامات نهایی انجام داد. به عنوان مثال: Logger ، Authorization ، GZIP و در آخر پیام را در DB ارسال کند.Crash-freeابن فرم ورک می تواند اگر در هنگام درخواست HTTP دچار مشکل شود می تواند  آن را بازیابی کند. به این ترتیب سرور شما همیشه در دسترس خواهد بود. به عنوان مثال - همچنین می توانید این خرابی  را به Sentry گزارش دهد!JSON validationابن فرم ورک می تواند JSON یک درخواست را تجزیه و تأیید کند - به عنوان مثال ، بررسی مقادیر مورد نیازRoutes groupingمسیرهای  گروه ها می توانند بدون محدودیت عملکرد به صورت نامحدود تو در تو قرار بگیرند.Error managementابن فرم ورک یک روش مناسب برای جمع آوری تمام خطاهایی که در هنگام درخواست HTTP رخ داده است فراهم می کند. در نهایت ، یک میان افزار می تواند آنها را در یک پرونده ورود به سیستم ، یک پایگاه داده بنویسد و آنها را از طریق شبکه ارسال کند.Rendering built-inابن فرم ورک استفاده آسان از API را برای ارائه JSON ، XML و HTML فراهم می کند.Extendableایجاد یک میان افزار جدید بسیار آسان استلیستی از بنچمارک ها  one Benchmarks two Benchmarksتوضیحات جدول(1): کل تکرارها در زمان ثابت به دست می آیند ، بالاتر یعنی نتیجه با اطمینان تر(2): مدت زمان تکرار  (ns / op) ، پایین تر بهتر است(3): این Heap Memory، پایین تر بهتر است(4): میانگین تخصیص در هر بار تکرار (allocs / op) ، پایین تر بهتر است.نیاز مندی این فرم ورکGo 1.9 or aboveGo 1.7 or Go 1.8 will be no longer supported soon.نصب و شروع اولین کد با این فرم ورک دستور زیر را توی ترمینال وارد کنید تا این فرم ورک نصب شهgo get -u github.com/gin-gonic/ginخوب یه فایل ایجاد کنید به اسم example.go و کد زیر رو  بنویسید.package main
 import &amp;quotgithub.com/gin-gonic/gin&amp;quot 
func main() { 
r := gin.Default() 
r.GET(&amp;quot/ping&amp;quot, func(c *gin.Context) { 
c.JSON(200, gin.H{ &amp;quotmessage&amp;quot: &amp;quotpong&amp;quot,}) 
}) 
r.Run() 
 }برای شروع کار حتما باید یه نمونه از این فرم ورک رو نمونه برداری کنیم توی خط چهارمتوی خط پنجم اومدیم یه درخواستی از نوع get ایجاد کردیم به آدرس ping که در خروجی قرار یه رشته pong رو برامون چاپ کنهخوب حالا دستور زیر رو میزنم# run example.go and visit 0.0.0.0:8080/ping on browser$ go run example.goاینم خروجی که ادرس 127.0.0.1/ping که خروجی رشته pong رو چاپ می کندچجوری تست بنویسم براش؟برای تست نویس باید از پکیج net/http/httptest استفاده کنید به صورت زیرpackage main

import (
	&amp;quotnet/http&amp;quot
	&amp;quotnet/http/httptest&amp;quot
	&amp;quottesting&amp;quot

	&amp;quotgithub.com/stretchr/testify/assert&amp;quot
)

func TestPingRoute(t *testing.T) {
	router := setupRouter()

	w := httptest.NewRecorder()
	req, _ := http.NewRequest(&amp;quotGET&amp;quot, &amp;quot/ping&amp;quot, nil)
	router.ServeHTTP(w, req)

	assert.Equal(t, 200, w.Code)
	assert.Equal(t, &amp;quotpong&amp;quot, w.Body.String())
}</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sat, 05 Dec 2020 17:47:14 +0330</pubDate>
            </item>
                    <item>
                <title>نصب فونت پارسی در لینوکس</title>
                <link>https://virgool.io/@bardiiia/%D9%86%D8%B5%D8%A8-%D9%81%D9%88%D9%86%D8%AA-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%AF%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-k1ele88z3r8a</link>
                <description>من این مقاله رو زمانی نوشتم که توی لینوکس خودم توی افیسش مشکل فونت داشتم . باخودم گفتم چطور و از کجا باید این فونت رو نصب کنم که بالاخره با سرچ زیاد روش های زیر رو پیدا کردم که گفتم بزارم تو قالب یه مقاله آموزشیخوب بریم سروقت اینکه باید چیکار کردتوی گام اول برید توی مسیر زیر.local / share / fontsتوی گام بعدی فونت های پارسی خود را که دانلود کردید توی یه پوشه جدید توی پوشه fonts کپی کنیدتوی مرحله بعدی باید با ترمینال وارد پوشه fonts شوید و کش فونت هارو پاک کنید تا دایرکتوری فونت جدید رو برای نصب شناسایی کنه.با دستور زیر:fc-cache -f -vبعدش باید برید توی پوشه ای که برای فونت ها ساختید رو برید و کددستوری زیر رو بزنید.fc-list | grep &amp;quotH&amp;quotخوب من توی پوشه جدیدی که ساختم اسم اول تمام فونت های پارسی من اول همه شون H هست. حالا شما ممکنه اسم اول فونت های شما s باشد که باید بجای H از S استفاده کنید.بعد از زدن دستور فوق خروجی به صورت زیر می باشد یعنی با موفقیت فونت شما اعمال شد/home/cafec0de/.local/share/fonts/Hack-BoldItalic.ttf: Hack:style=Bold Italic/home/cafec0de/.local/share/fonts/Hack-Italic.ttf: Hack:style=Italic/home/cafec0de/.local/share/fonts/Hack-Bold.ttf: Hack:style=Bold/home/cafec0de/.local/share/fonts/Hack-Regular.ttf: Hack:style=Regularخوب امیدوارم از این مقاله کاربری های لینوکسی استفاده کنن.</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sat, 05 Dec 2020 13:26:32 +0330</pubDate>
            </item>
                    <item>
                <title>نحوه استفاده از دستور stat در لینوکس</title>
                <link>https://virgool.io/@bardiiia/%D9%86%D8%AD%D9%88%D9%87-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%AF%D8%B3%D8%AA%D9%88%D8%B1-stat-%D8%AF%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-ezakez9unfiz</link>
                <description>How to Use the stat Command on Linuxنحوه استفاده از دستور stat در لینوکسدستور stat Linux به شما جزئیات بیشتری از ls نشان می دهد. ما به شما نحوه استفاده از آن را نشان خواهیم داد. ما با استفاده از این روش میخواهیم اطلاعات خوبی را در مورد یک پرونده به شما نشان دهیم ، مانند مجوزهایی که روی آن تنظیم شده است ، و سایز و نوع فایل و آیا این یک فایل یا یک پیوند نمادین است. برای نمایش این اطلاعات ، آن را از ساختار سیستم فایل به نام یک inode خوانده می شود. در واقع این inodeچیه حالا هر پرونده و پوشه دارای یک inode است. inode دارای داده های مربوط به پرونده است ، مانند اینکه کدام سیستم فایل را اشغال می کند ، و تمبرهای تاریخ مربوط به پرونده را ذخیره می کند. inode مانند کتابخانه برای پرونده است. اما فقط بعضی از اطلاعات را به شما نشان می دهد. برای دیدن همه چیز ، باید از دستور stat استفاده کنیم.مقایسه سریعبیایید از ls استفاده کنیم تا یک لیست با اندازه پرونده در اختیار ما قرار میدهد.ls -lh ana.hخروجی به شکل زیراز چپ به راست ، اطلاعاتی که ls ارائه می دهد عبارتند از:خط تیره اول به ما می گوید که فایل یک فایل معمولی است و نه سوکت ، و نه نوع دیگری.مجوزها با فرمت octal ذکر شده اند.تعداد پیوندهای اشاره شده به این پروندهمالک پرونده دیوید است.صاحب گروه دیوید است.اندازه پرونده 802 بایت است.پرونده آخرین بار در روز جمعه سیزدهم دسامبر 2015 اصلاح شد.نام پرونده ana.c.بیایید نگاهی با آمار داشته باشیم:stat ana.hاطلاعاتی که از stat دریافت می کنیم عبارتند از:File: نام پرونده. معمولاً همان اسمی است که برای ثبت در خط فرمان گذاشتیمSize: اندازه پرونده ( بایت)Blocks: تعداد بلوک های که در سیستم فایل نیاز هست ، تا در هارد دیسک ذخیره شودIO Block: اندازه یک بلوک سیستم فایلFile type: نوع metadata ها را توصیف می کند. متداول ترین نوع این metadata ها پرونده ها و دایرکتوری ها هستند اما می توانند لینک ها ، یا سو کت های نامگذاری شده باشندDevice: شماره Device به صورت هگزادسیمال و دسیمال است. این شناسه هارد دیسک است که پرونده در آن ذخیره می شود.Inode: شماره inode یعنی شماره شناسه این inodeLinks: این شماره نشان دهنده تعداد پیوندهای به این پرونده است. که هر پیوند دارای inode خاص خود است. بنابراین این رقم به معنی  اینست که چند inode به این پرونده اشاره دارد. هر بار که یک Links ایجاد یا حذف می شود ، این شماره به بالا یا پایین تنظیم می شود. هنگامی که به صفر رسید ، خود پرونده حذف شده و inode حذف می شود.Access: مجوزهای پرونده را  نشان می دهدUid: شناسه کاربر و نام حساب مالک.Gid: شناسه گروه و نام حساب مالک.Modify: زمان آخرین تغییر محتوای پرونده است.Change: ویژگی ها یا محتویات فایل آخرین بار تغییر یافته است. اگر با تنظیم مجوزهای جدید فایل را تغییر دهید ، نشانگر تغییر زمان به روز می شودBirth: برای نشان دادن تاریخ ایجاد اولیه پرونده استمفهوم Timestampsنشان های منطقه زمانی هستند. -0500 در پایان هر خط نشان می دهد که این پرونده در یک منطقه زمانی جهانی هماهنگ (UTC) بر روی رایانه ایجاد شده است که پنج ساعت از منطقه زمانی رایانه فعلی فاصله دارد. بنابراین این رایانه پنج ساعت از رایانه ای که این پرونده را ایجاد کرده است عقب است. در حقیقت ، این پرونده بر روی یک رایانه در منطقه زمانی انگلیس ایجاد شده است ، و ما آن را در اینجا در رایانه ای در منطقه زمانی استاندارد شرقی آمریکا مشاهده می کنیم.بیایید از chmod برای تغییر مجوزهای پرونده در پرونده ای به نام ana.c. استفاده کنیم. ما قصد داریم آن را برای همه قابل نوشتن کنیم. این روی محتوای پرونده تأثیر نمی گذارد ، اما روی ویژگی های پرونده تأثیر می گذارد.chmod +w ana.cبااستفاده از دستور زیر می توانیم منطقه زمانی را مشاهده کنیم:stat ana.cاستفاده از Stat با چندین فایلبرای داشتن گزارش آماری در چندین پرونده به طور هم زمان ، نام پرونده ها را در حالت خط فرمان به صورت زیر قرار دهید:stat ana.h ana.oبرای استفاده  از الگوی باید از علامت سؤال &quot;؟&quot; برای هر کاراکتر استفاده کنیم ، و علامت &quot;*&quot; بیانگر هر رشته ای از می باشد. ما می توانیم به stat بگوییم که پرونده ای بنام &quot;ana&quot; را با یک حرف اضافه با این دستور گزارش دهد:?stat ana.?با استفاده از stat برای گزارش در مورد Filesystemsدرواقع stat می تواند وضعیت سیستم های پرونده ها و همچنین وضعیت پرونده ها را گزارش کند. گزینه -f گزینه stat را برای گزارش در سیستم پرونده ای می باشد.stat -f ana.cآمارو اطلاعاتی که به ما می دهد:File: نام پرونده.ID: شناسه سیستم فایل در حالت hexadecimal.Namelen: حداکثر طول مجاز برای نام پرونده ها.Type: نوع سیستم فایل.Block size: مقدار داده درخواست برای خواندن نرخ انتقال بهینه داده ها.Fundamental block size: اندازه هر بلوک سیستم فایل.Total: تعداد کل بلوک ها در سیستم پرونده.Free: تعداد بلاک های رایگان در سیستم پرونده.Available: تعداد بلاک های رایگان در دسترس کاربران معمولی (غیر ریشه) است.Total: تعداد کل ورودیها در سیستم پرونده.Free: تعداد ورودی های رایگان در سیستم پرونده.ارجاعات Symbolic Links:اگر میخواهید پرونده ای که به صورت symbolic link هست رو مشاهده کنید باید به صورت زیر عمل کنید:stat -L code.cقالب های خروجی سفارشی:یک راه بهتر برای به دست آوردن مجموعه ای از داده ها در stat ، استفاده از یک قالب سفارشی است. یک لیست طولانی از نشانه ها به نام توالی قالب وجود دارد. هر یک از این عناصر داده را نشان می دهد. موارد مورد نظر خود را در خروجی انتخاب کرده و یک رشته فرمت ایجاد کنید.مجموعه های مختلفی از دنباله های فرمت برای فایلها و سیستم فایلها وجود دارد. لیست پرونده ها:%a: The access rights in octal.%A: The access rights in human-readable form (rwx).%b: The number of blocks allocated.%B: The size in bytes of each block.%d: The device number in decimal.%D: The device number in hex.%f: The raw mode in hex.%F  The file type.%g: The group ID of the owner.%G: The group name of the owner.%h: The number of hard links.%i: The inode number.%m: The mount point.%n: The file name.%N: The quoted file name, with dereferenced filename if it is a symbolic link.%o: The optimal I/O transfer size hint.%s: The total size, in bytes.%t: The major device type in hex, for character/block device special files.%T: The minor device type in hex, for character/block device special files.%u: The user ID of the owner.%U: The user name of the owner.%w: The time of file birth, human-readable, or a hyphen “-” if unknown.%W:  The time of file birth, seconds since the Epoch; 0 if unknown.%x: The time of last access, human-readable.%X: The time of last access, seconds since the Epoch.%y: The time of last data modification, human-readable.%Y: The time of last data modification, seconds since the Epoch.%z: The time of last status change, human-readable.%Z: The time of last status change, seconds since the Epoch.برای سیستم فایل ها قالب به صورت زیر می باشد:%a: The number of free blocks available to regular (non-root) users.%b: The total data blocks in the filesystem.%c: The total inodes in the filesystem.%d: The number of free inodes in the filesystem.%f: The number of free blocks in the filesystem.%i: The file system ID in hexadecimal.%l: The maximum length of filenames.%n: The filename.%s: The block size (the optimum writing size).%S: The size of filesystem blocks (for block counts).%t: The file system type in hexadecimal.%T: file system type in human-readable form.دو گزینه وجود دارد که رشته های دنباله فرمت را می پذیرند. اینها --format و --printf هستند. تفاوت بین آنها این است --printf توالی به سبک C مانند newline \ n و برگه \ t را تفسیر می کند ، و به طور خودکار کاراکتر جدیدی به خروجی آن اضافه نمی کند.مانند حالت زیرstat --printf=&quot;File %n is %s bytes, and is a %F\n&quot; code.c ana/ana.?گزارش برای هر پرونده در یک خط جدید ذکر شده است ، همان چیزی است که ما درخواست کردیم. نام پرونده ، اندازه پرونده و نوع پرونده برای ما تهیه شده است. قالبهای سفارشی به شما امکان دسترسی حتی به عناصر داده حتی بیشتر از آنچه در خروجی استاندارد استاندارد موجود است ، می دهد.</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Tue, 01 Dec 2020 14:21:07 +0330</pubDate>
            </item>
                    <item>
                <title>ساخت یک وب سرور ساده گولنگ روی یک داکر کانتینر</title>
                <link>https://virgool.io/@bardiiia/%D8%B3%D8%A7%D8%AE%D8%AA-%DB%8C%DA%A9-%D9%88%D8%A8-%D8%B3%D8%B1%D9%88%D8%B1-%D8%B3%D8%A7%D8%AF%D9%87-%DA%AF%D9%88%D9%84%D9%86%DA%AF-%D8%B1%D9%88%DB%8C-%DB%8C%DA%A9-%D8%AF%D8%A7%DA%A9%D8%B1-%DA%A9%D8%A7%D9%86%D8%AA%DB%8C%D9%86%D8%B1-mvuqeqqrxv27</link>
                <description>درود دوستان امیدوارم حال روزتون خوب باشه?? این یه آموزش ساده ساخت یک وب سرور ساده با گولنگ و لانچ کردن آن رو یک داکر کانتینر هست. این  ویدیوی که ضبط کردم اولین ویدیویی هست که ضبط کردم.اگه پیشنهادی نظری داشتید حتما اینجا یا توی تلگرام یا یوتوب برام کامنت کنید تا ویدیو های بعدی رو بهتر ضبط کنیم??درواقع من یه کانال آموزشی راه اندازی کردم به اسم گوفر آکادمی که تو کانال به صورت خیلی deepبه مطالب حوزه گولنگ می پردازیم.?خوشحال میشم اگه کسی دوست داشت برای انتشار مقاله یا فیلم در حوزه گولنگ بهم پیام در تلگرامآها راستی یادم نره لینک این فیلم هم توی آدرس زیر توی یوتوب و تلگرامم هست??بوتوب:https://www.youtube.com/watch?v=VTYz8inQ4ngتلگرام:https://t.me/gopher_academy/175منتظر نظرات و پیشنهادات شما هستیم در گوفرآکادمی??لینک کانال:https://t.me/gopher_academyانستاگرام:https://www.instagram.com/gopher_academy/</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sun, 08 Nov 2020 14:25:01 +0330</pubDate>
            </item>
                    <item>
                <title>Go Developer Roadmap part 3</title>
                <link>https://virgool.io/golangpub/go-developer-roadmap-part-3-yme5wi3jpsfe</link>
                <description>Go Developer Roadmap part 3در این مقاله که سری سوم و نهایی از مسیری در جهت تبدیل شدن به یک توسعه دهنده گولنگ را نشان می دهد. که یک توسعه دهنده گولنگ باید چه چیز های یاد بگیرد. پس با ما همراه باشید. شما می توایند قسمت اول  و قسمت دوم را از این جا بخوانید.سرفصل بخش اول شامل موارد زیر هستTestingTask SchedulingMicroServicesDesign Patternsخوشحال میشم اگه چیزی از قلم افتاده توی همین پست برام کامنت کنید.و در ضمن ما رو توی گیت هاب دنبال کنید۱. ابزار های Testingقبل اینکه با ابزار ها آشنا بشیم یه توضیح بدم که در واقع تست نویسی یکی از اصول مهم در برنامه نویسی هست که اکثر برنامه نویس های ایرانی ازش فراری هستن خوب در واقع تست نویسی این اطمینان را حاصل می کند که عملکرد مناسبی از برنامه تولید شود . این موضوع یکی از مهم ترین مراحل در در فرآیند تولید یک محصول است.به هیچ وجه نمی توان بدون تست یک محصول رو به بازار فرستاد.چرا باید تست بنویسیم؟تست باعث می شود نقص یا خطایی که ممکن است در مرحله توسعه ایجاد شود،شناسایی و برطرف گردد.موفقیت هر محصول با کیفیت و قابلیت اطمینان مشتری در مورد آن محصول ارزیابی می شود.برای ارائه نرم افزارهایی با کیفیت بالا، تست مناسب لازم و ضروری است. برای طراحی هر نرم افزاری هزینه های زیادی در مرحله توسعه ، بازاریابی و … شده است.بنابراین مهم است که یک برنامه نتایج مثبتی برای جلوگیری از هزینه های ناخواسته یا ناگهانی داشته باشد.اگر برنامه شما در بعضی قسمت ها مشکل داشته باشد باعث نارضایتی کاربر و ترک برنامه شما خواهد شد.برای تحکیم جایگاه خود در بازار ، عملکرد نرم افزار باید واقعاً خوب و بادوام باشد. این نوع اطمینان فقط با روشهای مناسب تست قابل دستیابی است.با کمک تست می توان امنیت کلی نرم افزار را بهبود بخشید.انواع تست ها در برنامه نویسیالبته نوع های مختلف دیگه ای هم هست اما ن توی این مقاله چندتا رو توضیح میدم که توی پکیج های گولنگ مورد استفاده قرار می گیرند.تست unit این تست قطعه کوچکی از کد که نیازمند به کد ها و یا ابجکت های زیادی نیست , مثل یک متد و یا یک کلاس برای تست که نیازمند آبجکت ها و یا کلاس های دیگر و یا توابع دیگر نیستند , دقت کنید که گفتیم زیاد نه اینکه یک کلاس وابسته به کلاس دیگری برای ران شدن باشد و ما این را یونیت تست صدا نزنیم , نه! این اشتباه است ما قطعه کوچک را باید در نظر بگیریم و اگر کد بزرگی داشتیم قطعا از متد های دیگر استفاده خواهیم کرد .تست integrationتستی که در برگیرنده چند واحد کد است و منظورمان چند کلاس و متد و… است . و معمولا بیشتر از یونیت تستینگ وقت گیر است چراکه complexity برنامه بالا رفته است و شما باید چند واحد را تست کنید و قطعا مشخص است که یونیت تستینگ وقت کمتری را خواهد گرفت .تست behaviorتوسعه رفتار محور تکنیک‌ها و قواعد اساسی، توسعه آزمون محور را با ایده‌های طراحی دامنه محور و تجزیه و تحلیل و طراحی شی گرا ادغام می‌کند تا برای تیم‌های توسعه و مدیریت نرم‌افزار، ابزارها و فرایندهای مشترکی برای همکاری در توسعه نرم‌افزار ارائه کند.معرفی ابزار های تست Unit, Behavior, Integrationابزار GoMockاین ابزار یک چارچوب mocking برای زبان برنامه نویسی Go است. که با بسته  داخلی Go ساخته شده  است.ابزار Testifyبی شک در این لیست این ابزار یکی از بهترین ابزار ها هست که متد های مختلفی و میتونید رو کد خودتون تست کنید.ویژگی ها:Easy assertionsMockingTesting suite interfaces and functionsابزار GinkGoیک نوع تست برای تست های BDD محصوب می شود.ابزار GoMegaیک نوع تست برای تست های BDD محصوب می شود.ابزار GoDogیک نوع تست برای تست های BDD محصوب می شودابزار GoConveyیک نوع تست که به صورت محیط ui تست های شمارو نشون میده. اینم لینک ویدیوویژگی ها:Directly integrates with go testFully-automatic web UI (works with native Go tests, too)Huge suite of regression testsShows test coverage (Go 1.2+)Readable, colorized console output (understandable by any manager, IT or not)Test code generatorDesktop notifications (optional)Immediately open problem lines in Sublime Text (some assembly required)۲. ابزارهای Task Schedulingاین ابزار ها که از اسمشان پیداست وظیفه مدیریت و زمانبدی وظابف رو دارن ابزار Gronکرون جاب ها در گولنگ می باشد.ویژگی ها:Minimalist APIs for scheduling jobs.Thread safety.Customizable Job Type.Customizable Schedule.ابزار JobRunnerاین ابزار چارچوبی برای انجام کار به صورت غیر همزمان می باشد.و  برنامه ریزی و صف بندی توابع  برای پردازش در زمان مشخص با Cron همراه میسازد.۳. ابزار های MicroServicesابزار های Message-Brokerابزار  RabbitMQاین ابزار یک نرم افزار صف بندی پیام به نام واسطه‌ی پیام یا مدیریت صف است. بطور ساده، نرم افزاری است که در آن صف‌ها می‌توانند تعریف شوند، برنامه‌ها ممکن است به صف متصل شده و یک پیام به آن انتقال دهند.ابزار  Apache Kafkaکافکا برای مواجهه با انبوهی از داده ها که بی وقفه در حال ارسال هستند و شما فرصت کافی برای پردازش و ذخیره سازی آنها نداشته باشید تولید شده است.کافکا  برای استفاده در پروژه های زمان واقعی (real-time) به منظور فراهم آوردن خط لوله داده ها و جریان برنامه های استفاده می شود. کافکا به صورت افقی مقیاس پذیر، مقاوم در برابر خطاو بسیار سریع است. و در تولیدات هزاران شرکت استفاده می شود.ابزار  ActiveMQاین نرم افزار محبوب و قدرتمند یک نرم افزار کدباز پیام رسانی و سرویس دهنده تجمیع کننده الگوها می باشد. این نرم افزار بسیار سریع بوده و بسیاری از زبانهای مبتنی بر ایستگاه کاری و پروتکل های مختلف را پشتیبانی می نماید. این نرم افزار به صورت بسیار کاربر پسند و حرفه ای، الگوهای تجاری را تجمیع می نماید. ActiveMQ قابلیت های پیشرفته ای در خود گنجانده است. همچنین نسخه جدید این نرم افزار ازJMS 1.1 و J2EE 1.4 پشتیبانی می نماید . این نرم افزار تحت مجوز Apache 2.0 License انتشار می نمایدابزار  Azure Service Busدر واقع این ابزار ارتباطات ابری قابل‌اطمینان بین برنامه‌ها و پایگاه‌های داده را فراهم می‌کند و پیام را به عنوان یک سرویس (MaaS) ارایه می‌دهد.ابزار  Building message-drivenابزار  Watermillاین ابزار یک کتابخانه برای جریان های پیام می باشد. این ابزار برای ساخت برنامه های مبتنی بر رویدادها ، فعال کردن منابع برای رویدادها ، RPC از طریق پیام ها ،و هر چیز دیگری به ذهن شما خطور می کند. در ضمن شما  می توانید با استفاده  از ابزار های متداولی مانند کافکا یا RabbitMQ ، بلکه HTTP یا MySQL استفاده کنید.ویژگی ها:Easy to understand.Universal - event-driven architecture, messaging, stream processing, CQRS - use it for whatever you need.Fast (see Benchmarks).Flexible with middlewares, plugins and Pub/Sub configurations.Resilient - using proven technologies and passing stress tests (see Stability).ابزار های Frameworksابزار GoKitاین فرم ورک برای ساخت برنامه های که مبتنی بر میکروسرویس می باشند عمل می کند.ویژگی ها:Operate in a heterogeneous SOA — expect to interact with mostly non-Go-kit servicesRPC as the primary messaging patternPluggable serialization and transport — not just JSON over HTTPOperate within existing infrastructures — no mandates for specific tools or technologiesابزار Microاین فرم ورک برای ساخت برنامه های توزیع شده می باشد.ویژگی ها:AuthenticationDynamic ConfigData StorageService DiscoveryLoad BalancingMessage EncodinggRPC TransportAsync MessagingSynchronizationPluggable Interfacesابزار rpcxیک چارچوب سریع برای میکرو سرویسهای دو طرفه چند زبانهویژگی ها:Support raw Go functions. There&#x27;s no need to define proto files.Pluggable. Features can be extended such as service discovery, tracing.Support TCP, HTTP, QUIC and KCPSupport multiple codecs such as JSON, Protobuf, MessagePack and raw bytes.Service discovery. Support peer2peer, configured peers, zookeeper, etcd, consul and mDNS.Fault tolerance：Failover, Failfast, Failtry.Load banlancing：support Random, RoundRobin, Consistent hashing, Weighted, network quality and Geography.Support Compression.Support passing metadata.Support Authorization.Support heartbeat and one-way request.Other features: metrics, log, timeout, alias, circuit breaker.Support bidirectional communication.Support access via HTTP so you can write clients in any programming languages.Support API gateway.Support backup request, forking and broadcast.ابزار های RPCابزار Protocol Buffersدرمورد این ابزار و نحو کارکرد آن  این مقاله آموزش صفر تا ۵۰ پروتوبافر رو بخونید.ابزار gRPC-Goدرمورد این ابزار و نحو کارکرد آن  این مقاله gRPC چیه و چطور کار میکنه؟ رو بخونید.۴. الگو های طراحیدر واقع Design Patternها در زمان طراحی سیستم های نرم افزاری و یا فرایند تولید جواب بسیار مورد توجه قرار می گیرد. الگوها سر و صدای زیادی به پا کرده است. از طرفی ممکن است در استفاده از آن ها دچار سردرگمی بشویم. اساساً با سوالات زیر مواجه خواهیم بود:در وافع Design Pattern چیه؟چرا باید از Design Patternها استفاده کنیم اصلن؟چه زمانی باید از Design Patternها استفاده کنیم؟در واقع Design Pattern چیه؟در واقع Design Patternها یکسری جواب های ثابت شده به مشکلات رایج در طراحی هستند. به وسیله آنها می توان یکسری راهکار برای حل مسائل بازگشتی در طراحی برنامه تعریف کرد.به طور واضح، Design Patternها کدهای آماده ای نیستند که بتوان مستقیماً از آن ها استفاده کرد. اما یسکری رویکرد یا نظریه برای حل چالش های عادی طراحی ارائه می دهند.چرا باید از Design Patternها استفاده کنیم؟باید از design pattern ها برای طراحی و توسعه اجزاء (componentها) ای استفاده کنیم که مجدداً قابل استفاده و مقیاس پذیر بوده باشند و به تیم برنامه نویسی کمک کنند تا عملیات توسعه در زمان مقرر و با کیفیت بالاتری به انجام برسد.طراحی یک برنامه به شکل استاندارد یا تست شده به سایر توسعه دهنده گان و کسانی که کدهای برنامه را قرار است مرور کنند، اجازه می دهد به راحتی مفهوم کدهای نوشته شده را درک کنند.چه زمانی باید از Design Patternها استفاده کنیم؟استفاده از Design Patternها بدون ارزیابی صحیح باعث پیچیدگی غیر ضروری الگو می شود. در شرایطی که به آنها احتیاج ندارید می توانید با استفاده از اصول ساده طراحی OOP کار خود را به جلو ببرید.اینکه چه زمانی از آنها استفاده کنیم و یا چه زمانی استفاده نکنیم به خودمان بستگی دارد. هر الگو درباره یک مشکل طراحی صحبت میکند و یک راه حل استاندارد برای آن ارائه می دهد. بنابراین قبل از استفاده از آنها کمی وقت برای تجزیه و تحلیل مسائل طراحی صرف کنید و سعی کنید آن را با توصیف های الگو تطبیق دهید.به خاطر داشته باشید که نکته کلیدی در پیدا کردن الگوی صحیح، شناسایی و درک سناریویی است که هر الگویی سعی میکند به آن دست یابد.به محض اینکه الگوی مناسب برای مسئله یا سناریوی خاص شما مشخص شد، می توانید از آن در طراحی نرم افزار خود استفاده کنید.یه چندتا منابع مبزارم براتون برای کاری با الگو ها در گولنگhttps://github.com/tmrts/go-patternshttps://golangbyexample.com/all-design-patterns-golang/</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sat, 11 Jul 2020 12:24:09 +0430</pubDate>
            </item>
                    <item>
                <title>Go Developer Roadmap part 2</title>
                <link>https://virgool.io/golangpub/go-developer-roadmap-part-2-mbeigfg5vfmu</link>
                <description>Go Developer Roadmap part 2در  این مقاله که سری دوم از  مسیری در  جهت تبدیل شدن به یک توسعه دهنده گولنگ را نشان می دهد. که یک توسعه دهنده گولنگ باید چه چیز های یاد بگیرد. پس با ما همراه باشید. شما می توایند قسمت اول را از  این جا بخوانید.سرفصل بخش اول شامل موارد زیر هستCachingLoggingReal-Time CommunicationAPI ClientsGood to Knowخوشحال میشم اگه چیزی از قلم افتاده توی همین پست برام کامنت کنید.و در ضمن ما رو توی گیت هاب دنبال کنید۱. ابزارهای cachingاولش یه توضیح بدیم که این کش ها کارشون چیه با یه مثالخودِ کلمه‌ی Cache به معنای پنهان کردن یا چیزی است که برای کاربردهای آتی ذخیره و پنهان شده است. مثلاً به غذایی که حیوانات در زمستان ذخیره و پنهان می‌کنند تا بعداً استفاده کنند، Cache گفته می‌شود. اصطلاح کش در دنیای کامپیوتر، همزمان با تلاش برای افزایش کارایی CPU (پردازنده‌های مرکزی کامپیوتر‌ها) به صورت گسترده رواج پیدا کرد.در واقع کش یک لایه ذخیره سازی داده با سرعت بالا است که مجموعه ای از داده ها را ذخیره می کند، با این هدف که پاسخ گویی به درخواست ها با سرعت بیشتری انجام شود. به طور کلی داده ها در کش، در سخت افزار با دسترسی سریع مانند RAM (حافظه با دسترسی تصادفی) ذخیره می شود تا امکان استفاده از داده های کش شده با سرعت بالا فراهم باشد. هدف اولیه Cache افزایش بازده داده ها با کاهش نیاز به دسترسی به لایه ذخیره سازی با سرعت پایین تر(مانند Hard Disk )است. در واقع Cache  ها در لایه های مختلفی مانند  سیستم عامل ها، لایه های شبکه از جمله NetNews ، تحویل محتوا (CDN) و DNS، برنامه های کاربردی وب و پایگاه های داده استفاده می شود.۱-۱. کتابخانه gcache یک کتابخانه کش برای گولنگ. این کتابخانه از کش ، LFU ، LRU و ARC استفاده می کند.ویژگی های این کتابخانهاز کش ، LFU ، LRU و ARC پشتیبانی می کند.گوروین امن.۱-۲. کتابخانه go-redisنوع امن  Redis برای Golang می باشد این کتابخانهویژگی های این کتابخانهRedis 3 commands except QUIT, MONITOR, SLOWLOG and SYNCAutomatic connection pooling with circuit breaker supportPub/SubTransactionsPipeline and TxPipelineScriptingTimeoutsRedis SentinelRedis ClusterCluster of Redis Servers without using cluster mode and Redis SentinelRingInstrumentation۱-۳. کتابخانه gomemcacheنوع  memcache برای Golang می باشد این کتابخانهیه تغریفی هم از Memcached داشته باشیم به زبان ساده تر Memcached یک نرم افزار برای انجام عملیات کش روی سرورهای وب سایت های Dynamic هست که باعث میشه از منابعتون بهتر و بهینه تر استفاده کنید . نرم افزار Memcached بصورت Open Source ارائه شده و مکانیزم کش کردن Object ها و به ویژه Query ها رو در Dynamic وب سایت ها بر عهده داره تا سرعتشون رو بالا ببره . با استفاده از Memcached تعداد دفعات دسترسی به پایگاه داده شما کم میشه و سرعت پاسخگویی وب سایت شما بالا می ره . در Memcached مکانیزم هایی برای منقضی شدن Object های کش شده و البته پاسخ های بازگشتی به کاربر دیده شده که اگر محتوایی تغییر می کنه یا نتیجه ای باید تغییر کنه بلافاصله اینکار انجام بشه و نتایج اشتباه به کاربر نمایش داده نشه .۲. ابزار های Logging۲-۱. کتابخانه های نوع Log Frameworksکتابخانه Zapیک سیستم سریع و ساختار ی رو ارایه می کند.در واقع Zap یک رویکرد متفاوت را اتخاذ می کند. این کتابخانه شامل یک رمزگذار JSON است و بر پایه Logger تلاش می کند تا از هر جایی که امکان پذیر باشد از سرریز سریال و تخصیص آن جلوگیری کند.کتابخانه ZeroLogبسته zerolog یک چارچوب  سریع و ساده را به خروجی JSON اختصاص می دهد.در واقع API Zerolog به گونه ای طراحی شده است که هم یک تجربه توسعه دهنده عالی داشته باشد و هم عملکرد خیره کننده ای داشته باشد. و همچنین برای ساده نگه داشتن پایه کد  فقط روی ورود به سیستم ساختاری کارآمد تمرکز دارد.کمپانی ها و پروژه های که از این کتابخانه استفاده می کنند.NetflixPublicaAlvalorZumatapomeriumAjoCardEurotelArquiveiownCloudSafeCrowUnityProductsupForChange (风变科技)BetMakersHoldaM3, incویژگی های این کتابخانهBlazing fastLow to zero allocationLevel loggingSamplingHooksContextual fieldscontext.Context integrationnet/http helpersJSON and CBOR encoding formatsPretty logging for development۲-۲. ابزارهای Log Management Systemابزار Sentry.ioاین ابزار مانیتورینگ خطا انجام می دهد یعنی خطاها را الویت بندی می کندابزار Loggly.comتجزیه و تحلیل ورود به سیستم و نظارت بر ورود به سیستم و مسائل مربوط به عملکرد را با ردیابی و  به یکدیگر سریعتر حل کنید۲-۳. ابزار های نوعDistributed Tracingابزار Jaegerنظارت و عیب یابی  در سیستم های پیچیده توزیع شده۳. ابزار  Real-Time Communication۳-۱. ابزار Socket.IOدر واقع Socket.IO در واقع یکی از کتابخانه های جاوا اسکریپت است که یک ارتباط دو طرفه (رفت و برگشتی) بین کلاینت و سرور برقرار می کند و از دو قسمت تشکیل می شود! کتابخانه سمت کلاینت که در مرورگر اجرا شده و دیگری ، کتابخانه سمت سرور بر پایه Node.js است که دارای یک API برای ارتباط با یکدیگر هستند.۴. کتابخانه های API ClientsمفوهمREST رست (به انگلیسی REST) مخفف REpresentational State Transfer یکی از محبوب‌ترین استانداردهای معماری API هست که روی فیلدینگ (Roy Fielding) در پایان نامه دکترای خودش معرفی کرد. این استاندارد تشویق میکنه لایه بک‌اند کاملا از فرانت‌اند جدا کنیم، این استاندارد یک سری قوانین وضع کردهبرای اطلاعات بیشتر این مقاله رو بخونید رست VS گراف‌کیوال ۴-۱. کتابخانه Gentlemanاین کتابخانه از اصول توسعه پذیری و ترکیب استفاده می کند تا روشی انعطاف پذیر برای ایجاد آسان لایه های  HTTP  بر اساس پلاگین های داخلی فراهم کند که می توانید در کلاینت های HTTP ثبت نام کرده و از آن استفاده مجدد کنید.ویژگی های این کتابخانه:Plugin driven architecture.Simple, expressive, fluent API.Idiomatic built on top of net/http package.Context-aware hierarchical middleware layer supporting all the HTTP life cycle.Built-in multiplexer for easy composition capabilities.Easy to extend via plugins/middleware.Ability to easily intercept and modify HTTP traffic on-the-fly.Convenient helpers and abstractions over Go&#x27;s HTTP primitives.URL template path params.Built-in JSON, XML and multipart bodies serialization and parsing.Easy to test via HTTP mockingSupports data passing across plugins/middleware via its built-in context.Fits good while building domain-specific HTTP API clients.Easy to hack.Dependency free.مفهوم GraphQLگراف‌کیوال یک query language برای API هست. تو سال ۲۰۱۲ توسط فیسبوک ایجاد شد و درسال ۲۰۱۵ به صورت اپن سورس منتشر شد. این نه یک استاندارده نه یک وب سرویس. گراف‌کیوال واسط بین کوئری و دیتاسورس‌های شماست. دیتاسورس شما میتونه دیتابیس یا وب سرویس باشه.برای اطلاعات بیشتر این مقاله رو بخونید رست VS گراف‌کیوال۴-۴. کتابخانه gqlgenیکی از بهترین کتابخوانه های گولنگ می باشد برای کار با گراف کیوال ها&amp;lt;br/&amp;gt;۴-۵. کتابخانه graphql-goیکی دیگر از کتابخوانه های گولنگ می باشد برای کار با گراف کیوال هاویژگی های این کتابخانه:minimal APIsupport for context.Contextsupport for the OpenTracing standardschema type-checking against resolversresolvers are matched to the schema based on method setshandles panics in resolversparallel execution of resolverssubscriptionsیکسری مثال با نحوه کار این ابزار روی گراف کیوال هاtonyghita/graphql-go-example - A more &quot;productionized&quot; version of the Star Wars API example given in this repository.deltaskelta/graphql-go-pets-example - graphql-go resolving against a sqlite database.OscarYuen/go-graphql-starter - A starter application integrated with dataloader, psql and basic authentication.zaydek/graphql-go-walkthrough - A beginner friendly walkthrough for prospective developers.۵. یکسری مفاهیمی که باید بدونید توی کد نویسی یعنی رعایت بشه۵-۱. کتابخانه Validatorکتابخانه ای برای اعتبار سنجی مقادیر فیلد ها و استراکچرهاویژگی های این کتابخانه:Cross Field and Cross Struct validations by using validation tags or custom validators.Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.Ability to dive into both map keys and values for validationHandles type interface by determining it&#x27;s underlying type prior to validation.Handles custom field types such as sql driver Valuer see ValuerAlias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structsExtraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldErrorCustomizable i18n aware error messages.Default validator for the gin web framework;۵-۲. کتابخانه GJsonاین  یک راه سریع و ساده برای به دست آوردن مقادیر از یک سند json را فراهم می کند. دارای ویژگی هایی مانند بازیابی یک خط ، مسیرهای نشانه گذاری نقطه ، تکرار و تجزیه خطوط json است.۵-۳. کتابخانه Authbossاین بسته یک سیستم تأیید اعتبار ماژولار برای وب است.این بسته چندین ماژول دارد که ویژگی های تأیید اعتبار و مجوز را دارد که به طور کلی برای وب سایت ها معمول است به گونه ای که شما می توانید هر تعداد مورد نیاز خود را فعال کنید و سایرین را کنار بگذارید. این کار باعث می شود تا بتوانید احراز هویت را به یک برنامه وصل کنید.۵-۴. کتابخانه Go-Underscoreکتابخانه Underscore.js یکی از کتابخانه های کاربردی JavaScript می باشد که بدون نیاز به توسعه Object های جاوااسکریپت و با استفاده از توابع موجود در آن می توان کدنویسی را بسیار ساده و با سرعت و Performance بهتری انجام داد. در واقع در گولنگ هم ما چنین  کتابخانه Go-Underscore داریم.&amp;lt;br/&amp;gt;</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Wed, 08 Jul 2020 11:49:21 +0430</pubDate>
            </item>
                    <item>
                <title>Go Developer Roadmap part 1</title>
                <link>https://virgool.io/golangpub/go-developer-roadmap-part-1-yzyifvf4gq0a</link>
                <description>Go Developer Roadmapدر  مقاله  زیر  یک مسیر جهت تبدیل شدن به یک توسعه دهنده گولنگ را  نشان می دهد. که یک توسعه دهنده گولنگ باید چه چیز های  یاد بگیرد. پس با ما همراه باشید. در قسمت اول این ماجراشما می توایند قسمت دوم را از این جا بخوانید.سرفصل بخش اول شامل موارد زیر هستPrerequisitesGeneral Development SkillsCLI ToolsWeb Frameworks + RoutersDatabasesORMsخوشحال میشم اگه چیزی از قلم افتاده  توی همین پست برام کامنت کنید.و در ضمن ما رو توی گیت هاب دنبال کنید۱. پیش نیاز ها برای شروع۱-۱. یاد گیری کدنویسی در گولنگ که می تونید اونارو از سایت های زیر یادبگیریدGo by ExampleGo ResourcesGo BootcampGophercisesLearning GoCosmicLearnSafari Books OnlineTutorials PointGolangbot.comGo Web ExamplesToptalTree HouseCodementorPluralsightReactDOMHackernoonAwesome GoTechgigGolang TutorialsGolang BasicEduonixArdan Labs50 Shades of GoMaster GoInfoworldA Tour of GoGolang CodePragmaCoders۱-۲. یادگیری Go Modulesدر واقع ماژول ها پکیج مورد استفاده ما درون یک پروژه شخصی می باشد. یعنی مدیریت پکیج های که درون پروژه مورد استغاده قرار دادیم. که پسوند این فایل go.mod هست.برای اطلاعات بیشتر و نحوه کار کرد آن به این آدرس مراجعه کنید.۱-۳. یادگیری مفاهیم ابتدای sql که برای شروع به این آدرس مراجعه کنید.۲. مهارتهای عمومی در توسعهآشنایی با دستورات gitپروتکل HTTPS را بدانید ، روش های درخواست (GET ، POST ، PUT ، PATCH ، DELETE ، OPTIONS)اطلاعاتی در مورد  الگوریتم ها و ساختار داده ها بخوانیددر مورد  احراز هویت ها  اطلاعات کسب کنیداصول SOLID  ، الگوهای معماری و design patterns مبانی تست نرم افزار (unit, integration, e2e)۳. آشنایی با CLI Tools۳-۱. ابزار cobraدر واقع Cobra هم یک کتابخانه برای ایجاد برنامه های قدرتمند CLI مدرن و هم برنامه ای برای تولید برنامه ها و فایل های فرمان می باشد. این ابزار در بسیاری از پروژه های Go مانند Kubernetes ، Hugo و Github CLI  مورد استفاده قرار گرفته. این لیست حاوی لیست گسترده تری از پروژه های با استفاده از این ابزار  هست.۳-۲. ابزار urfaveاین ابزار یک بسته ساده ، سریع و سرگرم کننده برای ساخت برنامه های خط فرمان در Go است. هدف این است که توسعه دهندگان بتوانند برنامه های خط فرمان  را سریع و توزیع را به روشی رسا بنویسند.۴. فرم ورک ها Web Frameworks + Routers۴-۱. فرم ورک beego برای توسعه  API های RESTful ، برنامه های وب و سروریس های بک اند در Go استفاده می شود. این فرم ورک الهام گرفته از Tornado ، Sinatra و Flask است. beego برخی از ویژگی های Go  مانند اینترفیس ها و اسنراکچر ها  را دارد.۴-۲. فرم ورک chiاین فرم ورک chi یک روتر سبک ، و سازگار برای ساخت سرویس های Go HTTP است. به خصوص کمک به  نوشتن سرویس های بزرگ REST API که با رشد پروژه و تغییر پروژه حفظ می شوند، به شما کمک می کند.تمرکز این پروژه به روی طراحی زیبا و راحت برای نوشتن سرورهای REST API بوده است ،ملاحظات اساسی در مورد طراحی chi عبارتند از:ساختار پروژهقابلیت نگهداریهندلرهای استاندارد http (فقط stdlib)بهره وری توسعه دهندهساختن یک سیستم بزرگ در بسیاری از قسمت های کوچک.۴-۳. فرم ورک echoابن فرم ورک دارای  معیار های همچون عملکرد بالا ، قابلیت توسعه ، و  minimalist می باشد.۴-۴. فرم ورک fiberاین فرم ورک یک چارچوب وب الهام گرفته از اکسپرس است که ، سریعترین از  موتور HTTP خود  Go هست   این فرم  ورک  برای سهولت در توسعه سریع و تخصیص حافظه و عملکرد  کارها را آسانتر می کند.۴-۵. فرم ورک ginیکی از ويژگی های که  این فرم ورک را از مابقی جدا می سازد سرعت و عملکرد بالای آن هست. این ویژگی دارای یک API Martini است که عملکرد آن به لطف httprouter تا 40 برابر سریعتر می کند. اگر به عملکرد و بهره وری خوبی نیاز دارید ، جین انتخاب خوبی هست.۵-۵. فرم ورک revelیک چارچوب وب با بهره وری بالا و انعطاف پذیر برای زبان Go۵. پایگاه داده هاRelationalSQL ServerPostgreSQLMariaDB MySQLCockroachDBCloud DatabasesCosmosDBDynamoDBSearch EnginesElasticSearchSolrSphinxNoSQLMongoDBRedisApache CassandraRavenDBCouchDBدرمورد پایگاه داده ها خودتون می تونید سرچ کنید. توی این مقاله دیگ توزیع ندادم.۶.  ابزار های Object Relational Mapperبه زبان بسیار ساده ابزاری هست که به شما به عنوان یک برنامه نویس میگه ، شما کاریت به نوشتن Query های دیتابیس ها نباشه ، کد مورد نظرت رو بنویس ، بده به من ، من به عنوان واسط بین کدها و دیتابیس میام و Query ها رو تولید می کنم و اینجوری باعث میشه دنیا برای برنامه نویس ها بسیار زیباتر بشه . فکر کنید دیگه نیازی نیست که شما درگیر کدهای SQL عجیب و غریب بشید و اینکار رو به عهده ORM می گذارید.خوب با تعاریف فوق ما توی گولنگ دوتا ابزار داریم برای این کاریGORMXORM</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Tue, 07 Jul 2020 13:22:51 +0430</pubDate>
            </item>
                    <item>
                <title>زبان Erlang</title>
                <link>https://virgool.io/@bardiiia/%D8%B2%D8%A8%D8%A7%D9%86-erlang-tvtuxon8sg81</link>
                <description>erlangزبان برنامه نویسی Erlang چیست؟در واقع Erlang یک زبان برنامه نویسی همگانی، همزمان و همچنین یک سیستم زمان بندی جمع آوری زباله است. زبان برنامه نویسی Erlnag یک زبان برنامه نویسی سمت سرور است که توسط شرکت اریکسون ساخته شده و دارای یک ماشین مجازی است که می توان آن را در ویندوز، لینوکس، فری بی اس دی و سیستم های دیگر نصب نمود و از قدرت بیش از حد آن بهره برد. اصطلاح Erlang به طور متناوب با Erlang/OTP یا OTP استفاده می شود که شامل سیستم زمان اجرا Erlang، تعدادی از اجزای آماده برای استفاده (که عمدتا در Erlnag نوشته شده اند) و مجموعه ای از اصول طراحی برای برنامه های Erlang می باشد.رلنگ در واقع یک زبان اختصاصی در شرکت اریسکون بود که توسط Joe Armstrong , Robert Virding و Mike Williams در سال ۱۹۸۶ توسعه پیدا کرده بود، اما در سال ۱۹۹۸ به عنوان یک زیان متن باز منتشر شد. Erlang/OTP توسط واحد محصول OTP در اریکسون پشتیبانی و نگهداری می‌شود.زبان Erlang برای سیستم هایی که دارای ویژگی های زیر باشند، مناسب است:توزیع شدهتحمل پذیری خطا (ویژگی است که سیستم را قادر می سازد تا در صورت شکست، برخی از اجزای آن به درستی عمل کنند.)برای برنامه های real-time توزیع شده معمولا از ارلنگ استفاده می کنندبرنامه های بدون توقف و همیشه قابل دسترسقابلیت مبادله دائم (جایی که کد را می توان بدون توقف یک سیستم تغییر داد.)ارلنگ یک زبان عالی برای برنامه نویس های back-end هستش و قابلیت هایی داره که تقریبا هیچ زبون برنامه نویسی او قابلیت هارو نداره .مثلا :1.توزیع شده هستش یعنی شما میتونید برنامه تون رو بدون مشکل ، هم زمان  روی چند رایانه اجرا کنید 3.میتونید هنگامی که برنامه در حال اجرای بدون ایجاد خللی در کار برنامه کد های اونو عوض کرد (Hot swapping)</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Fri, 03 Jul 2020 09:57:57 +0430</pubDate>
            </item>
                    <item>
                <title>ایجاد فایل gitignore برای تمام زبان های برنامه نویسی</title>
                <link>https://virgool.io/@bardiiia/%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%D9%81%D8%A7%DB%8C%D9%84-gitignore-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AA%D9%85%D8%A7%D9%85-%D8%B2%D8%A8%D8%A7%D9%86-%D9%87%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-z7qhsivmkjw1</link>
                <description>gitinoreمن توی این مقاله ای که نوشتم میخوام سایتی رو بهتون معرفی کنم که توش شما می تونبد زبان برنامه نویسی مد نظر خودتون رو انتخاب کنید و یک خروجی برای فایل gitinore برای پروژه در اختیارتون میدهخوب برای شروع کاری فقط کافیه که به سایت gitinore مراجعه کنیدخوب الان من به عنوان مثال  لاراول و گولنگ و جانگو رو مبخوام براتون مثلی از این قسمت ها ارائه کنموارد سایت فوق بشید بعدش توی قسمت سرچ بزنید مثلن django خوب خروجی که میده رو کپی کنید و وارد فایل gitinore پروژه خودتون کنید.قسمت های که برای فایل gitinore میده بهتون وارد زیر هست که با هشتگ مشخص شدهDjangoByte-compiled / optimized / DLL filesC extensionsDistribution / packagingPyInstallerInstaller logsUnit test / coverage reportsTranslationsScrapy stuff:Sphinx documentationPyBuilderpyenvcelery beat schedule fileSageMath parsed filesSpyder project settingsRope project settingsMr Developermkdocs documentationmypyPyre type checkerخوب شما بسته به ساختار و نحوه عملکرد پروژه تون یکی از قسمت ها یا بعضی از اون ها رو که با هشتگ مشخص شده توی فایل gitinore رو میتونید مشخص کنید.خوب الان میرم سراغ لاراول که به صورت زیر هست. فقظ با کلمه laravel رو سرچ بزنید.خروجی که میده برای لاراول نسخه 4 و 5 و لومن رو هم میده که بهترین کار برای لاراول اینه که شما دستورات زیر رو توی فایل gitinore قرار بدیدvendor/node_modules/npm-debug.logyarn-error.logpublic/storagepublic/hotstorage/*.key.envHomestead.yamlHomestead.json/.vagrant.phpunit.result.cacheخوب دستورات زیر هم برای زبان برنامه نویسی گولنگ هست که میتونید اون توی فایل gitinore قرار بدید### Go #### Binaries for programs and plugins*.exe*.exe~*.dll*.so*.dylib# Test binary, built with &#x60;go test -c&#x60;*.test# Output of the go coverage tool, specifically when used with LiteIDE*.out# Dependency directories (remove the comment below to include it)vendor/### Go Patch ###/vendor//Godeps/امیدوارم از این آموزش استفاده خوبی کنید.</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Wed, 01 Jul 2020 13:09:55 +0430</pubDate>
            </item>
                    <item>
                <title>چک لیست امنیتی جنگو قبل از استقرار</title>
                <link>https://virgool.io/@bardiiia/%DA%86%DA%A9-%D9%84%DB%8C%D8%B3%D8%AA-%D8%A7%D9%85%D9%86%DB%8C%D8%AA%DB%8C-%D8%AC%D9%86%DA%AF%D9%88-%D9%82%D8%A8%D9%84-%D8%A7%D8%B2-%D8%A7%D8%B3%D8%AA%D9%82%D8%B1%D8%A7%D8%B1-cxbozl74e86f</link>
                <description>django securityشما می دانید که امنیت وب برای جلوگیری از دسترسی هکرها و سارقان فضای مجازی به اطلاعات ورودی حساس می باشد. بنابراین ، در این پست قصد داریم آسیب پذیری های امنیتی جنگو و چگونگی رفع آنها را بررسی کنیم.چک لیست استقراراول از همه ، دستور زیر را در قسمت پروژه جانگو خود وارد کنید:Python3 manage.py check --deployخروجی به شما توضیحاتی  در مورد آسیب پذیری برنامه وب Django ارائه می دهد.خوب بریم کم کم ببینم چی رو باید رعایت کنیم ✍?The Mozilla Observatoryاگر قبلاً برنامه خود را مستقر کرده اید ، از این سایت که توسط سایت موزیلا برای اسکن وضعیت امنیتی سایت استفاده می شود استفاده کنید. این سایت همچنین شامل اسکنرهای شخص ثالث است که سایر جنبه های امنیتی سایت شما را آزمایش می کند. ? ?مثال اسکن:The Mozilla Observatoryمحافظت از درخواست جعلی سایت (CSRF)در یک برنامه وب ، اساساً یک  ورودی از کاربر گرفته می شود و آنها را به قسمت های سرور ارسال می کند تا آنها را پردازش کند. اجزای سمت سرور به طور کلی از روشهای POST ، PUT ، DELETE برای پذیرش داده ها از طریق HTTPاستفاده می کنند.جنگو در برابر بیشتر اشکال تهدیدهای CSRF امنیت داخلی ایجاد کرده است.همانطور که در اسناد ذکر شده است ، هنگام علامت گذاری با دکوراتور csrf_exempt بسیار مراقب باشید ، مگر اینکه کاملاً ضروری باشد. اگر شخصی به کوکی csrftoken شما دسترسی داشته باشد ، آنگاه این یک آسیب پذیری می باشد. محافظت CSRF نمی تواند در برابر حملات انسان محافظت کند ، بنابراین از HTTPS با امنیت حمل و نقل دقیق استفاده کنید.پس از تنظیم HTTPS ، این خطوط را در تنظیمات خود اضافه کنید.#to avoid transmitting the CSRF cookie over HTTP accidentally.CSRF_COOKIE_SECURE = True#to avoid transmitting the session cookie over HTTP accidentally.SESSION_COOKIE_SECURE = TrueCross-site Scripting (XSS)در واقع XSS به یک مهاجم اجازه می دهد تا یک اسکریپت را به محتوای یک وب سایت یا برنامه تزریق کند. وقتی کاربر از صفحه آلوده بازدید می کند ، اسکریپت در مرورگر قربانی اجرا می شود. این به مهاجمان اجازه می دهد تا اطلاعات شخصی مانند کوکی ها ، اطلاعات حساب و غیره را سرقت کنند.در واقع X-XSS-Protection: 1؛ mode = block فیلتر XSS را امکان پذیر می کند. در صورت شناسایی یک حمله ، مرورگر به جای آن که از صفحه محافظت کند ، از ارائه صفحه جلوگیری می کند.برای فعال کردن آن در Django ، اطمینان حاصل کنید که django.middleware.security.SecuranceMiddleware در لیست میان افزار موجود است و خطوط زیر را در تنظیمات خود اضافه کنید:SECURE_BROWSER_XSS_FILTER = TrueSECURE_CONTENT_TYPE_NOSNIFF = TrueDjango Admin Securityیکی از مهمترین چیزهای که Django را ایمن می کند. قبل از استقرار برنامه خود باید admin / مسیر را به/admin تغییر دهید. در غیر این صورت ، شخصی می تواند به راحتی وارد url شود و به صفحه ورود به سیستم مدیریت دسترسی پیدا کند.#urls.pyfrom django.contrib import adminfrom django.urls import pathurlpatterns = [path(&#039;admin/&#039;, admin.site.urls) # change admin something different]شما می توانید با استفاده از django-admin-honpot صفحه ورود به سیستم جعلی ایجاد کنید و در صورت تلاش برای دسترسی غیرمجاز به شما اطلاع می دهد.SSL Redirectخط زیر را به تنظیمات خود اضافه کنید تا Django مجبور شود تمام درخواستهای غیر HTTPS را به HTTPS تغییر مسیر دهد.SECURE_SSL_REDIRECT = TrueContent Security Policy (CSP)اگر برنامه Django شما بزرگ است ، حاوی کد زیادی است ، و دارای بسیاری از اسکریپت ها و سبک های درون خطی است که در کل پروژه پراکنده هستند ، پس باید CSP را به سایت خود اضافه کنید.درDjango یک روش داخلی برای ایجاد یک هدر CSP ندارد ، بنابراین می توانید ماژول django-csp Mozilla را نصب کنید و از کنسول مرورگر خود برای پیگیری نقض امنیتی در کد خود استفاده کنید.پس از نصب django-csp ، خطوط زیر را به تنظیمات خود اضافه کنیدCSP_DEFAULT_SRC = (&amp;quot&#039;none&#039;&amp;quot, )CSP_STYLE_SRC = (&amp;quot&#039;self&#039;&amp;quot, )CSP_SCRIPT_SRC = (&amp;quot&#039;self&#039;&amp;quot, )CSP_IMG_SRC = (&amp;quot&#039;self&#039;&amp;quot, )CSP_FONT_SRC = (&amp;quot&#039;self&#039;&amp;quot, )بنابراین ، اساساً ، تمام اسکریپت ها و سبک های درون خطی شما دیگر مجاز نخواهند بود. همه اسکریپت ها و سبک ها باید از یک منبع بارگیری شوند.پاک کردن کد شما از همه این سبک ها و اسکریپت های درون خطی بسیار مهم است. با این حال ، برخی از منابعی مانند Google Tag Manager یا Google Analytics باید در خط مشی CSP شما مجاز باشد.کد زیرا رو در فایل تنظیمات قرار دهدید::CSP_DEFAULT_SRC = (&amp;quot&#039;none&#039;&amp;quot, )CSP_STYLE_SRC = (&amp;quot&#039;self&#039;&amp;quot, &amp;quotfonts.googleapis.com&amp;quot, &amp;quot&#039;sha256-/3kWSXHts8LrwfemLzY9W0tOv5I4eLIhrf0pT8cU0WI=&#039;&amp;quot)CSP_SCRIPT_SRC = (&amp;quot&#039;self&#039;&amp;quot, &amp;quotajax.googleapis.com&amp;quot, &amp;quotwww.googletagmanager.com&amp;quot, &amp;quotwww.google-analytics.com&amp;quot)CSP_IMG_SRC = (&amp;quot&#039;self&#039;&amp;quot, &amp;quotdata:&amp;quot, &amp;quotwww.googletagmanager.com&amp;quot, &amp;quotwww.google-analytics.com&amp;quot)CSP_FONT_SRC = (&amp;quot&#039;self&#039;&amp;quot, &amp;quotfonts.gstatic.com&amp;quot)CSP_CONNECT_SRC = (&amp;quot&#039;self&#039;&amp;quot, )CSP_OBJECT_SRC = (&amp;quot&#039;none&#039;&amp;quot, )CSP_BASE_URI = (&amp;quot&#039;none&#039;&amp;quot, )CSP_FRAME_ANCESTORS = (&amp;quot&#039;none&#039;&amp;quot, )CSP_FORM_ACTION = (&amp;quot&#039;self&#039;&amp;quot, )CSP_INCLUDE_NONCE_IN = (&#039;script-src&#039;,)برای اطلاعات بیشتر در مورد django-csp documentation جست و جو کنیدHTTP Strict Transport Securityاگر این خط مشی تنظیم شود ، شما به درستی از منابع HTTPS استفاده نکنید یا اینکه گواهی شما منقضی شده باشد ، مرورگرها از اتصال به سایت شما برای مدت زمانی معین امتناع می ورزند.خطوط زیر را به تنظیمات خود اضافه کنید:SECURE_HSTS_SECONDS = 86400  # 1 daySECURE_HSTS_INCLUDE_SUBDOMAINS = TrueSECURE_HSTS_PRELOAD = True</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Wed, 01 Jul 2020 12:17:57 +0430</pubDate>
            </item>
                    <item>
                <title>ساخت پروژه های جانگو با شل اسکریپت</title>
                <link>https://virgool.io/@bardiiia/%D8%B3%D8%A7%D8%AE%D8%AA-%D9%BE%D8%B1%D9%88%DA%98%D9%87-%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%86%DA%AF%D9%88-%D8%A8%D8%A7-%D8%B4%D9%84-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-sajserdi1rbw</link>
                <description>یه شل اسکریپتی که براتون نوشتم رو در اختیارتون قرار بدم این شل اسکریپت کار رو برای راه اندازی و کانفیگ ساختار پروژه جانگو رو اوکی می کنه براتونخوب بریم واسه توضیحاتشما توی حالت عادی روش های زیر رو میرید تا پروژه جانگو شما شکل بگیره توی مرحله اول با دستور زیر یک پروژه جانگو دورس میشهdjango-admin startproject name-projectبعدش با دستور زیر شما یک اپ برای پروژه جانگو میسازیدpython3 manage.py startapp name-applicationبعدش که app مورد نظر رو ساختید باید برید توی فایل setting.pyقسمت INSTALLED_APPS اونجا باید نام app رو که ساختید رو بدید به صورت زیر باید باشهINSTALLED_APPS = [&#039;django.contrib.admin&#039;,&#039;django.contrib.auth&#039;,&#039;django.contrib.contenttypes&#039;,&#039;django.contrib.sessions&#039;,&#039;django.contrib.messages&#039;,&#039;django.contrib.staticfiles&#039;,&#039;django_db_logger&#039;,&#039;myapp&#039;,]خوب شما فرض کنید میخواید بجای ساخت یه app بخواید چندین app رو بسازید بعدش باید نام app های ساخنه شده خودتون رو یکی یکی وارد کنید داخل فایل مربوط به تنظیمات یا همون setting.pyخوب این کار یکم زمان بره من با این شلی که ساختم این قابلیت رو داره که شما app که میسازید رو توی فایل تظیمات می نویسه اون نام app رو دیگه نیاز نیست دستی شما برید توی فایل تنظیمات وارد کنید.خوب بریم سراغ الگوریتم کاری این شل که به صورت زیر هست.قبلش بگم که برای اجرا باید دستور زیر رو بزنید.Bash -f django.shمرحله اول:از شما نام پروژه رو میخواد که بهش میدیدمرحله دوم:از شما سوال میکنه که آیا میخواید ساختار قالب و فایل های سایت رو داشته باشید اگر یک رو بزنید براتون دوتا پوشه به اسم های static و templates ساخته میشه که توی هرکدوم یه سری فایل و پوشه میسازه بعدش باید عدد صفر یا هرچیز وارد کنید که از حالت معمول بیاد خارج شهمرحله سوم: ازتون نام app رو میخواد بعدش دوباره ازتون سوال می کنه که ایا میخواهید دوباره app بسازید با زدن yes می تونید یه app دیگه بسازید و اگر می خواهید اتمام دهید به ساخت app جدید باید گزینه no رو بزنید.اما یه نکته باحالی که من نوشتم توی این شل اینه که شما زمانی که اپلیکیشن شما تموم شده توی اپلیکشن سه تا فایل با پسوند sh رو می بینید این فایل ها عبارتنداز:Run.shRemote.shpush.shتوی فایل run.sh میاد براتون اپلیکیشن رو اجرا می کنهدر حالت عادی شما برای اجرای اپلیکیشن میاد دستور زیر رو میزنیدpython3 manage.py runserverخوب الان دیگه نیاز نیست واسه اجرا دستور زیر رو بنویسید فقط کافیه دستور زیر رو بزنیدSh run.shاین دستور برنامه شما رو اجرا میکنه که داخلش دو دستور زیر رو داره این فایل شل اسکریپت به صورت زیر این دو دستور درون این فایل شل اسکریپت هستfind -name &amp;quot__pycache__&amp;quot -type d -exec rm -rf {} \;python3 manage.py runserverدستور اول میاد تمام پوشه های که با نام __pycache__ رو پاک می کنه این پوشه پوشه حاوی کش پروژه تون هست که پیدا می کنه و انارو پاک می کنه و دستور دوم میاد اجرا میکنهخوب الان میخوام دوتا فایل شل اسکریپت دیگه رو براتون توضیح بدم در واقع این دو فایل کارشون با گیت هست.توی فایل Remote.sh میاد از شما ادرس گیت  پروژه رو میگیره که تمام پروژه رو توی گیت هاب سوار کنه. فقط کافیه اونو اجرا کنید با دستور زیرSh remote.shبعدش از شما ادرس گیت رو میخواد که به صورت زیر هست ادرس گیت پروژه شما که باید اونو وارد کنیدمثلن:دقیقا اینو وارد نکنید این یه ادرس هست باید ادرس خودتون رو وارد کنیدhttps://githu1b.com/bardia/api-rest-go.gitخوب بعدش از شما رمز عبور رو میپرسه اونو میزنید و پروژه شما با موفقیت توی مخزنی که ساخته بودید سوار میشه به همین راحتی دیگه نیاز نیست این همه دستور پایین رو بزنید چرا که اونا همش توی این فایل هستنecho -n &amp;quotEnter url git project &gt; &amp;quotread urlecho -n &amp;quotPlease select a name for commit &gt; &amp;quotread namecommitgit initfind -name &amp;quot__pycache__&amp;quot -type d -exec rm -rf {} \;git add .git commit -m &amp;quot$namecommit&amp;quotgit remote add origin $urlgit push origin masterخوب فایل اخر فایل push.sh هست همون کار کامیت رو انجام میده براتون اما تمیز تر که برای اجرا باید کد زیر رو بزنیدSh push.shفقط از شما یه پیام برای کامیت میپرسه اونو بهش میدید و تغییرات پروژه رو براتون روی مخزن اعمال می کنه. کدش به صورت زیر هستfind -name &amp;quot__pycache__&amp;quot -type d -exec rm -rf {} \;echo -n &amp;quotPlease select a name for commit &gt; &amp;quotread namecommitgit add .dt=$(date &#039;+%A-%b-%d-%Y-%H-%M-%S&#039;);git commit -m &amp;quot$namecommit-$dt&amp;quotgit push --set-upstream origin masterدانلود شل اسکریپت</description>
                <category>mrbardia72</category>
                <author>mrbardia72</author>
                <pubDate>Sun, 28 Jun 2020 23:41:09 +0430</pubDate>
            </item>
            </channel>
</rss>