How Iranian software engineers are suffering from US sanctions

Before I start, I would like to ask you to take a quick look at screenshots below:

Golang.org website Golang.org

Github.com Github.com

Gitlab.com Gitlab.com

Docker Hub hub.docker.com

Google and Android Developers website Google Developers

Oracle developers Oracle Developers

You may have never seen such things before but Iranian software developers are facing many difficulties accessing these websites and services every day; and of course, it’s not limited to the above examples.

Last year, Github (an essential service for developers) blocked Iranian software engineers. So, many developers have migrated to Gitlab because it was the only accessible git service. Last month, Gitlab joined Github and banned Iranians and prevented them to access their software source codes.

In 2017, in an unprecedented move, Apple removed Iranian apps from the AppStore due to US sanctions and as a result so many iOS and macOS developers lost their jobs because they could not publish their apps anymore. To deal with this, a few organizations decided to use Enterprise app certificates to keep their iOS users. But, every once in a while, Apple recognizes these accounts and blocks them. Consequently, most iPhone/iPad users have no other choice but to use the web app version of their desired services.

Because of sanctions, Iranian developers are unable to access cloud services such as AWS or Microsoft Azure as well!

Nearly all developer services and tools are blocked for Iranians; therefore, developers must change their IP addresses by using a VPN or proxy to be able to access them. For example, Android developers cannot download Android Studio and its modules without using a VPN! This applies to Docker and Golang packages as well! Iranian developers must again use a bypassing tool to be able to access all of mentioned resources. It’s also worth mentioning that using a VPN in Iran is considered a crime.

These limitations are not just applied to software industry. Designers of all kinds are victims too! For instance, Adobe Creative Cloud along with services like Behance and Dribbble are blocked for Iranian graphic designers.

As a matter of fact, restrictions were in place for years but have intensified during Trump administration. They always tell the news that they are sanctioning the Iranian government but the truth is that people are the only ones that are hit.

I would to ask you to take a moment and think about it. Just imagine one day you wake up and you cannot access these resources. What would you do?

In Misc | 27 Oct 2020

Digital declutter for a month

About a month ago, I finished the Cal Newport’s valuable book “Digital Minimalism” and it’s actually changing my lifestyle! This book is a MUST read for everyone who is using the social media and entertainment online services such not just because of the materials and contents they provide but because after reading it I realized that we are waisting the most precious thing we have like never before; our life time! I will definitely go for a full review of this book in future. For now, I just wanted to share my own experience about the process.

Declutter process

The book offers you to quit all optional digital services for one month which includes social media, entertainment online services, news websites, and video games (if you’re addicted to it). The word optional is crucial here. For example, you may need to check your email every day because of your job and it’s OK. Or maybe you need to continue using Slack because there are some important messages that you need to take care of and that’s completely OK. But when I thought about my own life, I realized that there are just two services that can be considered indispensable: Email, and Whatsapp.

So I uninstalled all others:

  • Instagram
  • Twitter
  • Facebook
  • Telegram
  • Reddit
  • CNN
  • BBC
  • Lichess (An online chess platform)

Besides apps, I also quit watching the news on TV as well. Also, I tried to stop talking about politics and financial news when talking with my friends and family as well.

Replacement process

Unlike what I have been heard, the first days after quitting was not too difficult for me except that I had two more hours every day that I didn’t know what to do. According to the book, one mission during this process is to find replacements for times that got freed. So one day I write all of my life priorities on a piece of paper:

  • I need to spend more time with my family
  • I want to read more books
  • I have to shed some pounds and get fit

So I started to change my lifestyle accordingly to achieve above goals:

Spend more time with Family

Every time I get back home from the office, I was used to napping on our sofa and check all social media for about 30 minutes. So instead of this, I told my family to get ready for a walk right after I arrive every other day. Now whenever I get home, they are ready for the walk. We go walking for about an hour. Then when we return home, we start to prepare dinner together. This participation helped me a lot to get in touch more with my wife and daughter.

Read more books

I am already a reader. What I wanted to do is to boost it a little bit. So I changed our home’s environment a little bit. I placed the book I’m currently reading on a desk near the TV; consequently, instead of picking up the TV’s remote control, I pick up my book and start reading for about an hour after the dinner and before getting to bed.

Get fit

These days gyms are closed due to the Coronavirus; so, instead of going to the gym, I brought it to the house ;) I haven’t done anything special. I bought a pair of dumbbells from an online store and workout on days we don’t go for a walk. Furthermore, I watched some YouTube videos about exercising at home without any pieces of equipment. It’s very cool to see you can use you body weight instead of any gym weights. On weekends, I go for a hike either alone or with my friends.

So what about my phone

These days, I used my phone just for making calls, listening to podcasts, and to update my book progress on Goodreads. I kept Goodreads from my phone because it’s difficult to turn on my computer every night to update my process. When I get home, I place my phone somewhere far from the living room so I check it less often. I also configured “Do not disturb” to turn on automatically after 10 PM so I only receive emergency calls notifications. When it’s weekend, I tend to keep my phone on airplane mode so I can spend more time doing what I love. Sometimes when we go for a walk, I intentionally leave my phone at home to spend as much time as possible with my family and the nature.

Conclusion

In this world full of distracting stuff, we pay less attention to the things that really matters. Our families, our health (especially mental health), and our values need more attention! After removing some worthless things from my life, I feel more energized than ever! Quitting these products and services could be difficult and it’s not your fault at all because they spend millions of dollars designing them to catch your attention as much as they can and unfortunately our brain can handle a limited amount of attention. When the brain capacity it full, it simply ignores the other things; so, prioritize what matters and put your time and energy on truly valuable things.

Book Review - Atomic Habits

Atomic Habits Last month I finished the book Atomic Habits. I have read a few other books on building great and quitting bad habits such as The Power of Habit by Charles Duhigg which was also a great book. But what makes atomic habits a great book to read is that it gives you step by step instructions! It’s a practical book. Everything James Clear, the author, claims is based on scientific facts. After convincing the reader by providing those facts, he then offers some great techniques to either building a good or quitting bad habits. In this post I’m going to describe my own perception of this book.

The book elaborates that human behaviors are the result of plenty of small (atomic) habits. Our habits made us what we are! Habits differ from goals. Goals are things we are going to achieve but habits are actually behaviors that we are going to institutionalize in ourselves.

Who do you want to become

To be able to either build or quit a habit, you should first ask an important question from yourself: What kind of person I want to become? Then, you should ask another question accordingly. For example, if you want to become a healthy person, which is habit not a goal, you should then ask this important question: What are the characteristics of a healthy person? These could be some answers

  • A healthy person’s weight is ideal.
  • A healthy person exercise regularly.
  • A healthy person doesn’t eat or drink junk foods.
  • A healthy person sleeps well.

When answers completed you now know how to become that kind of person!

The four stages of habit

Any habit has the following 4 stages: Atomic Habits

So, as shown in the above image, to make a good habit, you must answer the following question:

  • How can I make it obvious? (Cue)
  • How can I make it more attractive? (Craving)
  • How can I make it easier? (Response)
  • How can I make it more enjoyable? (Reward)

Consequently, if you want to quit a bad habit you should act the opposite:

  • How can I make it invisible? (Cue)
  • How can I make it less attractive? (Craving)
  • How can I make it more difficult? (Response)
  • How can I make it unpleasant? (Reward)

Understand your current habits

Sometimes you don’t know what habits (no matter bad or good) you have. To understand you current habits create a list of all things you do during a typical day. Then mark each one with + for good ones, - for bad one, or = for neutral tasks. Here is an example:

Task Symbol
Wake up =
Check social media -
Shower +
Coffee =
Walk to work +

When I did it myself, I realized that some of my current habits are completely useless! For example, every morning after I wake up, I was instantly check my phone for any new notifications. Then without understanding it, I was checking Instagram and Twitter.

After understanding your current status, sort them by the value they’re adding to your life. By doing this, you will understand which task adds real value to your life and which doesn’t. You then understand that some of your habits needs change. You may want to quit some of bad ones like the one I’ve mentioned about myself, and replace them by good habits. But how? As mentioned above, the four stages will help you.

Build new habits

Here are some notes I’ve taken from the book for building new habits.

Stage 1: Make it obvious

The first stage is to make a habit clear! There are some techniques mentioned in the book to help you do it:

Bind it with space and time

Bind the habit you’re going to build to a space and time. For example if you want to learn a new language, you can do the following: I will learn French everyday 6PM at home. By binding time and space to a habit, you give it an identity.

Connecting habits

Connect habits you want to build with the ones you already have. For example if you want to read more books, you may want to connect it to your every morning coffee: I will read books for 30 minutes while drinking my morning coffee.

Environment change

Change the environment to make good habits more obvious and bad ones invisible. This is a really good one. Let’s imaging you want to learn playing guitar. So you should change your home’s environment by placing your guitar somewhere you see. In the meantime, if you get distracted by TV, place the remote control somewhere you can’t access easily; maybe in the TV drawer. Environment change was the biggest lesson for me. Because when you don’t see the signs of a bad habit you will probably won’t do that.

Stage 2: Make it attractive

One key point for building a new habit is that you should keep that very attractive all the time. If a new habit gets boring you will stop doing that. Scientifically, you should keep you dopamine level as high as possible so your brain enjoy the process doing that habit. Here are some techniques:

Packing habits

The packing technique means combining habits you want to make with the ones you already have. For example if you want to do more exercises, you can buy an indoor bicycle and do some cardio while watching Netflix.

The imitation pattern

Our brain uses an imitation pattern to make habits more enjoyable. We typically enjoy doing things that the following groups do:

  • Our family (especially parents)
  • Famous people and celebrities
  • Close friends and communities we are in

For example, in a family, if parents read books, children will probably read as well because book reading is a value in that family. As an another example, if you’re participated in a hiking group in which all other participants love hiking and mountain climbing, then you probably will do it more frequently and with joy.

Turn force into opportunity

One of the reasons we stop doing habits is because we’re doing them by force. But in order to stick to a habit, we must change our mindset about it. For example, if you plan to build a habit of waking up early, instead of tell yourself that I must force myself to wake up early every morning, you should make yourself aware of the benefits waking up early gives you. For example, if I wake up early, I would have more time doing what I love to and get more things.

Stage 3: Make it easier

The easier it gets, the more you do it.

Redo, Redo, and Redo

What make things easier to do? The answer is very simple: redo, redo, and redo. Repeating is the main step toward building a new habit. Every time you do a habit, it will get easier for you because the brain doesn’t have to think about it. The more you do something, the easier it gets.

Embrace new habits

Some people don’t try new things because they afraid to fail. Accepting the fact that you will fail sometimes will help you doing that as soon as possible and prevent procrastination. You need to start doing whatever is in your mind. The best way to learn a new thing is practice it over and over again; not planning and not acting.

Deal with difficult habits

Some habits cannot become any easier. For this kind of habits, the book offers to make the first two minutes of doing that habit easy. The more the first parts of a habit become easier, the more you probably do it.

Make bad habits difficult

For bad habits, you must make them as much difficult as possible. For example, if you want to play less video games, place you console’s HDMI cable in somewhere hard to reach, so it will be much harder to start playing instantly.

Section 4: Make is satisfying

It’s as clear as sunshine that if you enjoy what you do, you will do in again and again and again. In this part of Atomic Habits, James Clear, the author, suggests some techniques to make your habits enjoyable.

Make your progress visible

Making progress while doing something is enjoyable and motivating; but, sometimes the process is hidden. For example, when losing weight, the first day you stick to a diet plan could have no visual effect on you but you have definitely progressed. One way to make the process enjoyable is by making hidden progresses visible. This is why calorie counter applications have such huge effect on people who are willing to lose weight. Because they see a visual progress from day one.

Find companions

I was going hiking almost every week with my friends. Nowadays, because of the COVID-19 pandemic I have to go alone. Because of this, I lost my willpower to go hiking every week. I skipped some weeks and to tell you the truth, I went hiking just once in the previous month. When you find some companions, they encourage you and boost your willpower to stick to a habit.

Conclusion

I believe when you read a book especially a self-improvement one, you should apply it to your own life if you find it interesting and practical. That’s why I have tried to apply this book and some other self-help books I find useful for myself. I believe if you can evolve good habits in yourself, it will change your life. For example, if you can institutionalize waking up early every morning and stick to it, it will change all aspects of your life.

When you want to build a new habit or quit a bad one, the following table could be very useful:

  Good habits Bad habits
Law #1 Make it obvious Make in invisible
Law #2 Make it attractive Make it unattractive
Law #3 Make it easy Make it difficult
Law #4 Make it satisfying Make it unpleasant

I highly recommend this book to everyone who care about productivity and will to change.

File upload using Gin

This post is my third post covering concepts of Gin , the HTTP web framework for Go. My previous post are:

In the RESTful era, most of our requests and responses’ payloads are JSON. However, in some cases, you may want to upload a file instead. In this post I’m going to describe how to receive and save an uploaded file using Gin framework.

The most common way to upload a file in a web browser is via the html file upload element (<input type="file" />). To be able to let the server know that you’re uploading a file, the request’s Content-Type header must be set to multipart/form-data. Here’s an example function for sending a file to a server using ReactJS and Axios:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import Axios from 'axios';

uploadFile = (file) => {
    const formData = new FormData();
    formData.append('file', file);
    Axios.post("https://example.com/upload", formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      })
      .then((resp) => {
        if (resp.status === 200) {
          console.log('File uploaded')
        }
      })
}

If everything goes fine, the file will be sent to the server. Now it’s time to get the file and save it some where in our server. Fortunately, Gin provides a very simply way to receive files. Gin’s Context argument (which all route handlers must have) has a FromFile method which helps you receive files from a multi-part content. Please take a look the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import (
    "net/http"
    "path/filepath"

    "github.com/gin-gonic/gin"
    "github.com/google/uuid" // To generate random file names
)

func saveFileHandler(c *gin.Context) {
    file, err := c.FromFile("file")

    // The file cannot be received.
    if err != nil {
        c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
            "message": "No file is received",
        })
        return
    }

    // Retrieve file information
    extension := filepath.Ext(file.Filename)
    // Generate random file name for the new uploaded file so it doesn't override the old file with same name
    newFileName := uuid.New().String() + extension

    // The file is received, so let's save it
    if err := c.SaveUploadedFile(file, "/some/path/on/server/" + newFileName); err != nil {
        c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
            "message": "Unable to save the file",
        })
        return
    }

    // File saved successfully. Return proper result
    c.JSON(http.StatusOK, gin.H{
        "message": "Your file has been successfully uploaded."
    })
}

As you can see in the above code, saveFileHandler is responsible for receiving and saving the file to the server. In line 10, we try to receive the uploaded file with the name file; then we check if the file is received successfully. To avoid conflicts, in line 23, we change the file name to a random string (UUID in this case). Finally, we attempt to save the file using Gin’s SaveUploadedFile method and check if the save is saved. To handle errors, we return proper responses if any errors occurred. If every goes well and we could save the file to our path, we return the 200 OK response to the client.

The above is a general example. You may want to validate the file you receive. In some cases, you just need to receive image files; so, file types should be validated. In addition, you may want to resize the received image before saving it.

How to enable CORS support in Gin

It’s about 3 months that I’m trying to do some real work in Go and my HTTP framework of choice is Gin.

After developing some REST APIs, I decided to create a frontend application to actually use them. When it comes to frontend development I usually choose ReactJS. Maybe I should write about why I like ReactJS over other frontend frameworks in the future ;)

When a client especially a web-based client wants to access an API, the server decides which clients are allowed to send requests. This is done by using called CORS which stands for Cross-origin resource sharing.

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.

For more information about CORS please check this Wikipedia article

You can manually add the required headers to each response using Gin’s Header method if you want:

1
2
3
4
5
6
7
8
9
10
func CustomHeaderAPI(c *gin.Context) {
    // Add CORS headers
    c.Header("Access-Control-Allow-Origin", "http://example.com")
    c.Header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS")

    // Prepare response
    c.JSON(http.StatusOK, gin.H{
        "message": "this response has custom headers"
    })
}

But it would be a pain in the neck to add the following lines of code to each API. To make things easier Gin supports middleware functions.

What are middleware functions? This is a good definition I found on the web:

Middleware functions are functions that have access to the request object ( req ), the response object ( res ), and the next function in the application’s request-response cycle.

You may create a middleware yourself to enable CORS support; but, we don’t want to reinvent the wheel! A group of nice people in the community has developed a library to enable CORS support in Gin. It’s called CORS gin’s middleware.

To install it:

1
go get github.com/gin-contrib/cors

After installed, simply import it:

1
import "github.com/gin-contrib/cors"

And start using it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
 "time"

 "github.com/gin-contrib/cors"
 "github.com/gin-gonic/gin"
)

func main() {
 router := gin.Default()
 // CORS for https://foo.com and https://github.com origins, allowing:
 // - PUT and PATCH methods
 // - Origin header
 // - Credentials share
 // - Preflight requests cached for 12 hours
 router.Use(cors.New(cors.Config{
  AllowOrigins:     []string{"https://foo.com"},
  AllowMethods:     []string{"PUT", "PATCH"},
  AllowHeaders:     []string{"Origin"},
  ExposeHeaders:    []string{"Content-Length"},
  AllowCredentials: true,
  AllowOriginFunc: func(origin string) bool {
   return origin == "https://github.com"
  },
  MaxAge: 12 * time.Hour,
 }))
 router.Run()
}

The above configuration is the most complete example of what capabilities the library gives you. However, you may don’t want to use them all. In fact, most of the projects’ CORS configuration are identical. To make it even simpler, cors package also has something called DefaultConfig which returns a generic default configuration mapped to localhost. In my opinion, the best way to use this library is to add your custom configurations to the DefaultConfig’s result. For example, here is my own configuration for a project:

1
2
3
4
5
6
7
8
9
10
11
12
router := gin.Default()
corsConfig := cors.DefaultConfig()

corsConfig.AllowOrigins = []string{"https://example.com"}
// To be able to send tokens to the server.
corsConfig.AllowCredentials = true

// OPTIONS method for ReactJS
corsConfig.AddAllowMethods("OPTIONS")

// Register the middleware
router.Use(cors.New(corsConfig))

Please support the library by star them on Github: https://github.com/gin-contrib/cors

I Hope it helps.