diff --git a/README.md b/README.md
index 8da47be..1c9ef3a 100644
--- a/README.md
+++ b/README.md
@@ -1,59 +1,54 @@
-# **http**
-## **Overview**
-
-The `http` Fortran package provides a **simple and convenient** way to make HTTP requests and retrieve responses. It aims to **simplify** the process of interacting with web services by providing a high-level API.
-
-___
-## **Features**
-
- The package includes the following features:
-
- 1. #### **Sending HTTP Requests:**
- - **`GET`**: Retrieve data from the server.
- - **`POST`**: Submit data to be processed by the server.
- - **`PUT`**: Replace or create resources on the server.
- - **`DELETE`**: Remove resources from the server.
- - **`PATCH`**: Partial updates to resources.
- - **`HEAD`**: Retrieve response headers without the response content.
-
- 2. #### **Data Support:**
- - Send any type of data with requests, including support for `file` uploads and `form data`.
-
- 3. #### **Response Handling:**
- - Retrieve response `content`.
- - Get the HTTP `status code` returned by the server.
- - Fetch the `length` of the response content.
- - Access response `headers`.
-
- 4. #### **Custom Headers:**
- - Include `custom headers` in requests to the server.
-
- 5. #### **Error Handling:**
- - Detect and handle unsuccessful requests gracefully, with informative `error messages`.
-
- 6. #### **Request Timeout:**
- - Set a maximum time allowed for a request to complete, improving responsiveness.
-
- 7. #### **Authentication:**
- - Authenticate requests to protected resources using standard authentication methods.
-
-## **Installation**
-
- Before building the `http-client` library, ensure that you have the necessary dependencies installed. On Ubuntu, you need to install the curl development headers. Use the following command:
+# http-client
+
+http-client is Fortran library to make HTTP requests.
+It simplifies interacting with web services by providing a high-level and
+user-friendly interface.
+
+## Features
+
+* HTTP request methods:
+ - `GET`: Retrieve data from the server.
+ - `POST`: Create new data the server.
+ - `PUT`: Replace an existing resource on the server.
+ - `DELETE`: Delete a resource from the server.
+ - `PATCH`: Partially update a resource on the server.
+ - `HEAD`: Get response headers without the response content.
+* Supported data types:
+ - URL encoded fields
+ - HTTP form data
+ - File uploads
+* Response handling:
+ - Retrieve response body (content).
+ - Get the HTTP status code returned by the server.
+ - Access response headers.
+* Setting custom request headers
+* Error handling with informative error messages
+* Setting request timeouts
+* Basic HTTP authentication
+
+## Installation
+
+Before building the http-client library, ensure that you have the necessary
+dependencies installed. On Ubuntu, you need to install the curl development
+headers. Use the following command:
```
sudo apt install -y libcurl4-openssl-dev
```
- To use `http-client` within your fpm project, add the following to your package `fpm.toml` file:
+To use http-client as a dependency in your fpm project, add the following to
+your the fpm.toml file of your package:
```toml
[dependencies]
http = { git = "https://github.com/fortran-lang/http-client.git" }
stdlib = "*"
```
-## **Usage Example**
-The following example demonstrates how to use the http package to make a **Simple GET request** and process the response
+
+## Example use
+
+The following example demonstrates how to use http-client to make a simple `GET`
+request and process the response:
```fortran
program simple_get
@@ -78,7 +73,9 @@ program simple_get
end program simple_get
```
-### Ouptut :
+
+Ouptut:
+
```
Response Code : 200
Response Length : 83
@@ -90,85 +87,99 @@ end program simple_get
"completed": false
}
```
-In this example, we make a GET request to the URL https://jsonplaceholder.typicode.com/todos/1 to retrieve JSON data. If the request is successful, we print the ***response code, content length, method, and content***. If the request fails, we print the ***error message***.
-
-## **Getting Started Guides**
-> ### ***The Complete Tutorial Guide is Currently in progress and will be available soon.***
-1. ### **Installation** π
- - Installing Dependencies (Ubuntu)
- - Setting up the Package in your Project
-
-2. ### **Making HTTP Requests** π
- - **Sending `GET` Requests**
- - *Accessing Response `Content`*
- - *Retrieving `Status Codes`*
- - *Getting Response `Headers`*
- - *Extracting `Content Length`*
- - **Sending `POST` Requests**
- - *Sending `Data` with Requests*
- - *Sending `Form Data`*
- - *Uploading `File`*
- - **Sending `PUT` Requests**
- - **Sending `PATCH` Requests**
- - **Sending `DELETE` Requests**
- - **Sending `HEAD` Requests**
-
-3. ### **Customizing Requests** βοΈ
- - Sending Custom **Headers**
- - Setting Request **Timeout**
- - **Authentication** Option
-
-4. ### **Error Handling** π€¨
- - Handling Unsuccessful Requests
- - Displaying Error Messages
-
-5. ### **Real Projects** π€
- - **GitHub organization analyzer** : Retrieve valuable information about the organization repositories
-
-
-## **Contributing to project**
-Thank you for your interest in contributing to the `http` Fortran package! Contributions from the community are valuable in improving and enhancing the functionality of the package. This section provides a guide on how to get the code, build the library, and run examples and tests.
-
-### **Get the code**
+
+In this example, we make a `GET` request to the URL
+https://jsonplaceholder.typicode.com/todos/1 to retrieve JSON data.
+If the request is successful, we print the response code, content length,
+method, and content. If the request fails, we print the error message.
+
+## Getting Started Guides
+
+To begin your journey with our package, dive into the comprehensive tutorial
+available here: [tutorial.md](./tutorial/tutorial.md)**.
+
+## Projects using http-client
+
+* [github-org-analyzer](https://github.com/rajkumardongre/github-org-analyzer):
+An example mini-project to demonstrate the use of http-client by downloading
+and parsing data from the GitHub API.
+* [fortran-xkcd](https://github.com/rajkumardongre/fortran-xkcd/tree/http_client_version):
+An fpm example project that displays the latest xkcd comic inside an X window.
+As a limitation, only images in PNG format are supported.
+The alt text will be printed to console.
+* [foropenai](https://github.com/gha3mi/foropenai): A Fortran library to access
+* the OpenAI API.
+
+If you're using http-client in your Fortran project and would like to be
+included on this list, we welcome you to contribute by creating a pull request
+(PR) and adding your project details.
+
+## Contributing to project
+
+Thank you for your interest in http-client! Contributions from the community
+are esential for improving the package. This section provides a guide on how to
+get the code, build the library, and run examples and tests.
+
+### Get the code
+
To get started, follow these steps:
Clone the repository using Git:
+
```
git clone https://github.com/fortran-lang/http-client
cd http-client
```
-### **Prerequisites**
-Before building the library, ensure that you have the necessary dependencies installed. On `Ubuntu`, you need to install the curl development headers. Use the following command:
+
+### Prerequisites
+
+Before building the library, ensure that you have the necessary dependencies
+installed. On Ubuntu, you need to install the curl development headers.
+Use the following command:
+
```
sudo apt install -y libcurl4-openssl-dev
```
-### **Build the library**
-The `http` package uses **fpm** as the build system. Make sure you have fpm `version 0.8.x` or later installed. To build the library, execute the following command within the project directory:
+### Build the library
+
+http-client uses **fpm** as the build system. Make sure you have fpm-0.8.x or
+later installed. To build the library, run the following command within the
+project directory:
+
```
fpm build
```
-### **Run examples**
-The http package provides example programs that demonstrate its usage. To run the examples, use the following command:
+
+### Run examples
+
+http-client provides example programs that demonstrate its use. To run the
+examples, use the following command:
```
fpm run --example
```
-Executing this command will execute the example programs, allowing you to see the package in action and understand how to utilize its features.
-### **Run tests**
- The http package includes a test suite to ensure its functionality is working as expected. To run the tests, execute the following command:
+Executing this command will execute the example programs, allowing you to see
+the package in action and understand how to utilize its features.
+
+### Run tests
+
+http-client includes a test suite to ensure its functionality is working as
+expected. To run the tests, type:
+
```
fpm test
```
-Running the tests will validate the behavior of the package and help identify any issues or regressions.
-### **Generating API Documentation**
+Running the tests will validate the behavior of the package and help identify
+any issues or regressions.
-Before generating API documentation, ensure that you have FORD installed on your system.
+### Generating API Documentation
-**Installation link**: [https://github.com/Fortran-FOSS-Programmers/ford#installation](https://github.com/Fortran-FOSS-Programmers/ford#installation)
+Before generating API documentation, ensure that you have FORD
+[installed on your system](https://github.com/Fortran-FOSS-Programmers/ford#installation).
Once FORD is set up, execute the following command to build the API documentation:
@@ -176,14 +187,14 @@ Once FORD is set up, execute the following command to build the API documentatio
ford ford.md
```
-### **Supported compilers**
+### Supported compilers
http-client is known to work with the following compilers:
* GFortran 11 & 12 (tested in CI)
* Intel OneAPI ifx v2023.1.0 and ifort classic v2021.9.0
-### **Contributing guidelines**
+### Contributing guidelines
When contributing to the http Fortran package, please keep the following guidelines in mind:
@@ -194,6 +205,6 @@ When contributing to the http Fortran package, please keep the following guideli
* Make sure to test your changes and ensure they do not introduce regressions or break existing functionality.
* Submit a pull request with your changes, providing a clear explanation of the problem you are solving and the approach you have taken.
-We appreciate your contributions and look forward to your valuable input in improving the http Fortran package.
+We appreciate your contributions and look forward to your valuable input in improving http-client.
-Happy coding!
+Happy coding!π
\ No newline at end of file
diff --git a/fpm.toml b/fpm.toml
index 89974d4..5eff75d 100644
--- a/fpm.toml
+++ b/fpm.toml
@@ -19,5 +19,5 @@ implicit-external = false
source-form = "free"
[dependencies]
-fortran-curl = {git = "https://github.com/interkosmos/fortran-curl.git"}
+fortran-curl = {git = "https://github.com/interkosmos/fortran-curl.git", tag = "0.5.0"}
stdlib = "*"
\ No newline at end of file
diff --git a/src/http/http_request.f90 b/src/http/http_request.f90
index 190a34d..e3a4baf 100644
--- a/src/http/http_request.f90
+++ b/src/http/http_request.f90
@@ -43,6 +43,7 @@ module http_request
type(pair_type), allocatable :: file
!! Used to store information about files to be sent in HTTP requests.
integer(kind=int64) :: timeout
+ !! **`Timeout`** value for the request in **seconds**.
type(pair_type), allocatable :: auth
!! Stores the username and password for Authentication
end type request_type
diff --git a/test/test_get.f90 b/test/test_get.f90
index c10b5bc..4e0440b 100644
--- a/test/test_get.f90
+++ b/test/test_get.f90
@@ -22,9 +22,8 @@ program test_get
pair_type('Set-Cookie', 'Theme-Light'), &
pair_type('Set-Cookie', 'Auth-Token: 12345'), &
pair_type('User-Agent', 'my user agent') &
- ]
+ ]
- ! res = request(url='https://reqres.in/api/users/1', header=request_header)
res = request(url='https://dummyjson.com/products/1', header=request_header)
msg = 'test_get: '
diff --git a/tutorial/example-project/github-org-analyzer.md b/tutorial/example-project/github-org-analyzer.md
new file mode 100644
index 0000000..1a5288f
--- /dev/null
+++ b/tutorial/example-project/github-org-analyzer.md
@@ -0,0 +1,224 @@
+# Building a [GitHub Organization Analyzer](https://github.com/rajkumardongre/github-org-analyzer) in Fortran, using `http-client` π
+
+In this tutorial, we'll create a simple Fortran program that uses the [GitHub API](https://docs.github.com/en/rest?apiVersion=2022-11-28) to retrieve and display all the repositories of the [`fortran-lang`](https://github.com/fortran-lang) organization. We'll use the [`http-client`](https://github.com/fortran-lang/http-client) and [`json-fortran`](https://github.com/jacobwilliams/json-fortran) libraries to make API requests and handle JSON responses.
+
+# Prerequisite π©
+
+Before proceeding with building the GitHub Organization Analyzer library and running the program, it's crucial to ensure that you have at least [`fpm`](https://fpm.fortran-lang.org/) v0.9.0 (Fortran Package Manager) installed. Additionally, there is a single dependency required for the [`http-client`](https://github.com/fortran-lang/http-client) library utilized in this project. Please follow the steps provided below to set up your environment:
+
+### Step 1: Install fpm
+
+[`fpm`](https://fpm.fortran-lang.org/) is the Fortran Package Manager used for building and managing Fortran projects. If you do not currently have `fpm` installed, you can follow the installation instructions available on the official `fpm` repository to install version v0.9.0 or a more recent version. The installation guide can be found here: [Installation Guide](https://fpm.fortran-lang.org/install/index.html).
+
+
+### Step 2: Install libcurl Development Headers
+
+The `http-client` library requires the [`libcurl`](https://curl.se/libcurl/) development headers to be installed. On Ubuntu-based systems, you can install the required dependencies using the following command:
+
+```bash
+sudo apt install -y libcurl4-openssl-dev
+```
+
+This command will install the necessary development headers for libcurl, enabling the `http-client` library to make API requests to fetch data from the GitHub API.
+
+Once you have `fpm` installed and the required dependencies set up, you are ready to proceed with building and running the GitHub Organization Analyzer project.π
+
+# Let's Start Building π¨βπ»
+
+### Step 1: Set up the Project
+
+>**Note : This requires at least fpm v0.9.0.**
+
+1. Open your terminal or command prompt and create a new directory for the project:
+
+```bash
+fpm new github-org-analyzer
+cd github-org-analyzer
+```
+
+2. The project structure will look like this:
+
+```
+.
+βββ README.md
+βββ app
+β βββ main.f90
+βββ fpm.toml
+βββ src
+β βββ github-org-analyzer.f90
+βββ test
+ βββ check.f90
+```
+
+### Step 2: Add Dependencies to `fpm.toml`
+
+Open the `fpm.toml` file and add the following dependencies:
+
+```toml
+[dependencies]
+http = { git = "https://github.com/fortran-lang/http-client.git" }
+stdlib = "*"
+json-fortran = { git = "https://github.com/jacobwilliams/json-fortran.git" }
+```
+
+### Step 3: Import the Libraries
+
+Open the `github-org-analyzer.f90` file in the `src` folder and import the required libraries:
+
+```fortran
+module github_org_analyzer
+ use json_module, only : json_file
+ use http, only : request, response_type
+ use stdlib_strings, only : to_string
+
+ ! ... (subroutine to be added later)
+end module github_org_analyzer
+```
+* `json_module` : This module provides functionalities for parsing JSON content, and we use it here to work with JSON data obtained from the GitHub API.
+
+* The `http` module enables us to make API calls and send HTTP requests to fetch data from the GitHub API.
+
+* `to_string` : We use this function to convert integers to their string representations
+
+### Step 4: Create the `print_org_repositories` Subroutine
+
+Now let's write the `print_org_repositories` subroutine, which fetches and prints all the repositories of the "fortran-lang" organization using the GitHub API. This subroutine utilizes the `http-client` and `json-fortran` libraries to make API requests and handle JSON responses.
+
+1. Open the `github_org_analyzer.f90` file in the `src` folder.
+
+2. Create the `print_org_repositories` subroutine within the `github_org_analyzer` module:
+
+```fortran
+module github_org_analyzer
+ use json_module, only : json_file
+ use http, only : request, response_type
+ use stdlib_strings, only : to_string
+
+ implicit none
+ private
+
+ ! Declare the function as public to make it accessible to other modules
+ public :: print_org_repositories
+contains
+ subroutine print_org_repositories()
+ !! subroutine to print all repositories of fortran-lang organization
+ character(*), parameter :: api_url = 'https://api.github.com/orgs/fortran-lang/repos'
+ !! Stores GitHub API URL for fetching repositories
+ integer :: i
+ !! counter to traverse all the repos return by api
+ character(:), allocatable :: count
+ !! stores the string equivalent of counter, i.e variable i
+ character(:), allocatable :: value
+ !! stores the individual github repo name for each traversal
+ type(json_file) :: json
+ !! give the ability to parse the json content
+ type(response_type) :: response
+ !! stores the response from the github api
+ logical :: found
+ !! flag for weather the current repo found or not
+
+ ! Make an HTTP GET request to the API URL and store the response in the `response` variable
+ response = request(url=api_url)
+
+ ! Checking for any errors. If an error occurs during the HTTP call, the `ok`
+ ! attribute will be set to .false., and the `err_msg` attribute will contain
+ ! the reason for the error.
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Fortran lang All repositories:'
+
+ ! Initialize the `json` object to parse the JSON content
+ call json%initialize()
+
+ ! Deserialize the JSON response(parsing the json)
+ call json%deserialize(response%content)
+
+ ! Traverse Repositories and Print Names
+
+ ! Counter to traverse all repos one by one
+ i = 0
+ ! Enter the loop to traverse all repositories while they exist
+ do
+ ! Increment the counter for the next repository
+ i = i + 1
+
+ ! Convert the updated counter to its string representation and store it in count variable
+ count = to_string(i)
+
+ ! Fetch the name of the current repository (based on the `i` counter) and check if it exists
+ call json%get('['//count//'].name', value, found)
+ if(.not.found) exit
+
+ ! If the repository name exists (`found` is true), print the repository number and name
+ print *, count//'. ', value
+
+ end do
+ end if
+ end subroutine print_org_repositories
+end module github_org_analyzer
+```
+
+### Step 5: Call the Subroutine in `main.f90`
+
+Open the `main.f90` file in the `app` folder and call the `print_org_repositories` subroutine:
+
+```fortran
+program main
+ ! importing `print_org_repositories` subroutine
+ use github_org_analyzer, only: print_org_repositories
+ implicit none
+
+ ! Print all repositories inside Fortran lang organization'
+ call print_org_repositories()
+end program main
+```
+
+### Step 6: Run the Program
+
+Now that you've completed all the steps, it's time to run the program:
+
+```
+fpm run
+```
+
+You should see the following outputπ§:
+
+```
+Fortran lang All repositories:
+1. fftpack
+2. vscode-fortran-support
+3. stdlib
+4. stdlib-docs
+5. fpm
+6. fortran-lang.org
+7. talks
+8. benchmarks
+9. fpm-registry
+10. setup-fpm
+11. stdlib-cmake-example
+12. .github
+13. fortran-forum-article-template
+14. test-drive
+15. fpm-haskell
+16. fpm-metadata
+17. minpack
+18. fortls
+19. fpm-docs
+20. homebrew-fortran
+21. playground
+22. contributor-graph
+23. webpage
+24. assets
+25. registry
+26. fpm-on-wheels
+27. http-client
+```
+
+πCongratulations! You've successfully built a simple Fortran program that fetches and displays the repositories of the "fortran-lang" organization using the GitHub API.
+
+π¨βπ» Feel free to explore the full capabilities of the [`http-client`](https://github.com/fortran-lang/http-client) library to create more advanced projects!
+
+Moreover, we highly encourage you to actively contribute to the [github-org-analyzer](https://github.com/rajkumardongre/github-org-analyzer) project. You have the opportunity to propose and implement new features, address any bugs, and enhance the existing code.
+
+Happy Coding! π
\ No newline at end of file
diff --git a/tutorial/tutorial.md b/tutorial/tutorial.md
new file mode 100644
index 0000000..7c4fb55
--- /dev/null
+++ b/tutorial/tutorial.md
@@ -0,0 +1,611 @@
+# **Welcome**
+### *Welcome to the Getting Started Guides.* π
+
+### **Table of contents:** π
+
+1. ### [**Installation** π](#installation)
+
+2. ### [**Making HTTP Requests** π](#making-http-requests-f09f9a80-1)
+ - [**Sending `GET` Requests**](#sending-get-requests)
+ - [*Accessing Response `Content`*](#accessing-response-content)
+ - [*Extracting `Content Length`*](#extracting-content-length)
+ - [*Retrieving `Status Codes`*](#retrieving-status-codes)
+ - [*Handling `Errors`*](#handling-errors)
+ - [*Getting Response `Headers`*](#getting-response-headers)
+ - [*Understanding `pair_type` derived type*](#understanding-pair_type-derived-type)
+ - [*Sending Custom `Headers`*](#sending-custom-headers)
+ - [*Setting Request `Timeout`*](#setting-request-timeout)
+ - [*Setting `Authentication`*](#setting-authentication)
+ - [**Sending `POST` Requests**](#sending-post-request)
+ - [*Sending Data using `data`*](#sending-data-using-data)
+ - [*Sending Data using `form`*](#sending-data-using-form)
+ - [*Sending Data using `file`*](#sending-data-using-file)
+ - [**Sending `PUT` Requests**](#sending-put-requests)
+ - [**Sending `PATCH` Requests**](#sending-patch-requests)
+ - [**Sending `DELETE` Requests**](#sending-delete-requests)
+ - [**Sending `HEAD` Requests**](#sending-head-requests)
+
+3. ### [**Real Projects** π€](#real-projects-f09fa496-1)
+
+
+1. # **Installation** π
+
+ Before building the `http-client` library, ensure that you have the necessary dependencies installed. On Ubuntu, you need to install the curl development headers. Use the following command:
+
+```
+sudo apt install -y libcurl4-openssl-dev
+```
+
+ To use `http-client` within your fpm project, add the following to your package `fpm.toml` file:
+
+```toml
+[dependencies]
+http = { git = "https://github.com/fortran-lang/http-client.git" }
+stdlib = "*"
+```
+
+2. # **Making HTTP Requests** π
+## **Sending `GET` Requests**
+Let's First Import `http` package into our program
+```fortran
+program send_get_request
+ use http, only : request, response_type
+ ...
+end program send_get_request
+```
+For making a `GET` request we required to import `request` function which is use to configure our HTTP request(like setting request `URL`, `method`, `headers` and etc.).
+
+The `request()` function returns a `response_type` object, containing server response. so we also have to import `response_type` derived type to store server response, like below.
+
+```fortran
+type(response_type) :: response
+```
+Now Let's make the HTTP `GET` request.
+```fortran
+response = request(url='https://httpbin.org/get')
+```
+The above code will make a HTTP `GET` request to https://httpbin.org/get url and store the server response in `response` variable.
+
+Now let's study the `response` object in detail. π§
+
+The `response` object contain rich information about server response. It contains following attribute.
+
+* `url` : The URL of the request.
+* `method` : The HTTP method of the request.
+* `content` : The content of the server response.
+* `err_msg` : The Error message if the response was not successful.
+* `status_code` : The HTTP status code of the response.
+* `content_length` : length of the response content.
+* `ok` : Boolean flag, which indicates weather the request was sucessfull or not.
+* `header` : An array of **name-value** pairs representing response headers.
+
+### **Accessing Response `Content`**
+To access the content of the server's response, use the `content` attribute:
+
+```fortran
+print *, 'Response Content: ', response%content
+```
+### **Extracting `Content Length`**
+
+You can retrieve the response content length using the `content_length` attribute:
+
+```fortran
+print *, 'Response Length: ', response%content_length
+```
+
+### **Retrieving `Status Codes`**
+
+HTTP response [`status codes`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) indicate whether a request was successful or not. The status code is stored in the `status_code` attribute:
+
+```fortran
+print *, 'Response Code: ', response%status_code
+```
+### **Handling `Errors`**
+
+Ensuring robust error handling is crucial when working with HTTP requests. You can verify the success of your request by inspecting the `ok` attribute in the response. If the attribute is `.false.`, it indicates a request failure. Conversely, if it's `.true.`, the HTTP request was successful.
+
+```fortran
+print *, 'Request is Successful: ', response%ok
+```
+
+In cases where the request encounters an issue, the `err_msg` attribute in the response will contain information about the reason for the failure. It's essential to handle errors gracefully:
+
+```fortran
+if (.not. response%ok) then
+ print *, response%err_msg
+ ! Code for handling the failed request
+else
+ ! Code for processing a successful request
+end if
+```
+
+> **Note:**
+>
+> Always prioritize checking the `ok` attribute of the response to identify any request failures. Incorporate the provided code snippet whenever you are processing the response to ensure comprehensive error management. This practice will help you build more robust and reliable HTTP interactions.
+
+### **Getting Response `Headers`**
+
+The response headers are stored as array of [`pair_type`](#pair_type-derived-type) object in `header` attribute.
+
+```fortran
+print *, 'Response Header Size : ', size(response%header)
+```
+We can iterate over all the `headers` in this way.
+```fortran
+implicit none
+character(:), allocatable :: header_name, header_value
+integer :: i
+!...
+!...
+do i=1, size(response%header)
+ header_name = response%header(i)%name
+ header_value = response%header(i)%value
+ print *,header_name, ': ', header_value
+end do
+```
+
+Complete program for sending `GET` request :
+```fortran
+program get
+ use http, only : request, response_type
+ implicit none
+ type(response_type) :: response
+ character(:), allocatable :: header_name, header_value
+ integer :: i
+
+ ! Making a GET request
+ response = request(url='https://httpbin.org/get')
+
+ ! Checking any errors
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Status Code : ', response%status_code
+ print *, 'Content : ', response%content
+ print *, 'Content Length : ', response%content_length
+ print *, 'Response Header Size : ', size(response%header)
+
+ print *, 'All response headers :'
+ ! Traversing over all response headers
+ do i=1, size(response%header)
+ ! Extracting header name
+ header_name = response%header(i)%name
+ ! Extracting corresponding header value
+ header_value = response%header(i)%value
+ print *, header_name, ': ', header_value
+ end do
+ end if
+end program get
+```
+
+
+Before we proceed, it's crucial to grasp the `pair_type` derived type, as we will be utilizing it in various scenarios.
+
+### **Understanding `pair_type` derived type**
+
+It is use to store a **name-value pair**.
+
+```fortran
+! pair_type defination
+type :: pair_type
+ character(:), allocatable :: name, value
+end type pair_type
+```
+It serves various purposes within the `http` package.
+
+1. Storing request and response `headers` as array of `pair_type` objects, where :
+ - `name` represent the header name.
+ - `value` represent the header value.
+
+2. Representing fields in a url-encoded **HTTP `form`**:
+ - `name` to represent the form field name.
+ - `value` to represent the form field value.
+
+3. Storing information about the `file` to upload:
+ - `name` to represent the name of the file.
+ - `value` to represent the path of the file on the local system.
+
+4. Storing authentication detail, require to authenticate the request.
+ - `name` to represent the **username**
+ - `value` to represent the **password**
+
+
+### **Sending Custom `Headers`**
+
+Much like [response headers](#getting-response-headers), request headers are also stored as an array of [`pair_type`](#pair_type-derived-type) objects. These headers are provided through the `header` attribute of the `request()` function.
+
+```fortran
+program send_headers
+ use http, only : request, response_type, pair_type
+ implicit none
+ type(response_type) :: response
+ type(pair_type), allocatable :: req_headers(:) ! will store request headers
+
+ ! Storing request header in array of pair_type object, where each pair_type
+ ! object represents a single header. (in header-name,header-value format)
+ req_headers = [ &
+ pair_type('my-header-1', 'Hello World'), &
+ pair_type('my-header-2', 'Hello Universe'), &
+ pair_type('Set-Cookie', 'Theme-Light'), &
+ pair_type('Set-Cookie', 'Auth-Token: 12345'), &
+ pair_type('User-Agent', 'my user agent') &
+ ]
+
+ ! Congiguring request with API URL and request headers
+ response = request( &
+ url='https://httpbin.org/headers', &
+ header=req_headers &
+ )
+
+ ! Checking for any error
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Content : ', response%content
+ end if
+end program send_headers
+```
+### **Setting Request `Timeout`**
+
+The overall `timeout` for the request, which is the time the entire request must complete. The value of this timeout(**in seconds**) can be set by passing the `timeout` parameter to the `request()` function.
+
+```fortran
+program timeout
+ ! The request below is designed to take more than 10 seconds to complete,
+ ! but we set the timeout value to 5 seconds.
+ ! As a result, the request will fail with an error message that says
+ ! "Timeout was reached".
+ use http, only: response_type, request
+ implicit none
+ type(response_type) :: response
+
+ ! Delay in response for 10 seconds
+ response = request( &
+ url='https://httpbin.org/delay/10', &
+ timeout=5 &
+ )
+
+ ! Checking for any error
+ if(.not. response%ok) then
+ print *,'Error message : ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program timeout
+```
+
+### **Setting `Authentication`**
+
+We can set a Basic Authentication to the request by setting `auth` parameter to the `request()` function.
+
+The `auth` parameter takes `pair_type` object as value, in which `name` represent the **username** and `value` represent the **password**.
+
+```fortran
+program authentication
+ ! Making request with HTTP Basic Auth
+ use http, only: response_type, request, pair_type
+ implicit none
+ type(response_type) :: response
+ type(pair_type) :: req_auth
+
+ ! setting username and password required for authentication
+ req_auth = pair_type('user', 'passwd')
+
+ ! Configuring request
+ response = request( &
+ url='https://httpbin.org/basic-auth/user/passwd', &
+ auth=req_auth &
+ )
+
+ ! Checking for any error
+ if(.not. response%ok) then
+ print *,'Error message : ', response%err_msg
+ else
+ print *, 'Response Code : ', response%status_code
+ print *, 'Response Content : ', response%content
+ end if
+end program authentication
+```
+Output :
+```bash
+ Response Code : 200
+ Response Content : {
+ "authenticated": true,
+ "user": "user"
+}
+```
+> **Note :**
+>
+>It sends the **username** and **password** over the network **in plain text, easily captured by others**.
+
+## **Sending `POST` Request**
+
+An HTTP `POST` request is used to send data to a server, where data are shared via the body of a request. You can send a `POST` request by setting `method` parameter of `request()` function to `HTTP_POST`.
+
+```fortran
+program post
+ use http, only: response_type, request, HTTP_POST
+ implicit none
+ type(response_type) :: response
+
+ ! Setting HTTP Method for request
+ response = request( &
+ url='https://example.com/post', &
+ method=HTTP_POST &
+ )
+
+end program post
+```
+
+Within the `http` package, there are several options for sending data, accomplished through three mainly parameters: `data`, `form`, and `file` within the `request()` function.
+
+Now let's see each of them π§
+
+### **Sending Data using `data`**
+
+The `data` parameter allows us to transmit a variety of data. When utilizing this parameter, it's essential to include the `Content-Type` header, indicating the type of data being transmitted.
+
+**Sending plain text :**
+```fortran
+program post
+ ! This program demonstrates sending plain text data using POST request
+ use http, only: response_type, request, HTTP_POST, pair_type
+ implicit none
+ type(response_type) :: response
+ character(:), allocatable :: req_data
+ type(pair_type), allocatable :: req_header(:)
+
+ ! Setting Content-type header for sending plain text
+ req_header = [pair_type('Content-Type', 'text/plain')]
+
+ ! plain-text data we want to send
+ req_data = 'Hello, this data needs to be sent to the server.'
+
+ ! Setting HTTP POST method and Data to be send on server
+ response = request( &
+ url='https://httpbin.org/post', &
+ method=HTTP_POST, &
+ data=req_data, &
+ header=req_header &
+ )
+
+ ! Checking for any error
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program post
+```
+**Sending JSON data :**
+```fortran
+program post
+ ! This program demonstrates sending JSON data using POST request.
+ use http, only: response_type, request, HTTP_POST, pair_type
+ implicit none
+ type(response_type) :: response
+ character(:), allocatable :: json_data
+ type(pair_type), allocatable :: req_header(:)
+
+ ! Setting Content-type header for sending JSON
+ req_header = [pair_type('Content-Type', 'application/json')]
+
+ ! JSON data we want to send
+ json_data = '{"name":"Jhon","role":"developer"}'
+
+ ! Configuring request with HTTP Method, JSON data and request headers
+ response = request( &
+ url='https://httpbin.org/post',&
+ method=HTTP_POST, &
+ data=json_data, &
+ header=req_header &
+ )
+
+ ! Checking for any errors
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program post
+```
+### **Sending Data using `form`**
+
+When you need to transmit HTML form data to the server, you can utilize the `form` parameter to pass the data. The `form` parameter accepts an array of `pair_type` objects, where each `pair_type` object represents a **single form field**.
+
+The `form` data is initially URL encoded and then sent as the request's body. If no `Content-type` header is specified, a default `Content-type` header with the value `application/x-www-form-urlencoded` will be automatically set.
+
+```fortran
+program post_form_data
+ ! This program demonstrates sending Form data using a POST request.
+ use http, only: response_type, request, HTTP_POST, pair_type
+ implicit none
+ type(response_type) :: response
+ type(pair_type), allocatable :: form_data(:)
+
+ ! Store form data in an array of pair_type objects, where each
+ ! pair_type object represents a single form field
+ form_data = [ &
+ pair_type('name', 'John'), &
+ pair_type('job', 'Developer') &
+ ]
+
+ ! Make the HTTP POST request with the form data
+ response = request( &
+ url='https://httpbin.org/post', &
+ method=HTTP_POST, &
+ form=form_data &
+ )
+
+ ! Checking for any errors
+ if (.not. response%ok) then
+ print *, 'Error message: ', response%err_msg
+ else
+ print *, 'Response Content: ', response%content
+ end if
+end program post_form_data
+```
+
+### **Sending Data using `file`**
+
+When you need to send a file (such as .png, .jpg, .txt, etc.) to a server, you can utilize the `file` parameter within the `request()` function. This parameter takes a `pair_type` object as its value. In this `pair_type` object, the `name` member specifies the field name under which the file will be sent to the server, and the `value` member represents the path to the file you want to send.
+
+If you don't explicitly provide a `Content-type` header, a default `Content-type` header with the value `multipart/form-data` will be automatically set.
+
+```fortran
+program post_file
+
+ ! This program demonstrates sending a File using a POST request.
+
+ use http, only : request, response_type, HTTP_POST, pair_type
+ implicit none
+ type(response_type) :: response
+ type(pair_type) :: file_data
+
+ ! Specify the pair_type object as ('', '/path/to/file.txt')
+ file_data = pair_type('my_file', '/path/to/file.txt')
+
+ ! Make the HTTP POST request with the file data
+ response = request( &
+ url='https://httpbin.org/post', &
+ method=HTTP_POST, &
+ file=file_data &
+ )
+
+ ! Checking for any errors
+ if (.not. response%ok) then
+ print *, 'Error message: ', response%err_msg
+ else
+ print *, 'Response Content: ', response%content
+ end if
+end program post_file
+```
+
+#### **Note** :
+- If `data` member is provided, it takes the **highest priority** and is sent as the body of the request. Any other provided `file` or `form` members will be ignored, and only the `data` member will be included in the request body.
+
+- If both `form` and `file` members are provided, both `form` and `file` data are included as part of the request body. A default `Content-type` header with value `multipart/form-data` will be set if no `Content-type` header is provided.
+
+- If `data`, `form`, and `file` are all provided, only `data` is sent, and the `form` and `file` inputs are ignored.
+
+## **Sending `PUT` Requests**
+
+Sending a `PUT` request is quite similar to sending a [`POST`](#sending-post-request) request. In this case, the `method` parameter should be set to `HTTP_PUT`.
+
+```fortran
+program put
+ ! This program demonstrates sending JSON data with PUT request.
+ use http, only: response_type, request, HTTP_PUT, pair_type
+ implicit none
+ type(response_type) :: response
+ character(:), allocatable :: json_data
+ type(pair_type), allocatable :: req_header(:)
+
+ req_header = [pair_type('Content-Type', 'application/json')]
+
+ ! JSON data we want to send
+ json_data = '{"name":"Jhon","role":"developer"}'
+
+ response = request( &
+ url='https://httpbin.org/put',&
+ method=HTTP_PUT, &
+ data=json_data, &
+ header=req_header &
+ )
+
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program put
+```
+
+## **Sending `PATCH` Requests**
+
+Sending a `PATCH` request is quite similar to sending a [`POST`](#sending-post-request) request. In this case, the `method` parameter should be set to `HTTP_PATCH`.
+
+```fortran
+program patch
+ ! This program demonstrates sending JSON data with PATCH request.
+ use http, only: response_type, request, HTTP_PATCH, pair_type
+ implicit none
+ type(response_type) :: response
+ character(:), allocatable :: json_data
+ type(pair_type), allocatable :: req_header(:)
+
+ req_header = [pair_type('Content-Type', 'application/json')]
+
+ ! JSON data we want to send
+ json_data = '{"name":"Jhon","role":"developer"}'
+
+ response = request( &
+ url='https://httpbin.org/patch',&
+ method=HTTP_PATCH, &
+ data=json_data, &
+ header=req_header &
+ )
+
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program patch
+```
+
+## **Sending `DELETE` Requests**
+
+To send a `DELETE` request, simply set the `method` parameter to `HTTP_DELETE`.
+
+```fortran
+program delete
+ ! This program demonstrates sending DELETE request.
+ use http, only: response_type, request, HTTP_DELETE
+ implicit none
+ type(response_type) :: response
+
+ response = request( &
+ url='https://httpbin.org/delete',&
+ method=HTTP_DELETE &
+ )
+
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Response Content : ', response%content
+ end if
+end program delete
+```
+
+## **Sending `HEAD` Requests**
+
+To send a `HEAD` request, simply set the `method` parameter to `HTTP_HEAD`.
+
+```fortran
+program head
+ ! This program demonstrates sending HEAD request.
+ use http, only: response_type, request, HTTP_HEAD
+ implicit none
+ type(response_type) :: response
+
+ response = request( &
+ url='https://www.w3schools.com/python/demopage.php',&
+ method=HTTP_HEAD &
+ )
+
+ if(.not. response%ok) then
+ print *, 'Request Fail: ', response%err_msg
+ else
+ print *, 'Request is Successfull!!!'
+ end if
+end program head
+```
+
+3. # **Real Projects** π€
+
+- [**GitHub organization analyzer**](example-project/github-org-analyzer.md) :
+
+ This Fortran project **provides procedures to analyze GitHub organizations and retrieve valuable information about their repositories**. By leveraging the power of the `http-client` package, this analyzer fetches data from the GitHub API to generate insightful reports.
+
+- There are many more to come...
\ No newline at end of file