<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ computer networking - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ computer networking - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 13 May 2026 11:57:55 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/computer-networking/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Understanding Proxies and Reverse Proxies: Your Gateway to Secure Networking ]]>
                </title>
                <description>
                    <![CDATA[ As our lives become increasingly digital, the need for secure networking solutions is more important than ever. Whether you’re browsing the web or managing a corporate network, the role of proxies is  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understanding-proxies-and-reverse-proxies-your-gateway-to-secure-networking/</link>
                <guid isPermaLink="false">69e7e351e4367278149e58cb</guid>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ proxy ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 21 Apr 2026 20:51:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/8cf050c7-173f-4298-90e0-8627613c0cab.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As our lives become increasingly digital, the need for secure networking solutions is more important than ever.</p>
<p>Whether you’re browsing the web or managing a corporate network, the role of proxies is critical in maintaining security and efficiency. This article will help you understand what proxies are and how they can enhance your online experiences.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-what-is-a-proxy">What is a Proxy?</a></p>
</li>
<li><p><a href="#heading-benefits-of-forward-proxies">Benefits of Forward Proxies</a></p>
</li>
<li><p><a href="#heading-understanding-reverse-proxies">Understanding Reverse Proxies</a></p>
</li>
<li><p><a href="#heading-other-proxy-types">Other Proxy Types</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-proxy"><strong>What is a Proxy?</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/6a13adaa-8286-45da-9a6c-8d32d183aff1.png" alt="Proxy Server" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>A <a href="https://www.freecodecamp.org/news/a-developers-guide-to-proxy-servers/">proxy server</a> serves as an intermediary between your private network and the public internet.</p>
<p>Think of it as a middleman that manages communications between your devices and the internet. When you send a request to access a website, the proxy server receives it and forwards it to the intended destination, acting on your behalf.</p>
<p>In simpler terms, a proxy server provides a layer of security and privacy by masking your internet activities. It helps ensure that all your online requests are routed appropriately while protecting your network from threats like hackers or malicious sites.</p>
<p>This is especially useful for large networks, where direct internet access can expose vulnerabilities and security risks.</p>
<h2 id="heading-benefits-of-forward-proxies"><strong>Benefits of Forward Proxies</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/f29e42e8-1ee8-46e4-8d22-6002357c623d.png" alt="Forward proxy" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><a href="https://www.radware.com/cyberpedia/application-delivery/forward-proxy/">Forward proxies</a> offer a multitude of advantages that can enhance network performance and security.</p>
<p>Firstly, they help regulate internet traffic. By controlling the flow of data, you can prevent harmful websites from accessing your network. Also, forward proxies conceal individual IP addresses and present a single interface to the outside world, enhancing your privacy.</p>
<p>Another key benefit of forward proxies is the ability to monitor and log user activity. Organisations can track website visits and the duration of each session, offering insights into user behaviour and accountability.</p>
<p>They also offer an opportunity to bypass restricted content. In highly regulated environments, proxies help in accessing content that might otherwise be restricted.</p>
<p>Last but not least, forward proxies improve speed and efficiency by caching frequently accessed websites. This means these websites load more quickly as they're retrieved from the cache instead of being retrieved from the internet each time.</p>
<h2 id="heading-understanding-reverse-proxies"><strong>Understanding Reverse Proxies</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/453a743e-4531-4a72-b907-7b499f7aca28.png" alt="453a743e-4531-4a72-b907-7b499f7aca28" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><a href="https://www.cloudflare.com/en-gb/learning/cdn/glossary/reverse-proxy/">Reverse proxies</a> work in the opposite way by managing the traffic coming into a network rather than the traffic going out. They're particularly useful in protecting servers, enhancing security by creating a single point of entry to the network. This limits direct exposure of servers to potential threats, as external users interact with the reverse proxy rather than the server itself.</p>
<p>A significant benefit of reverse proxies is <a href="https://www.ibm.com/think/topics/load-balancing">load balancing</a>. In complex networks, incoming traffic can overwhelm servers, leading to downtimes. Reverse proxies distribute this traffic evenly, preventing any single server from being overloaded. This ensures smooth operations and maximises server uptime.</p>
<p>Reverse proxies can also protect against <a href="https://www.freecodecamp.org/news/protect-against-ddos-attacks/">Distributed Denial of Service (DDoS)</a> attacks by acting as a buffer. They intercept and block malicious traffic before it reaches the servers, providing an extra layer of security. Reverse proxies also conceal server IP addresses, making it harder for hackers to target specific servers directly.</p>
<h2 id="heading-other-proxy-types"><strong>Other Proxy Types</strong></h2>
<p>There are even more proxy solutions depending on your specific network needs.</p>
<p><a href="https://www.freecodecamp.org/news/us-residential-proxy-why-local-ip-accuracy-matters-for-serp-ads-pricing/">Residential proxies</a> provide anonymous browsing by routing traffic through real IP addresses assigned by Internet Service Providers (ISPs) to actual households. This makes the traffic appear highly legitimate, significantly reducing the chances of detection or blocking by target websites.</p>
<p>They are particularly effective for web scraping, account management, and accessing geo-restricted content because websites treat them as genuine users. But they tend to be more expensive due to the scarcity and operational complexity of maintaining real residential IP pools. Despite the cost, they're often the preferred choice when reliability and stealth are critical.</p>
<p>ISP proxies, also known as static residential proxies, combine the advantages of both residential and datacenter proxies. They're hosted on servers but use IP addresses assigned by ISPs, which gives them the appearance of residential traffic while maintaining high speed and stability.</p>
<p>These proxies are ideal for long-running sessions, automation workflows, and large-scale scraping operations where consistency is important. Businesses often rely on ISP proxies when they need both performance and trustworthiness without frequent IP rotation. They strike a balance between cost, speed, and legitimacy, making them a versatile option.</p>
<p><a href="https://www.scrapingbee.com/blog/isp-proxy/">Datacenter proxies</a> are generated from cloud servers or data centers rather than real residential networks. They're known for their high speed, low latency, and cost-effectiveness, making them suitable for tasks that require rapid data extraction or bulk operations.</p>
<p>But because they originate from identifiable server ranges, websites can more easily detect and block them compared to residential or ISP proxies. They're best used for non-sensitive scraping tasks, testing environments, or scenarios where scale and speed are prioritized over stealth. Many teams use them as a first layer before switching to more sophisticated proxy types if needed.</p>
<p><a href="https://fleetproxy.io/blog/how-to-buy-mobile-proxies-for-web-testing">Mobile proxies</a> route traffic through IP addresses assigned to mobile devices via cellular networks such as 4G or 5G. These IPs are highly trusted by websites because mobile carriers use techniques like carrier-grade NAT, where many users share the same IP, making blocking less effective.</p>
<p>As a result, mobile proxies offer the highest level of anonymity and are extremely effective at bypassing strict anti-bot and anti-scraping mechanisms. They're commonly used for social media automation, ad verification, and accessing mobile-specific content. While they're typically the most expensive option, their success rate in difficult environments often justifies the investment.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Proxies  –  be it forward or reverse  –&nbsp;represent a crucial piece of today’s network security and efficiency puzzle. Forward proxies protect client devices by regulating outgoing internet traffic and masking individual identities, while reverse proxies safeguard servers by controlling incoming traffic and offering load balancing.</p>
<p>By leveraging these proxy solutions, you can ensure enhanced network security and improved functionality. Whether you’re a business looking to protect server data or a user interested in anonymous browsing, choosing the right proxy solution can make a significant difference in maintaining a secure and efficient digital presence.</p>
<p><em>Join my</em> <a href="https://applyaito.substack.com/"><em><strong>Applied AI newsletter</strong></em></a> <em>to learn how to build and ship real AI systems. Practical projects, production-ready code, and direct Q&amp;A. You can also</em> <a href="https://www.linkedin.com/in/manishmshiva/"><em><strong>connect with me on</strong></em> <em><strong>LinkedIn</strong></em></a><em><strong>.</strong></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Computer Networking Fundamentals ]]>
                </title>
                <description>
                    <![CDATA[ How does the Internet really work? For many technical jobs it is important to understand computer networking. We just posted a massive 12-hour course that will give you a deep dive into computer networking. Here are the sections covered in this compr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/computer-networking-fundamentals/</link>
                <guid isPermaLink="false">6995e32376926e7d4ed2c700</guid>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 18 Feb 2026 16:04:51 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1771430669203/458df2d4-6920-4f6f-a30a-aecfa4635309.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>How does the Internet really work?</p>
<p>For many technical jobs it is important to understand computer networking. We just posted a massive 12-hour course that will give you a deep dive into computer networking.</p>
<p>Here are the sections covered in this comprehensive course:</p>
<p><strong>Course Overview &amp; Methodology</strong></p>
<ul>
<li><p>Fundamental Concepts and Networking Stack</p>
</li>
<li><p>Orientation: Curriculum and Prerequisite (DSA)</p>
</li>
<li><p>Introduction to the Instructor: Shrathir Sharma</p>
</li>
<li><p>Course Access (YouTube/Udemy) and Target Audience</p>
</li>
<li><p>Teaching Methodology: Raw Pen &amp; Paper Style</p>
</li>
<li><p>Core Modules: IPv4, Error Control, and Flow Control</p>
</li>
<li><p>Core Modules: Transport, Media Access, and Routing</p>
</li>
<li><p>Bonus Module: Cybersecurity</p>
</li>
</ul>
<p><strong>Networking Basics</strong></p>
<ul>
<li><p>Defining a Computer Network</p>
</li>
<li><p>Why Networks Interact: Resource Sharing</p>
</li>
<li><p>5 Components of Data Communication</p>
</li>
<li><p>4 Metrics for Network Effectiveness</p>
</li>
<li><p>Transmission Modes: Simplex, Half-Duplex, Full-Duplex</p>
</li>
<li><p>Types of Connections: Point-to-Point vs. Multi-Point</p>
</li>
</ul>
<p><strong>Topology &amp; Architecture</strong></p>
<ul>
<li><p>Introduction to Topology Layouts</p>
</li>
<li><p>Mesh Topology and Link Calculations</p>
</li>
<li><p>Advantages and Disadvantages of Topologies</p>
</li>
<li><p>Star, Bus, and Ring Topology Details</p>
</li>
<li><p>The OSI Model Framework</p>
</li>
<li><p>Layered Architecture and Peer-to-Peer Protocols</p>
</li>
</ul>
<p><strong>Binary &amp; IP Addressing Foundations</strong></p>
<ul>
<li><p>Review of Lecture Zero</p>
</li>
<li><p>Binary Number Representation &amp; Conversion</p>
</li>
<li><p>Binary Weights and Octet Conversions</p>
</li>
<li><p>Introduction to IPv4 Logical Addressing</p>
</li>
<li><p>Network ID vs. Host ID and IANA Authority</p>
</li>
</ul>
<p><strong>Classful vs. Classless Addressing</strong></p>
<ul>
<li><p>Telephone Network Analogy for IP Classes</p>
</li>
<li><p>Class A, B, and C Breakdown</p>
</li>
<li><p>Classful Wastage and the Need for Classless (CIDR)</p>
</li>
<li><p>Implementation: Fixing Bits for Classes A-E</p>
</li>
<li><p>IP Address Space Distribution</p>
</li>
<li><p>Hexadecimal and Decimal IP Representations</p>
</li>
</ul>
<p><strong>IPv4 Addressing Deep Dive</strong></p>
<ul>
<li><p>Class A Details: Reserved Addresses &amp; 127.0.0.1 Loopback</p>
</li>
<li><p>Calculating Valid Hosts and Reserved All-Zeros/All-Ones</p>
</li>
<li><p>Loopback Testing &amp; Troubleshooting Connectivity</p>
</li>
<li><p>Class B Details: Network Ranges &amp; Host Capacity</p>
</li>
<li><p>Class C Details: Network/Host Ratios</p>
</li>
<li><p>Class D (Multicasting) and Class E (Experimental)</p>
</li>
<li><p>IP Conversion Practice: Hexadecimal to Decimal</p>
</li>
<li><p>Common Pitfalls: "Addresses" vs. "Valid Hosts"</p>
</li>
</ul>
<p><strong>Subnetting &amp; VLSM</strong></p>
<ul>
<li><p>Introduction to Subnetting: Why We Divide Networks</p>
</li>
<li><p>Disadvantages of Subnetting: Wastage and Cost</p>
</li>
<li><p>How to Subnet: Borrowing Bits from Host ID</p>
</li>
<li><p>Subnet Identification: Calculating Subnet IDs and DBAs</p>
</li>
<li><p>Working with Weights: Identifying Specific Subnets</p>
</li>
<li><p>Subnet Masks vs. Network Masks</p>
</li>
<li><p>Designing a Subnet Mask for Specific Requirements</p>
</li>
<li><p>Variable Length Subnet Masking (VLSM) Strategy</p>
</li>
<li><p>Determining Subnet IDs using Bitwise AND Operations</p>
</li>
<li><p>Routing Tables: Matching Destination IPs to Interfaces</p>
</li>
<li><p>CIDR: Classless Inter-Domain Routing &amp; Slash Notation</p>
</li>
<li><p>Rules for Valid CIDR Blocks</p>
</li>
<li><p>Supernetting: Merging Multiple Blocks</p>
</li>
</ul>
<p><strong>Error Control &amp; Detection</strong></p>
<ul>
<li><p>Introduction to Error Control: Noise vs. Security</p>
</li>
<li><p>Single Bit Error vs. Burst Errors</p>
</li>
<li><p>Redundant Bits and Block Coding Logic</p>
</li>
<li><p>Hamming Distance: Calculating Difference Between Strings</p>
</li>
<li><p>Minimum Hamming Distance for Detection and Correction</p>
</li>
<li><p>Simple Parity: Even vs. Odd Parity Methods</p>
</li>
<li><p>2D Parity: Detecting and Correcting Single Bit Errors</p>
</li>
<li><p>Limitations of 2D Parity for Multi-Bit Errors</p>
</li>
<li><p>Cyclic Redundancy Check (CRC): Divisor &amp; Remainder Logic</p>
</li>
<li><p>Checksum: One's Complement Summation Method</p>
</li>
</ul>
<p><strong>Flow Control &amp; Layered Architecture</strong></p>
<ul>
<li><p>Network Delays: Transmission vs. Propagation</p>
</li>
<li><p>Queuing and Processing Delays</p>
</li>
<li><p>Data Encapsulation: Headers and Trailers</p>
</li>
<li><p>The Need for Flow Control: Avoiding Receiver Overwhelm</p>
</li>
<li><p>Stop and Wait Protocol: Core Mechanism</p>
</li>
<li><p>Using Timers and Sequence Numbers</p>
</li>
<li><p>Calculating Efficiency and Round Trip Time (RTT)</p>
</li>
<li><p>Throughput: Effective Bandwidth Relationship</p>
</li>
<li><p>Sliding Window Concept: Improving Efficiency</p>
</li>
<li><p>Go-Back-N (GBN) Protocol: Sender/Receiver Windows</p>
</li>
<li><p>Selective Repeat (SR) Protocol: Out-of-Order Handling</p>
</li>
<li><p>Cumulative vs. Independent Acknowledgments</p>
</li>
</ul>
<p><strong>Network Layer: IP Header &amp; Routing</strong></p>
<ul>
<li><p>IPv4 Header Format Overview</p>
</li>
<li><p>Type of Services (TOS): Priority and DTRC Bits</p>
</li>
<li><p>Time to Live (TTL): Preventing Infinite Loops</p>
</li>
<li><p>Protocol Field and Header Checksum</p>
</li>
<li><p>IP Options: Strict vs. Loose Source Routing</p>
</li>
<li><p>TCP Header Structure: Ports, Sequence, and Ack</p>
</li>
<li><p>Wrap Around Time and Segment Lifetime</p>
</li>
<li><p>Advertisement Window (Flow Control)</p>
</li>
<li><p>TCP Control Flags: URG, ACK, PSH, RST, SYN, FIN</p>
</li>
<li><p>SYN Flooding Attack (DDoS)</p>
</li>
<li><p>Congestion Control Policy: Slow Start &amp; Avoidance</p>
</li>
<li><p>TCP Timers: Time-Wait, Keep-Alive, Persistent</p>
</li>
<li><p>UDP Header and Best-Effort Delivery</p>
</li>
<li><p>Comparison: TCP vs. UDP</p>
</li>
</ul>
<p><strong>Media Access &amp; Application Support</strong></p>
<ul>
<li><p>Multiple Access: Random vs. Controlled Access</p>
</li>
<li><p>Pure Aloha vs. Slotted Aloha Throughput</p>
</li>
<li><p>CSMA (Carrier Sense): Persistent Methods</p>
</li>
<li><p>Polling, Reservation, and Token Passing</p>
</li>
<li><p>Routing: Flooding vs. Dynamic Routing</p>
</li>
<li><p>Distance Vector (Bellman-Ford) vs. Link State (Dijkstra)</p>
</li>
<li><p>Circuit Switching vs. Packet Switching</p>
</li>
<li><p>Email Protocols: SMTP, POP3, IMAP4</p>
</li>
<li><p>Domain Name System (DNS) Hierarchy &amp; Queries</p>
</li>
<li><p>FTP (File Transfer) and HTTP (Web Services)</p>
</li>
<li><p>Support Protocols: ARP and ICMP Error Reporting</p>
</li>
<li><p>Final Summary: OSI Model Layers 1-7</p>
</li>
</ul>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/fQbBPa0ADvs">the freeCodeCamp.org YouTube channel</a> (12-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/fQbBPa0ADvs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How TCP Turns Round Trip Time and Jitter into Packet Loss ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever noticed that your network connection sometimes feels fast and then suddenly slow, even when nothing obvious has changed? A request that takes 20 ms at one moment can take 80 ms the next, and sometimes it does not return at all. Terms li... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-tcp-turns-round-trip-time-and-jitter-into-packet-loss/</link>
                <guid isPermaLink="false">69837b8b9eb9655b2349db75</guid>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Packet Loss ]]>
                    </category>
                
                    <category>
                        <![CDATA[ rtt ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jitter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Syeda Maham Fahim ]]>
                </dc:creator>
                <pubDate>Wed, 04 Feb 2026 17:02:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770224386950/ceeafb62-ae8c-4c70-8239-91ba835b85b7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever noticed that your network connection sometimes feels fast and then suddenly slow, even when nothing obvious has changed? A request that takes 20 ms at one moment can take 80 ms the next, and sometimes it does not return at all. Terms like RTT, jitter, and packet loss are often used to explain this behavior, but the real connection between them is easy to miss.</p>
<p>In this article, we’ll look at RTT, jitter, and packet loss as parts of a single timing system rather than separate metrics. You’ll start by understanding RTT and why it changes over time. Then you’ll learn how jitter emerges as an extra delay relative to a baseline. Finally, you’ll see how TCP uses this timing information to decide when delay turns into packet loss, with a focus on real protocol behaviour such as TLS and post-quantum TLS handshakes.</p>
<p>The goal is simple: to understand how timing turns into decisions.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-rtt-round-trip-time">RTT (Round Trip Time)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-baseline-rtt">Baseline RTT</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-baseline-rtt-matters">Why Baseline RTT Matters</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-jitter">What is Jitter?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-jitter-actually-means">What Jitter Actually Means</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-where-jitter-comes-from">Where Jitter Comes From</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-jitter-tells-us">What Jitter Tells Us</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-tcp-learns-rtt-and-jitter">How TCP Learns RTT and Jitter</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-tcp-does-not-know-rtt-in-advance">TCP Does Not Know RTT in Advance</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-srtt-smoothed-rtt">SRTT (Smoothed RTT)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rttvar-rtt-variance">RTTVAR (RTT Variance)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-tcp-needs-both">Why TCP Needs Both</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-tcp-decides-packet-loss">How TCP Decides Packet Loss</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-tcp-never-sees-a-packet-being-dropped">TCP Never Sees a Packet Being Dropped</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-retransmission-timeout-rto">Retransmission Timeout (RTO)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-delay-vs-packet-loss">Delay vs Packet Loss</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-jitter-turns-into-packet-loss">How Jitter Turns Into Packet Loss</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-rtt-round-trip-time">RTT (Round Trip Time)</h2>
<p>Before talking about delay, jitter, or packet loss, we need to clearly understand what RTT is. If RTT is not clear, everything that comes after it becomes confusing.</p>
<p>RTT stands for <strong>Round Trip Time</strong>. It is the total time taken for a packet to travel from a client to a server and for the response to return to the client.</p>
<p><a target="_blank" href="speedvitals.com"><img src="https://cdn-images-1.medium.com/max/1600/1*tKeOZNVYvkDuXMl4WytN5Q.jpeg" alt="RTT [Image Source: speedvitals.com ]" width="600" height="400" loading="lazy"></a></p>
<p>Assuming you send a packet and receive the reply after 50 milliseconds, then the RTT is 50 ms. That is the basic definition.</p>
<p>But here is the important part: <strong>RTT is not a fixed number.</strong> It changes all the time. Even when you communicate with the same server, RTT can change from one packet to the next. This happens because the network is always changing, and this can be because of any of these reasons:</p>
<ul>
<li><p>Packets waiting in queues</p>
</li>
<li><p>Temporary congestion</p>
</li>
<li><p>Scheduling inside routers</p>
</li>
<li><p>Background traffic on the same path</p>
</li>
</ul>
<p>Let’s assume you connect to Google, and you send a packet now. In practice, RTT can be measured using simple tools. One common way is the <code>ping</code> command, which sends a packet and measures how long it takes for the reply to return.</p>
<pre><code class="lang-python">ping -n <span class="hljs-number">1</span> google.com
</code></pre>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*_cGYjq_VgETjsV6rl6XLZA.png" alt="Ping to google.com showing round-trip time output." width="600" height="400" loading="lazy"></p>
<p>And here, you get the reply after 50 ms.</p>
<pre><code class="lang-python">RTT = <span class="hljs-number">50</span> ms
</code></pre>
<p>That value is real, but it is incomplete. A single RTT measurement does not tell us whether the network path itself takes 50 ms, or whether the path is faster and the packet experienced a small temporary delay along the way.</p>
<p>For example, the actual path delay might be 49 ms, with an additional 1 ms spent waiting in a queue. From a single RTT value, there is no way to separate these effects. RTT only makes sense after multiple measurements.</p>
<p>So, let’s measure multiple RTT values.</p>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*ecgJnU89HtE9FVzczJue4g.png" alt="Ping to google.com showing multiply round-trip time output." width="600" height="400" loading="lazy"></p>
<p>Now you can see a pattern. From the measurements:</p>
<pre><code class="lang-python">min RTT ≈ <span class="hljs-number">18</span> ms
max RTT ≈ <span class="hljs-number">19</span> ms
average RTT ≈ <span class="hljs-number">18</span> ms
</code></pre>
<p>That is why RTT is not something you magically know from one packet. It is something you observe over time.</p>
<p>But now, at this point, an important question comes up: <strong>Which of these RTT values represents the real network path?</strong></p>
<p>When RTT is measured repeatedly, the values are not consistent. Some RTT measurements are small, some are larger, and some suddenly jump due to temporary network conditions.</p>
<p>You may see something like this: <code>small, small, small, small, BIG</code>. That is why we need a reference point, which we can call the stable point. Without it, every RTT value looks equally confusing, and we cannot tell whether a packet was slow because the path itself is slow or because something temporary happened.</p>
<h3 id="heading-baseline-rtt">Baseline RTT</h3>
<p>That stable point is the baseline RTT. Baseline RTT means the <strong>minimum RTT observed over time</strong>. This represents the RTT without temporary effects.</p>
<p>For example, in the above example, our repeated measurements show minimum RTT ≈ 18 ms. 18 ms becomes our baseline RTT. You can think of baseline RTT as the fastest possible RTT for a given path, representing the calm state of the network where packets do not wait in queues, there is no congestion, and no retransmissions occur.</p>
<p>In other words, baseline RTT reflects what the network is capable of when nothing unusual is happening. The best happy case that usually excludes temporary effects.</p>
<h3 id="heading-why-baseline-rtt-matters"><strong>Why Baseline RTT Matters</strong></h3>
<p>Once we have a baseline RTT, individual RTT measurements stop feeling random. We can see when an RTT is close to the baseline, when it is higher than expected, and when extra delay has been introduced by temporary network conditions.</p>
<p>Without a baseline RTT, each RTT value stands alone, and comparison becomes guesswork. With a baseline in place, RTT values gain meaning, variation becomes visible, and we are finally able to reason about what causes RTT to increase, which naturally leads to jitter.</p>
<p>This is the point where we are finally ready to talk about <strong>what causes RTT to increase</strong>, which leads naturally to jitter.</p>
<h2 id="heading-what-is-jitter">What is Jitter?</h2>
<p>Now comes Jitter. Once we have a baseline RTT, something important becomes clear. Most RTT values are not equal to the baseline. They are usually higher.</p>
<p>So the next natural question is: <strong>If baseline RTT shows the calm network, what is causing the RTT to increase in the other measurements?</strong></p>
<p>That extra part is what we call jitter.</p>
<h3 id="heading-what-jitter-actually-means">What Jitter Actually Means</h3>
<p>Jitter is the extra delay added on top of the baseline RTT. In simple words, baseline RTT shows what the network can do when nothing is wrong, while jitter describes what happens when the network becomes busy, and packets experience extra delay.</p>
<p>So every observed RTT can be thought of like this: <code>Observed RTT = Baseline RTT + Extra Delay</code></p>
<p><strong><em>Example</em></strong></p>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*T6bC3VvXULV5CIVRixg-uA.png" alt="Observed RTT and Jitter." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Baseline RTT = 18 ms. That extra delay is jitter.</p>
<p>There are two important points to remember. First, jitter is always positive because a packet can be delayed but can never arrive faster than the baseline RTT. Second, baseline RTT acts as the reference point, which means jitter only exists relative to that baseline. Without a baseline, jitter has no meaning.</p>
<h3 id="heading-where-jitter-comes-from">Where Jitter Comes From</h3>
<p>Jitter appears when packets do not move immediately through the network.</p>
<p>This usually happens because of:</p>
<ul>
<li><p>Packets waiting in queues</p>
</li>
<li><p>Routers delaying packets before forwarding</p>
</li>
<li><p>Temporary congestion on links</p>
</li>
<li><p>Retransmissions after drops</p>
</li>
</ul>
<p>These effects are not constant. They come and go. Because of that, jitter is irregular and bursty. Sometimes it is very small, and at other times it can suddenly become large.</p>
<h3 id="heading-what-jitter-tells-us">What Jitter Tells Us</h3>
<p>At this stage, jitter is still just an observation. It tells us how unstable the network timing is and how often packets experience extra delay. We are not making decisions yet. We are only describing what the network is doing.</p>
<h2 id="heading-how-tcp-learns-rtt-and-jitter">How TCP Learns RTT and Jitter</h2>
<p>We have seen that:</p>
<ul>
<li><p>RTT changes over time</p>
</li>
<li><p>Baseline RTT gives us a reference</p>
</li>
<li><p>Jitter explains extra delay</p>
</li>
</ul>
<p>So, up to this point, we have only been observing the network. But now a new question appears: If RTT keeps changing, and if delay and jitter exist, <strong>who is actually watching all this?</strong> More importantly, <strong>who decides when waiting is normal and when waiting becomes a problem?</strong></p>
<p>This is the point where <strong>TCP</strong> enters the picture. TCP is the component that observes these timing changes and uses them to decide what to do next.</p>
<h3 id="heading-tcp-does-not-know-rtt-in-advance">TCP Does Not Know RTT in Advance</h3>
<p>TCP does not start with any knowledge of how long the path is, how stable the network will be, or how much delay to expect. It learns all of this dynamically while the connection is running.</p>
<p>TCP learns everything <strong>while the connection is running</strong>, only by looking at time. Every time TCP sends data and receives an acknowledgement, it gets one RTT sample. Over time, these samples are used to build expectations.</p>
<p>To make sense of these timing samples, TCP maintains two internal values that summarize what it has learned so far.</p>
<h3 id="heading-srtt-smoothed-rtt">SRTT (Smoothed RTT)</h3>
<p>SRTT is the RTT that TCP expects most of the time. It is not the minimum RTT, and it is not a simple average. It is a smoothed value that represents the normal RTT that the TCP has learned from recent history. This means recent RTT measurements matter more, while older RTT measurements gradually matter less.</p>
<p>Because of this, SRTT does not jump because of a single delayed packet. Instead, it adapts gradually as network conditions change.</p>
<p>For example, suppose TCP observes these RTT samples (in ms): 48, 50, 49, 51, 50.</p>
<p>Then TCP smooths these values into a stable expectation, such as: SRTT ≈ 50 ms.</p>
<p>You can think of SRTT as: The RTT that TCP believes is reasonable for this connection, based mostly on recent history. It is a memory-weighted average, biased toward recent RTT values.</p>
<h3 id="heading-rttvar-rtt-variance">RTTVAR (RTT Variance)</h3>
<p>RTTVAR tells TCP <strong>how much RTT is changing</strong>. Now compare two situations.</p>
<p><strong>Stable RTT</strong></p>
<p>RTT samples: <code>49, 50, 51, 50</code></p>
<p>Because these values are close to each other, the variation is small, RTTVAR remains low, and TCP feels confident about its timing estimates.</p>
<p><strong>Unstable RTT</strong></p>
<p>RTT samples: <code>50, 52, 90, 48</code></p>
<p>Here, the sudden jump increases variation, causes RTTVAR to rise, and makes TCP less confident about its timing.</p>
<h3 id="heading-why-tcp-needs-both">Why TCP Needs Both</h3>
<p>SRTT alone is not enough for TCP to make reliable timing decisions. If TCP only knew that the RTT is around 50 ms, it would still have no way to tell whether delays are stable or whether sudden spikes are common.</p>
<p>RTTVAR fills this gap by capturing how much RTT changes over time. While SRTT tells TCP what RTT to expect under normal conditions, RTTVAR tells TCP how confident it should be in that expectation.</p>
<p>At this stage, TCP is still <strong>learning</strong>, not judging. It is building a timing model of the network.</p>
<p>So far, the network produces RTT variation, baseline RTT provides a calm reference, jitter explains extra delay, and TCP observes all of this using SRTT and RTTVAR.</p>
<p>TCP now has expectations. Only after this point does TCP start making decisions. And one of those decisions is packet loss.</p>
<h2 id="heading-how-tcp-decides-packet-loss">How TCP Decides Packet Loss</h2>
<p>Now that TCP has learned what RTT usually looks like and how much it varies, it has to answer one important question: <strong>How long should I wait before assuming a packet is gone?</strong></p>
<p>This is where packet loss comes in.</p>
<h3 id="heading-tcp-never-sees-a-packet-being-dropped">TCP Never Sees a Packet Being Dropped</h3>
<p>TCP does not see routers, queues, or links, and it does not know where packets go. TCP only sees time. It sends data and then waits.</p>
<p>If the acknowledgment arrives in time, everything is fine. If it does not, TCP must decide what to do next.</p>
<h3 id="heading-retransmission-timeout-rto">Retransmission Timeout (RTO)</h3>
<p>To make this decision, TCP uses the Retransmission Timeout, or RTO. RTO is not random. It is computed from what TCP has already learned about network timing.</p>
<p>Conceptually, RTO is calculated as:</p>
<pre><code class="lang-markdown">RTO=SRTT+max(𝐺,4×RTTVAR)
</code></pre>
<p>Here, SRTT sets the expected delay, while RTTVAR adds extra margin to account for jitter. As a result, RTO represents how long TCP is willing to wait, based on how uncertain the network timing is.</p>
<p>Suppose TCP has learned that the SRTT is 50 ms and the RTTVAR is 5 ms. In that case, the RTO becomes 70 ms.</p>
<p>RTO = 50 + 4 × 5<br>RTO = 70 ms</p>
<p>Now TCP behavior is simple:</p>
<ul>
<li><p>ACK arrives at <strong>60 ms</strong> → delay</p>
</li>
<li><p>ACK arrives at <strong>75 ms</strong> → packet loss</p>
</li>
</ul>
<p>The network is the same, and the packet is the same. Only the arrival time changes, and that alone leads to a different decision.</p>
<h3 id="heading-delay-vs-packet-loss">Delay vs Packet Loss</h3>
<p>TCP logic is simple. If a packet arrives before the RTO expires, it is treated as delay. If it does not arrive before the RTO, TCP declares it lost.</p>
<p>This leads to an important rule: <strong>packet loss is a timing decision, not a certainty</strong>. The packet may still arrive later, but once the RTO expires, TCP has already acted.</p>
<h3 id="heading-how-jitter-turns-into-packet-loss">How Jitter Turns Into Packet Loss</h3>
<p>This behaviour connects directly to jitter. As long as jitter stays within the RTO window, packets are delayed but not considered lost. When jitter becomes large enough that delays cross the RTO boundary, TCP interprets delay as packet loss.</p>
<p>So packet loss does not always mean a packet disappeared. Often, it means the network timing has become too unpredictable.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>At this point, everything connects: RTT, jitter, and packet loss are not separate network metrics. They describe different parts of the same timing process.</p>
<ul>
<li><p>RTT shows how long communication usually takes.</p>
</li>
<li><p>Baseline RTT gives a stable reference.</p>
</li>
<li><p>Jitter explains why delays change.</p>
</li>
<li><p>Packet loss appears when that variation exceeds what the protocol can tolerate.</p>
</li>
</ul>
<p>Once this flow is clear, network behavior stops feeling random. It becomes a matter of timing, uncertainty, and decisions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Developer’s Guide to Proxy Servers ]]>
                </title>
                <description>
                    <![CDATA[ Every time you open a website, your device talks directly to another server on the internet.  Your IP address, location, and basic network details are visible to that server.  In many cases, this is fine. But there are situations where you may want m... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-developers-guide-to-proxy-servers/</link>
                <guid isPermaLink="false">695db23365ab0e59d902fa64</guid>
                
                    <category>
                        <![CDATA[ proxy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ server ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Wed, 07 Jan 2026 01:09:07 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767748085260/ef495b53-f484-4f55-af29-57432aaf1dba.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every time you open a website, your device talks directly to another server on the internet. </p>
<p>Your IP address, location, and basic network details are visible to that server. </p>
<p>In many cases, this is fine. But there are situations where you may want more control over how your requests travel across the internet. This is where proxies come in.</p>
<p>A <a target="_blank" href="https://www.geeksforgeeks.org/computer-networks/what-is-proxy-server/">proxy</a> acts as an intermediary between you and the internet. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767634042506/560a0ace-c42e-4810-b5d1-fbb9a1a6a246.png" alt="How Proxy Works" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Instead of your device connecting directly to a website, it sends the request to a proxy server. The proxy then forwards the request on your behalf and sends the response back to you. </p>
<p>From the website’s point of view, it’s the proxy that is making the request, not you.</p>
<p>Proxies are used for privacy, security, performance, testing, automation, and access control. They are common in companies, data centers, scraping systems, and even home networks. </p>
<p>To understand why proxies matter, it helps to first understand how internet requests normally work.</p>
<h2 id="heading-what-well-cover"><strong>What We’ll Cover</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-internet-requests-work-without-a-proxy">How internet requests work without a proxy</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-types-of-proxies">Types of proxies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-proxies-vs-vpns">Proxies vs VPNs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-using-a-proxy-in-python">Using a proxy in Python</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-proxy-use-cases">Proxy Use Cases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-proxies-affect-performance-and-reliability">How proxies affect performance and reliability</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-proxies-are-detected-and-blocked">How proxies are detected and blocked</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-security-considerations-when-using-proxies">Security considerations when using proxies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-how-internet-requests-work-without-a-proxy"><strong>How Internet Requests Work Without a Proxy</strong></h2>
<p>When you type a website address into your browser, your computer resolves the domain name to an IP address using DNS. It then opens a connection directly to that server. </p>
<p>Your IP address is included as part of the network connection so the server knows where to send the response.</p>
<p>The server can log your IP address, infer your location, detect your network provider, and apply rules based on that information. Some websites restrict access by country. </p>
<p>Others rate-limit or block traffic from specific IP ranges. In automated systems, repeated requests from the same IP are often flagged as suspicious.</p>
<p>Without a proxy, all of this traffic is directly tied to your device or server. There is no separation layer.</p>
<h2 id="heading-types-of-proxies"><strong>Types of Proxies</strong></h2>
<p>Proxies come in several forms, each designed for different scenarios.</p>
<p><a target="_blank" href="https://www.zscaler.com/resources/security-terms-glossary/what-is-forward-proxy">Forward proxies</a> are the most common. These are used by clients to access external resources. Corporate networks often use forward proxies to control employee internet access.</p>
<p><a target="_blank" href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/">Reverse proxies</a> work in the opposite direction. They sit in front of servers rather than clients. Websites use reverse proxies to load balance traffic, terminate TLS, and protect backend systems.</p>
<p>Transparent proxies operate without explicit client configuration. They intercept traffic at the network level. These are often used by ISPs or enterprise networks.</p>
<p>Residential, datacenter, and mobile proxies differ based on where their IP addresses come from. Residential and mobile proxies appear like real user devices, while datacenter proxies come from cloud providers.</p>
<h2 id="heading-proxies-vs-vpns"><strong>Proxies vs VPNs</strong></h2>
<p>Proxies and VPNs are often confused, but they solve different problems. A proxy usually works at the application level. You configure a browser, script, or tool to use a proxy, and only that traffic goes through it.</p>
<p>A VPN works at the operating system or network level. Once connected, all traffic from your device is routed through the <a target="_blank" href="https://www.paloaltonetworks.com/cyberpedia/what-is-a-vpn-tunnel">VPN tunnel</a> by default. This includes browsers, apps, and background services.</p>
<p>Another difference is encryption. Most VPNs encrypt traffic between your device and the VPN server. Many proxies don’t, unless you’re using HTTPS or a secure proxy protocol.</p>
<p>People sometimes compare proxies to a <a target="_blank" href="https://nordvpn.com/">free VPN</a>, especially when the goal is hiding an IP address. While both can change your apparent location, a proxy is usually more lightweight and task-specific. A VPN is better when you want system-wide privacy, but it comes with more overhead and less fine-grained control.</p>
<p>For developers and automation systems, proxies are often preferred because they are easier to rotate, cheaper at scale, and simpler to integrate into code.</p>
<h2 id="heading-using-a-proxy-in-python"><strong>Using a Proxy in Python</strong></h2>
<p>Using a proxy in Python is straightforward, especially with popular libraries like <code>requests</code>. Below is a simple example that sends an HTTP request through a proxy.</p>
<p>To get a proxy URL, you can either build your own proxy using open-source solutions like <a target="_blank" href="https://www.manageengine.com/products/firewall/tech-topics/what-is-squid-proxy.html">SquidProxy</a> or buy a third-party service that charges per GB of traffic. Here is a list of <a target="_blank" href="https://www.geeksforgeeks.org/websites-apps/best-residential-proxy-providers/">popular proxy providers</a>. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests  <span class="hljs-comment"># Import the requests library to make HTTP requests</span>

<span class="hljs-comment"># Proxy URL with authentication details</span>
<span class="hljs-comment"># Format: protocol://username:password@host:port</span>
proxy_url = <span class="hljs-string">"http://username:password@proxy_host:proxy_port"</span>


<span class="hljs-comment"># Define proxy settings for both HTTP and HTTPS traffic</span>
<span class="hljs-comment"># Requests will route all outgoing traffic through this proxy</span>
proxies = {
   <span class="hljs-string">"http"</span>: proxy_url,
   <span class="hljs-string">"https"</span>: proxy_url
}

<span class="hljs-comment"># Make a GET request to httpbin.org, which returns the IP address</span>
<span class="hljs-comment"># This helps verify whether the request is going through the proxy</span>
response = requests.get(
   <span class="hljs-string">"https://httpbin.org/ip"</span>,  <span class="hljs-comment"># Test endpoint that echoes the client IP</span>
   proxies=proxies,          <span class="hljs-comment"># Apply the proxy configuration</span>
   timeout=<span class="hljs-number">10</span>                <span class="hljs-comment"># Fail the request if it takes more than 10 seconds</span>
)

<span class="hljs-comment"># Print the response body</span>
<span class="hljs-comment"># If the proxy is working, the IP shown here will be the proxy's IP, not yours</span>
print(response.text)
</code></pre>
<p>In this example, the requests library sends the outbound request to the proxy instead of directly to the website. The website sees the proxy’s IP address. The response shows which IP was used, making it easy to verify that the proxy is working.</p>
<p>This same pattern applies to APIs, scrapers, and internal tools. More advanced setups rotate proxies per request or per session.</p>
<h2 id="heading-proxy-use-cases"><strong>Proxy Use Cases</strong></h2>
<p>One of the most common reasons to use a proxy is IP masking. By routing traffic through a proxy, your real IP address is hidden from the destination server. This is useful for privacy, security testing, and bypassing IP-based restrictions.</p>
<p>Proxies are also used for geographic routing. If a service behaves differently in different countries, a proxy located in a specific region lets you see what users there experience.</p>
<p>In automation and scraping systems, proxies are essential. Sending thousands of requests from a single IP is a fast way to get blocked. Rotating proxies distribute traffic across many IPs, reducing detection.</p>
<p>Companies use proxies to monitor, filter, and log outbound traffic. This helps with compliance, security, and performance optimisation.</p>
<h2 id="heading-how-proxies-affect-performance-and-reliability"><strong>How Proxies Affect Performance and Reliability</strong></h2>
<p>Adding a proxy introduces an extra network hop, which can increase latency. A well-located, high-quality proxy can still be fast, but performance depends heavily on proxy capacity and distance.</p>
<p>Proxies can also improve performance in some cases. Caching proxies store responses and serve them locally for repeated requests. This reduces load on upstream servers and speeds up access.</p>
<p>Reliability depends on proxy health. If a proxy goes down, all traffic routed through it fails. This is why production systems often use proxy pools and health checks to automatically switch between proxies.</p>
<h2 id="heading-how-proxies-are-detected-and-blocked"><strong>How Proxies Are Detected and Blocked</strong></h2>
<p>Websites often try to detect proxy usage. They analyse IP reputation, request patterns, headers, and behavioural signals. Datacenter proxies are easier to detect because their IP ranges are well-known.</p>
<p>Some proxies leak information through headers that reveal the original client IP. Poorly configured proxies are especially easy to spot.</p>
<p>To reduce detection, systems rotate IPs, randomise headers, simulate real browser behaviour, and use residential or mobile proxies. Detection and evasion is an ongoing arms race between websites and proxy users.</p>
<h2 id="heading-security-considerations-when-using-proxies"><strong>Security Considerations When Using Proxies</strong></h2>
<p>Not all proxies are trustworthy. When you route traffic through a proxy, that proxy can see your requests and responses. This means sensitive data should only be sent over encrypted connections.</p>
<p>Public or free proxies often log traffic, inject ads, or behave unpredictably. For serious use cases, dedicated or private proxies are safer.</p>
<p>In corporate environments, proxies are part of the security model. They enforce policies, block malicious destinations, and provide audit logs. In these cases, the proxy is a defensive tool rather than a privacy tool.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>A proxy is a simple but powerful concept. By inserting an intermediary between a client and the internet, proxies change how requests appear, how traffic is controlled, and how systems scale.</p>
<p>They are used for privacy, testing, automation, compliance, and performance. While they are often mentioned alongside VPNs, proxies offer more targeted control and flexibility, especially for developers and infrastructure teams.</p>
<p>Understanding how proxies work at a request level helps you decide when to use them, how to configure them safely, and how to design systems that rely on them. Whether you are building a scraper, testing geo-specific behavior, or managing outbound traffic, proxies remain a core building block of the modern internet.</p>
<p><em>Hope you enjoyed this article. Find me on</em> <a target="_blank" href="https://linkedin.com/in/manishmshiva"><em>Linkedin</em></a> <em>or</em> <a target="_blank" href="https://manishshivanandhan.com/"><em>visit my website</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use CDNs to Improve Performance in your Front-end Projects ]]>
                </title>
                <description>
                    <![CDATA[ In web development, styling plays a crucial role in the visual presentation of web applications. According to a study by Adobe, 59% of users would choose a beautifully designed website over a “simple and plain” design. So designs that are crafted in ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-cdns-improve-performance-in-front-end-projects/</link>
                <guid isPermaLink="false">670d72a6d4c1491e5ee9df77</guid>
                
                    <category>
                        <![CDATA[ Frontend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CDN ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Timothy Olanrewaju ]]>
                </dc:creator>
                <pubDate>Mon, 14 Oct 2024 19:36:06 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728820334493/8ef2738f-c2ac-42d3-be3f-5a6a3bddbdbd.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In web development, styling plays a crucial role in the visual presentation of web applications. According to a study by Adobe, 59% of users would choose a beautifully designed website over a “simple and plain” design. So designs that are crafted in a visually appealing way tend to attract users to consume content on a website.</p>
<p>In recent times, there has been a steady rise in styling tools that you can use to elevate the visual appeal of your websites. Such tools include CSS frameworks, animation libraries, icon libraries, and typography libraries. These tools offer customization flexibility, responsiveness, and consistency.</p>
<p>One awesome thing about these styling tools is that they bundle stylistic effects in a file which you can access via a Content Delivery Network (CDN).</p>
<p>In this article, we’ll be looking extensively at CDNs, how they work, their different hosting methods, the differences between them, their pros and cons, and the best use-cases of the methods for your project.</p>
<p>Let's dive straight into it!</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-a-cdn">What is a CDN?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-does-a-cdn-work">How does a CDN work?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-real-world-analogy-to-explain-cdns">Real-world analogy to explain CDNs</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-why-are-cdns-important">Why are CDNs Important?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-different-ways-to-use-a-cdn">Different Ways to Use a CDN</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-remote-hosted-cdn">Remote Hosted CDN</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-locally-hosted-cdn">Locally Hosted CDN</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hybrid-hosted-cdn">Hybrid Hosted CDN</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-what-is-a-cdn"><strong>What is a CDN?</strong></h2>
<p>A CDN, or Content Delivery Network, is a system of distributed servers that delivers web content (like images, stylesheets, scripts and other resources) to users, reliably and efficiently.</p>
<h3 id="heading-how-does-a-cdn-work"><strong>How does a CDN work?</strong></h3>
<p>A CDN’s primary function is to cache and serve both static and dynamic web content to users. It achieves this by using the following:</p>
<ul>
<li><p><strong>Origin Server</strong>: This is the main server where all content is originally hosted.</p>
</li>
<li><p><strong>Edge Servers</strong>: These are servers distributed in different geographical locations to serve web content to users closer to them.</p>
</li>
<li><p><strong>Caching</strong>: This is a way of storing content on edge servers to reduce repeated requests to the origin server.</p>
</li>
<li><p><strong>DNS Routing</strong>: This is the mechanism that reroutes users to the nearest edge servers based on their location.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728819505243/6389ac39-e1d2-4348-9f97-8ee370eecd7f.png" alt="Diagram showing origin server communicating with different edge servers" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>This is what happens when a user clicks on a CDN link:</p>
<ul>
<li><p>If trying to access the resource for the first time, the request hits the origin server.</p>
</li>
<li><p>The origin server sends the resource to the user as a response and also sends a copy to the edge server located geographically closest to the user.</p>
</li>
<li><p>The edge server caches the copy.</p>
</li>
<li><p>When the user wants to access the resources again, the edge server (not the origin server) sends over the cached copy.</p>
</li>
</ul>
<h3 id="heading-real-world-analogy-to-explain-cdns"><strong>Real-World Analogy to Explain CDNs</strong></h3>
<p>To further explain how the CDN works, I’ll give an analogy to make it clearer. Imagine having an account with a bank that has its headquarters in New York (origin server).</p>
<p>You don’t expect customers who live far away from New York to be scampering to the headquarters any time they encounter issues. Instead, the bank provides branches (edge servers) in different locations to cater to the needs of their customers. Customers can easily walk into any branch nearest to them and get their issues or transactions sorted.</p>
<p>The branches have every customer's account information and transaction logs (cached data). Every branch of that bank delivers the same services and can satisfy their customers regardless of their distance from the headquarters.</p>
<p>The distribution of branches in different locations helps reduce the traffic that would have caused delays if the bank had just the headquarters as the only option. On contacting the bank's customer service on an issue, you would most likely be redirected to the nearest bank branch to you (DNS Routing)!</p>
<h2 id="heading-why-are-cdns-important"><strong>Why are CDNs Important?</strong></h2>
<p>There are many reasons why CDNs many websites use CDNs these days. Some of the key benefits are:</p>
<ol>
<li><p><strong>Improved Website Performance:</strong> CDNs can compress files and optimize images automatically, which helps speed up load time.</p>
</li>
<li><p><strong>Efficient Resource Storage:</strong> With CDNs, styling resources are stored and managed properly. Resources are also stored in files matching their content types.</p>
</li>
<li><p><strong>Better Search Engine Optimization (SEO):</strong> Using CDNs directly speeds up load time which in turn impacts search engine rankings. Google considers site speed a key metric that allows web pages to show up higher in search engines.</p>
</li>
<li><p><strong>Better User Experience:</strong> Users prefer faster and more responsive websites to slow and unresponsive ones. With a better user experience, a website is sure to receive more engagement and lower bounce rates.</p>
</li>
</ol>
<h2 id="heading-different-ways-to-use-a-cdn"><strong>Different Ways to Use a CDN</strong></h2>
<p>There are three ways you can access CDN resources in your project:</p>
<ul>
<li><p>Remote Hosting</p>
</li>
<li><p>Local Hosting</p>
</li>
<li><p>Hybrid Hosting</p>
</li>
</ul>
<h3 id="heading-remote-hosted-cdn"><strong>Remote Hosted CDN</strong></h3>
<p>Remote CDN links allow developers to access styling resources from a third-party server by simply linking to the CDN in their HTML files via the <code>link</code> or <code>script</code> tag.</p>
<p>Bootstrap, for example, has two primary CDN links – one for CSS stylesheet and another for JavaScript (handles dynamic interaction like dropdowns, pop-overs, and so on).</p>
<p>To use a Bootstrap stylesheet in your project, you need to add this single line - <code>https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css</code></p>
<p>And for the JavaScript: <code>https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js</code></p>
<h4 id="heading-how-to-find-remote-cdn-links"><strong>How to find remote CDN links</strong></h4>
<p>The best way to identify thte remote CDN links of your desired styling tool is to visit their official documentation site and look for the direct links there.</p>
<h4 id="heading-advantages-of-a-remote-cdn"><strong>Advantages of a remote CDN:</strong></h4>
<ol>
<li><p><strong>Easy to Use:</strong> You don’t need to download, manage, or upload files with CDN links. All you need to do is insert a single line of code in your HTML file and you are good to go.</p>
</li>
<li><p><strong>Global Caching:</strong> whenever you visit a website that uses CDN links, it downloads the resources on loading the page and then saves it in your browser cache. On subsequent visits to the same website or other sites that use the same CDN, it fetches from the cache and displays these resources more quickly. This is one of the biggest advantages of using CDN links, as it improves website load time.</p>
</li>
<li><p><strong>Optimized Global Delivery:</strong> CDNs are built to deliver content to users around the world by serving files from edge servers closest to users. This helps reduce the time it takes data to transfer across a network, also known as latency, and boosts performance for international users.</p>
</li>
<li><p><strong>Reduced Server Load:</strong> Due to the CDN fetching data from an external source, the load on your server is reduced, which is helpful for high-traffic websites.</p>
</li>
<li><p><strong>Real-Time Updates:</strong> Companies that own CDN links carry out periodic bug fixing, security patching, and feature updates, which can be beneficial for your project. These updates are reflected as soon as they are released.</p>
</li>
</ol>
<h4 id="heading-disadvantages-of-a-remote-cdn"><strong>Disadvantages of a remote CDN:</strong></h4>
<ol>
<li><p><strong>Customization Limitations:</strong> Styling components in remote CDNs are standard and unmodified. To modify them, you would have to override the specific styles in your local file which can introduce complexities.</p>
</li>
<li><p><strong>No Control over Updates:</strong> When automatic updates are made, they can cause problems in your web applications. If the changes being introduced include drastic changes, it can affect your website’s layout or behavior in a big way.</p>
</li>
<li><p><strong>Dependency on Third-Party Availability:</strong> If the CDN service experiences hitches like downtime or slowness, it can lead to broken styles thus, affecting your site’s performance negatively.</p>
</li>
<li><p><strong>Privacy and Security Concerns:</strong> Links referencing an external source can pose serious security concerns, as they can be used to track users and get vital information. It is important to include only trusted CDN link sources in your web project to avoid breaches.</p>
</li>
</ol>
<h3 id="heading-locally-hosted-cdn"><strong>Locally Hosted CDN</strong></h3>
<p>These are CDN resources downloaded from a remote CDN and saved within your project folder or hosted on a local server. This approach allows you to have full control over the resources.</p>
<h4 id="heading-how-to-host-cdn-resources-locally"><strong>How to host CDN resources locally:</strong></h4>
<p>Hosting locally is straightforward and easy. All you have to do is:</p>
<ul>
<li><p>Access the resource by navigating to the CDN link URL (for example, <a target="_blank" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"><code>https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css</code></a>).</p>
</li>
<li><p>Copy the code found in the URL.</p>
</li>
<li><p>Create a file with the appropriate file extension (.css, .js) within your project folder.</p>
</li>
<li><p>Paste and save.</p>
</li>
<li><p>Reference the file in your HTML document.</p>
</li>
</ul>
<p>If you follow these steps, you should be able to localize the CDN resource and access its styling locally.</p>
<h4 id="heading-advantages-of-a-locally-hosted-cdn"><strong>Advantages of a locally hosted CDN:</strong></h4>
<ol>
<li><p><strong>Full Control over Files:</strong> With resources resident within your project folder/server, you’re in full control of your files as there will be no unexpected outages, changes, or updates that might break your site.</p>
</li>
<li><p><strong>Offline Availability:</strong> Local hosting ensures that your styling resources are always available, especially for users with little or no network. This is perfect for building Progressive Web Applications (PWAs)<strong>.</strong></p>
</li>
<li><p><strong>Customization:</strong> There’s be no need for overrides, as your styling can be modified from within your project files.</p>
</li>
<li><p><strong>Security:</strong> By localizing CDN resources, you reduce the risk of potential third-party attacks on your project to the barest minimum.</p>
</li>
</ol>
<h4 id="heading-disadvantages-of-a-locally-hosted-cdn"><strong>Disadvantages of a locally hosted CDN:</strong></h4>
<ol>
<li><p><strong>No Global Caching:</strong> There is no benefit of global caching when resources are hosted locally. This will result in slower load time for first-time visitors.</p>
</li>
<li><p><strong>Increased Server Load:</strong> With files residing locally, the load on the server increases especially as traffic increases. This approach puts a burden on the server and its capacity has to be considered.</p>
</li>
<li><p><strong>Manual Updates:</strong> While hosting locally gives you control over updates, you’ll need to manually track and apply updates to your stylesheets when necessary. Also, missing security updates could make your site vulnerable.</p>
</li>
<li><p><strong>Regional Performance Impact:</strong> If your server is located in a specific region, users from faraway places may encounter slower load times because the content has to travel greater distances.</p>
</li>
</ol>
<h3 id="heading-hybrid-hosted-cdn"><strong>Hybrid Hosted CDN</strong></h3>
<p>This approach involves the combination of using both the remote link and local hosting of CDN resources. A hybrid approach – which involves using remote CDNs for core libraries and local hosting for custom stylesheets – may strike the perfect balance between performance and control.</p>
<h3 id="heading-best-approach-to-use"><strong>Best Approach to Use</strong></h3>
<p>The decision between remote and local hosting of of your CDN styling resources depends on factors such as project performance needs, user base, and security. Your choice should depend on the suitability of the approach to your project and should elevate the performance levels.</p>
<h4 id="heading-best-use-cases-for-a-remote-cdn"><strong>Best use-cases for a remote CDN:</strong></h4>
<ol>
<li><p><strong>Global User Base:</strong> If your website is to be accessed by a large, globally distributed audience, using the remote option would work best due to its performance and caching advantage.</p>
</li>
<li><p><strong>Fast Integration:</strong> In a situation where you want to develop and deploy a project in the shortest period of time, using the remote CDN link is quick and easy.</p>
</li>
<li><p><strong>Low-Traffic Website:</strong> Small projects such as portfolio sites and blogs are better served using a remote CDN link so as not to put a strain on the server. It also leads to easier implementation.</p>
</li>
</ol>
<h4 id="heading-best-use-cases-for-a-locally-hosted-cdn"><strong>Best use-cases for a locally hosted CDN:</strong></h4>
<ol>
<li><p><strong>High Security Needs:</strong> For applications that require tight security due to the sensitivity of their operations, hosting the CDN resources locally will reduce third-party risks and vulnerabilities.</p>
</li>
<li><p><strong>Offline Applications:</strong> For web applications that work offline, localizing styling resources would be the best option.</p>
</li>
<li><p><strong>Customization Requirements:</strong> If you need to create your tailored styling versions, hosting them locally is the best option.</p>
</li>
</ol>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this guide, you’ve learned what a CDN is, how you can host your CDN, and some of the benefits, drawbacks, and best use-cases for each approach.</p>
<p>Remote CDNs provide speed, convenience and reduced server load, while local hosting offers greater control, security, and customization options.</p>
<p>Ultimately, the best approach depends on your specific use case, audience, and priorities.</p>
<p>You can connect with me on <a target="_blank" href="https://www.linkedin.com/in/timothy-olanrewaju750/">LinkedIn</a> or <a target="_blank" href="https://x.com/SmoothTee_DC">X</a> for more frontend-related posts and articles.</p>
<p>See you on the next one!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Network File System – How to Confirm Your Application is Using NFS ]]>
                </title>
                <description>
                    <![CDATA[ I was tasked recently to find which of our processes was accessing an NFS share. During this process, I found that some tools are better adapted than others for the task. In this article, I want to share with you my findings. The whole process was fu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-confirm-your-application-is-using-nfs/</link>
                <guid isPermaLink="false">66d8514139c4dccc43d4d4b6</guid>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose Vicente Nunez ]]>
                </dc:creator>
                <pubDate>Mon, 18 Sep 2023 06:54:37 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725458376947/86a9c2e5-a07d-4802-82e4-dd8c28aebbc5.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I was tasked recently to find which of our processes was accessing an NFS share. During this process, I found that some tools are better adapted than others for the task.</p>
<p>In this article, I want to share with you my findings. The whole process was fun and gave me ideas on how to use these tools to tackle similar problems in the future.</p>
<h2 id="heading-what-is-nfs">What is NFS?</h2>
<p>Network File System (NFS) is a distributed file system protocol that allows a user to access files over a computer network.</p>
<p>Please note that this is not a full tutorial on NFS. For that, please take a look at the following <a target="_blank" href="https://www.redhat.com/sysadmin/getting-started-nfs">tutorial</a>.</p>
<p>In this article, we will focus only on detecting access to a shared drive using several techiques as well setting up two servers and one client.</p>
<p>Also, I do use a different OS to set up both the server and the client, so instructions on how to do the task change a little bit.</p>
<h2 id="heading-how-to-set-up-a-nfs-server-and-client">How to Set Up a NFS Server and Client</h2>
<p>My lab setup has one NFS server and two clients:</p>
<p><img src="https://github.com/josevnz/tutorials/blob/main/docs/SpyOnNfs/NfsLayout.png?raw=true" alt="NfsLayout" width="600" height="400" loading="lazy"></p>
<p>On my setup, I will have three computers talking to each other. One of them will be the NFS server and the other two will be a client.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Machine</td><td>OS</td><td>Hardware</td><td>Mode</td></tr>
</thead>
<tbody>
<tr>
<td>OrangePi5</td><td>Ubuntu Armbian 23.8.1 jammy</td><td>Orange Pi 5</td><td>Server:/data</td></tr>
<tr>
<td>RaspberriPi</td><td>Debian 20.04.4 LTS (Focal Fossa)</td><td>Raspberry Pi 4 Model B Rev 1.4</td><td>Server:/var/log/suricata</td></tr>
<tr>
<td>Dmaf5</td><td>Fedora 37 (Workstation Edition)</td><td>AMD Ryzen 5 3550H with Radeon Vega Mobile Gfx</td><td>Client</td></tr>
</tbody>
</table>
</div><h3 id="heading-how-to-configure-the-server">How to Configure the Server</h3>
<p>I will prepare my OrangePI machine to be the NFS server. Do so, I will enter the following commands:</p>
<pre><code class="lang-shell">sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nfs-kernel-server -y
sudo systemctl enable nfs-kernel-server.service --now
</code></pre>
<p>Next step is to tell the <a target="_blank" href="https://ubuntu.com/server/docs/service-nfs">server we want to share</a>.</p>
<p>For that, we will edit the <a target="_blank" href="https://www.man7.org/linux/man-pages/man5/exports.5.html">/etc/exports</a> file (<code>sudo vi /etc/exports history</code>):</p>
<pre><code class="lang-text">/data *(ro,all_squash,async,no_subtree_check)
</code></pre>
<p>Please check the man page to understand what these options mean.</p>
<p>In a nutshell, export /data:</p>
<ul>
<li><p>Is read-only</p>
</li>
<li><p>Maps IDs to anonymous ID</p>
</li>
<li><p>This option allows the NFS server to violate the NFS protocol and reply to requests before any changes made by that request have been committed to stable storage</p>
</li>
<li><p>This option disables subtree checking. It's the default.</p>
</li>
</ul>
<p>Now it is time to activate our shared directories:</p>
<pre><code class="lang-shell">root@orangepi5:~# sudo exportfs -a
root@orangepi5:~# sudo showmount -e
Export list for orangepi5:
/data (everyone)
</code></pre>
<p>I did something similar to the other host, raspberrypi:</p>
<pre><code class="lang-shell">root@raspberrypi:~# cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
#        to NFS clients.  See exports(5).
#
/var/log/suricata *(ro,all_squash,async,no_subtree_check)
root@raspberrypi:~# showmount -e
Export list for raspberrypi:
/var/log/suricata *
</code></pre>
<h3 id="heading-how-to-configure-the-client">How to Configure the Client</h3>
<p>First thing is to confirm we can indeed see the shared mount points from our server:</p>
<pre><code class="lang-shell">(tutorials) [josevnz@dmaf5 SpyOnNfs]$ sudo showmount -e orangepi5
Export list for orangepi5:
/data raspberrypi,dmaf5
</code></pre>
<p>Data is shared with two machines – just what we expected.</p>
<p>Now, there are several ways to mount this drive. One of them is manually, another one is at startup, and the last one, my preferred one, is on demand.</p>
<h4 id="heading-how-to-set-up-the-automount-client-on-fedora-linux">How to Set Up the AutoMount Client on Fedora Linux</h4>
<p>First we <a target="_blank" href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/4/html/system_administration_guide/mounting_nfs_file_systems-mounting_nfs_file_systems_using_autofs">set the service</a>:</p>
<pre><code class="lang-shell">sudo dnf install -y autofs
sudo systemct enable autofs.service --now
</code></pre>
<p>Then we set this up, so we end mounting remote <code>/data</code> into local <code>/misc/data</code>. For that, sdd the following line to your <code>/etc/auto.master</code>:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# vi /etc/auto.misc
# After editing the file, adding our entry to the last line of the file ...
[root@dmaf5 ~]# cat /etc/auto.misc
#
# This is an automounter map and it has the following format
# key [ -mount-options-separated-by-comma ] location
# Details may be found in the autofs(5) manpage

cd              -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom

data            -ro,soft,rsize=16384,wsize=16384 orangepi5:/data
suricata        -ro,soft,rsize=16384,wsize=16384 raspberrypi:/var/log/suricata
</code></pre>
<p>Restart the service one more time:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# systemctl enable autofs.service --now
</code></pre>
<p>And the smoke test:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# ls -l /misc/data
total 0
drwxrwxr-x. 1 root 1001 48 Apr  7 17:57 nexus
[root@dmaf5 ~]# ls /misc/suricata
certs       eve.json.7  files            http.log    stats.log.1     suricata.log.2        suricata-start.log.3  tls.log.4
core        fast.log    http-data.log    http.log.1  stats.log.2     suricata.log.3        suricata-start.log.4  tls.log.5
eve.json    fast.log.1  http-data.log.1  http.log.2  stats.log.3     suricata.log.4        suricata-start.log.5  tls.log.6
eve.json.1  fast.log.2  http-data.log.2  http.log.3  stats.log.4     suricata.log.5        suricata-start.log.6  tls.log.7
eve.json.2  fast.log.3  http-data.log.3  http.log.4  stats.log.5     suricata.log.6        suricata-start.log.7
eve.json.3  fast.log.4  http-data.log.4  http.log.5  stats.log.6     suricata.log.7        tls.log
eve.json.4  fast.log.5  http-data.log.5  http.log.6  stats.log.7     suricata-start.log    tls.log.1
eve.json.5  fast.log.6  http-data.log.6  http.log.7  suricata.log    suricata-start.log.1  tls.log.2
eve.json.6  fast.log.7  http-data.log.7  stats.log   suricata.log.1  suricata-start.log.2  tls.log.3
</code></pre>
<p>Now we are ready to play with our service.</p>
<h2 id="heading-how-to-create-a-python-program-that-reads-files-into-the-nfs-server">How to Create a Python Program that Reads Files into the NFS Server</h2>
<p>For our example, we want to determine if a Python application is reading data from this directory. This script has two features:</p>
<ul>
<li><p>Performs a one time read view of a file. This will teach us how to capture this type of scenerarios, when a file is not opened all the time.</p>
</li>
<li><p>And the script also follows updates on a file periodically.</p>
</li>
</ul>
<p>Here is how our test script looks like in action:</p>
<pre><code class="lang-shell">./scripts/test_script.py \
--quick_read /misc/data/nexus/log/jvm.log \
--follow /misc/suricata/eve.json \
--verbose
...
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,889 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,890 &lt;dependency_failed type='leaf_type' ctxk='java/io/FileOutputStream' witness='java/net/SocketOutputStream' stamp='66511.794'/&gt;
2023-09-10 14:48:22,890 &lt;dependency_failed type='unique_concrete_method' ctxk='java/io/ByteArrayOutputStream' x='java/io/ByteArrayOutputStream write ([BII)V' witness='sun/security/ssl/HandshakeOutStream' stamp='66511.855'/&gt;
2023-09-10 14:48:22,890 &lt;dependency_failed type='unique_concrete_method' ctxk='java/io/ByteArrayOutputStream' x='java/io/ByteArrayOutputStream write ([BII)V' witness='sun/security/ssl/HandshakeOutStream' stamp='66511.855'/&gt;
...
# Ctrl-C to exit
</code></pre>
<p>The code, written in Python, is pretty simple:</p>
<pre><code class="lang-python"><span class="hljs-comment">#!/usr/bin/env python</span>
<span class="hljs-string">"""
Simple script to simulate light activity on NFS drives
Author Jose Vicente Nunez (kodegeek.com@protonmail.com)
"""</span>
<span class="hljs-keyword">import</span> concurrent
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> time
<span class="hljs-keyword">from</span> concurrent.futures <span class="hljs-keyword">import</span> ThreadPoolExecutor, ALL_COMPLETED
<span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path
<span class="hljs-keyword">from</span> argparse <span class="hljs-keyword">import</span> ArgumentParser
<span class="hljs-keyword">import</span> logging

logging.basicConfig(format=<span class="hljs-string">'%(asctime)s %(message)s'</span>, encoding=<span class="hljs-string">'utf-8'</span>, level=logging.DEBUG)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">forever_read</span>(<span class="hljs-params">the_file: Path, verbose: bool = False</span>):</span>
    <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> continuous_read(the_file=the_file):
        <span class="hljs-keyword">if</span> verbose:
            logging.warning(line.strip())


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">continuous_read</span>(<span class="hljs-params">the_file: Path</span>):</span>
    <span class="hljs-string">"""
    Continuously read the contents of file
    :param the_file:
    :return:
    """</span>
    <span class="hljs-keyword">with</span> open(the_file, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file_data:
        file_data.seek(<span class="hljs-number">0</span>, os.SEEK_END)
        <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
            line = file_data.readline()
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> line:
                time.sleep(<span class="hljs-number">0.1</span>)
                <span class="hljs-keyword">continue</span>
            <span class="hljs-keyword">yield</span> line


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">quick_read</span>(<span class="hljs-params">the_file: Path, verbose: bool = False</span>):</span>
    <span class="hljs-string">"""
    Red the whole file and close it once done
    :param verbose:
    :param the_file:
    :return:
    """</span>
    <span class="hljs-keyword">with</span> open(the_file, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file_data:
        <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> file_data:
            <span class="hljs-keyword">if</span> verbose:
                logging.warning(line.strip())


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    PARSER = ArgumentParser(description=__doc__)
    PARSER.add_argument(
        <span class="hljs-string">'--verbose'</span>,
        action=<span class="hljs-string">'store_true'</span>,
        default=<span class="hljs-literal">False</span>,
        help=<span class="hljs-string">'Enable verbose mode'</span>
    )
    PARSER.add_argument(
        <span class="hljs-string">'--quick_read'</span>,
        type=Path,
        required=<span class="hljs-literal">True</span>,
        help=<span class="hljs-string">'Read a file once'</span>
    )
    PARSER.add_argument(
        <span class="hljs-string">'--follow'</span>,
        type=Path,
        required=<span class="hljs-literal">True</span>,
        help=<span class="hljs-string">'Read a file continuously'</span>
    )
    OPTIONS = PARSER.parse_args()
    <span class="hljs-keyword">try</span>:
        <span class="hljs-keyword">with</span> ThreadPoolExecutor(max_workers=<span class="hljs-number">3</span>) <span class="hljs-keyword">as</span> tpe:
            futures = [
                tpe.submit(forever_read, OPTIONS.follow, OPTIONS.verbose),
                tpe.submit(quick_read, OPTIONS.quick_read, OPTIONS.verbose)
            ]
            concurrent.futures.wait(futures, return_when=ALL_COMPLETED)
    <span class="hljs-keyword">except</span> KeyboardInterrupt:
        <span class="hljs-keyword">pass</span>
</code></pre>
<p>Now, let's go over how we can see if our script is indeed accessing an NFS partition.</p>
<h3 id="heading-common-steps">Common steps</h3>
<p>First we need to learn where to look for. So on the machine, check for NFS in <code>/etc/fstab</code> (for mount points that are available since the machine was rebooted):</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# rg -e 'rsize=' /etc/fstab
</code></pre>
<p>Then on the AutoMount files:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# rg -e 'rsize=' /etc/auto*
/etc/auto.misc
17:data            -ro,soft,rsize=16384,wsize=16384 orangepi5:/data
18:suricata        -ro,soft,rsize=16384,wsize=16384 raspberrypi:/var/log/suricata
</code></pre>
<p>The regular expressions are not exact science, but you get the idea what to look for next.</p>
<h3 id="heading-how-to-use-the-tools">How to Use the tools</h3>
<p>We need to confirm if there was access to any of the following partitions mounted over NFS:</p>
<ul>
<li><p><code>/misc/data</code></p>
</li>
<li><p><code>/misc/suricata</code></p>
</li>
</ul>
<p>Next, I will show you a set of tools that will make the task easier, each one of them with their own strength and limitations.</p>
<p>Starting with <a target="_blank" href="https://www.redhat.com/sysadmin/analyze-processes-lsof">lsof</a> and <a target="_blank" href="https://github.com/BurntSushi/ripgrep">ripgrep</a> combined.</p>
<h3 id="heading-how-to-use-lsof-and-rg-for-capturing-and-filtering">How to Use Lsof and rg for Capturing and Filtering</h3>
<pre><code class="lang-shell">[josevnz@dmaf5 docs]$ lsof -w -b| rg -e '/misc/data|/misc/suricata'
python    36509                 josevnz    3   unknown                           /misc/suricata/eve.json
python    36509 36510 python    josevnz    3   unknown                           /misc/suricata/eve.json
python    36509 36511 python    josevnz    3   unknown                           /misc/suricata/eve.json
</code></pre>
<p>I passed the <code>-b</code> option to lsof to avoid it from getting stuck, in case the <a target="_blank" href="https://access.redhat.com/solutions/2674">NFS handle is stale</a>.</p>
<p>A few things about lsof:</p>
<ul>
<li><p>If you are using Autofs, you should know than mount points eventually get un-mounted to save bandwidth. This can be problematic when trying to catch the access of a file that is only opened once.</p>
</li>
<li><p>The short-lived read didn't show up because the filehandle was closed after we inspected the process.</p>
</li>
<li><p>If you want to monitor ALL the processes on this machine, you may need to run as root. You can only inspect your own processes without special privileges.</p>
</li>
</ul>
<p>Still, lsof is a great tool to investigate.</p>
<p>Next strategy involves monitoring from the beginning, to catch the elusive short-read. We will use <a target="_blank" href="https://strace.io/">strace</a>.</p>
<h3 id="heading-how-to-use-strace">How to Use strace</h3>
<pre><code class="lang-shell">sudo dnf install -y strace
(tutorials) [josevnz@dmaf5 SpyOnNfs]$ strace -f ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json 2&gt;&amp;1| rg -e '/misc/data|/misc/suricata'
execve("./scripts/test_script.py", ["./scripts/test_script.py", "--quick_read", "/misc/data/nexus/log/jvm.log", "--follow", "/misc/suricata/eve.json"], 0x7ffd9ae29738 /* 46 vars */) = 0
execve("/home/josevnz/virtualenv/tutorials/bin/python", ["python", "./scripts/test_script.py", "--quick_read", "/misc/data/nexus/log/jvm.log", "--follow", "/misc/suricata/eve.json"], 0x7ffe269dbf88 /* 46 vars */) = 0
[pid 38241] openat(AT_FDCWD, "/misc/suricata/eve.json", O_RDONLY|O_CLOEXEC &lt;unfinished ...&gt;
[pid 38242] openat(AT_FDCWD, "/misc/data/nexus/log/jvm.log", O_RDONLY|O_CLOEXEC &lt;unfinished ...&gt;
</code></pre>
<p>The <code>openat(AT_FDCWD)</code> entries give away the two files our script is reading from NFS. But as you can tell this approach has some caveats:</p>
<ul>
<li><p>We are filtering the output. It is best to save the output to a file with 'tee' and then search there</p>
</li>
<li><p>It requires starting the process with strace from the beginning. Yes, you could do a 'strace -p $PID' to attach later to the process, but you risk missing short-lived reads</p>
</li>
</ul>
<p>Is there a different way? Time to move on to the next tool, <a target="_blank" href="https://www.wireshark.org/docs/man-pages/tshark.html">tshark</a> and see how to use a network capture to confirm access to the share.</p>
<h3 id="heading-how-to-use-tshark">How to Use tshark</h3>
<p>We can also capture the network traffic and filter out only NFS. <a target="_blank" href="https://ask.wireshark.org/question/3582/how-to-capture-filename-path-for-nfsv4-traffic-using-tshark/">It is not perfect</a>, but it may be sufficient.</p>
<p>First, find out which network interface is used to communicate with the NFS server. In my case it is easy – they all connected using a wired private network:</p>
<pre><code class="lang-shell">[josevnz@dmaf5 docs]$ ip --oneline address|rg -e 'eno|wlp'
3: eno1    inet 192.168.68.70/22 brd 192.168.71.255 scope global dynamic noprefixroute eno1\       valid_lft 4568sec preferred_lft 4568sec
4: wlp4s0    inet 192.168.1.95/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp4s0\       valid_lft 3423sec preferred_lft 3423sec
4: wlp4s0    inet6 fe80::ac40:5365:7f09:a5d2/64 scope link noprefixroute \       valid_lft forever preferred_lft forever
</code></pre>
<p>For this example it is eno1 with IP address '192.168.68.70'. Then capture the traffic, and with some luck we will get the file path:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# tshark -i eno1 -Y "nfs"
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eno1'
 ** (tshark:42326) 16:02:47.417145 [Main MESSAGE] -- Capture started.
 ** (tshark:42326) 16:02:47.417286 [Main MESSAGE] -- File: "/var/tmp/wireshark_eno1rEGxiu.pcapng"
   13 1.601197994 192.168.68.70 → 192.168.68.60 NFS 450 V4 Call GETATTR FH: 0x90ba4ee1  ; V4 Call GETATTR FH: 0x90ba4ee1
   14 1.601374466 192.168.68.70 → 192.168.68.60 NFS 258 V4 Call GETATTR FH: 0x90ba4ee1
   15 1.601395155 192.168.68.70 → 192.168.68.60 NFS 258 V4 Call GETATTR FH: 0x90ba4ee1
   16 1.602155254 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 13) GETATTR
   17 1.602368826 192.168.68.60 → 192.168.68.70 NFS 554 V4 Reply (Call In 13) GETATTR  ; V4 Reply (Call In 14) GETATTR
   19 1.602515091 192.168.68.70 → 192.168.68.60 NFS 274 V4 Call READ StateID: 0xa902 Offset: 57552896 Len: 12288
   20 1.602557170 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 15) GETATTR
   22 1.603156327 192.168.68.60 → 192.168.68.70 NFS 1730 V4 Reply (Call In 19) READ
   66 4.611124808 192.168.68.70 → 192.168.68.60 NFS 642 V4 Call GETATTR FH: 0x90ba4ee1  ; V4 Call GETATTR FH: 0x90ba4ee1  ; V4 Call GETATTR FH: 0x90ba4ee1
   67 4.611301059 192.168.68.70 → 192.168.68.60 NFS 258 V4 Call GETATTR FH: 0x90ba4ee1
   68 4.611809385 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 66) GETATTR
   69 4.611887552 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 66) GETATTR
   71 4.611976479 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 66) GETATTR
   72 4.620685968 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 67) GETATTR
   74 5.017200005 192.168.68.70 → 192.168.68.60 NFS 250 V4 Call GETATTR FH: 0x9419c00c
   75 5.017804843 192.168.68.70 → 192.168.68.59 NFS 242 V4 Call GETATTR FH: 0x314e720f
   76 5.017838787 192.168.68.60 → 192.168.68.70 NFS 310 V4 Reply (Call In 74) GETATTR
   77 5.018131217 192.168.68.70 → 192.168.68.60 NFS 326 V4 Call OPEN DH: 0x90ba4ee1/
   78 5.018711408 192.168.68.60 → 192.168.68.70 NFS 386 V4 Reply (Call In 77) OPEN StateID: 0x9984
   79 5.018855699 192.168.68.59 → 192.168.68.70 NFS 310 V4 Reply (Call In 75) GETATTR
   81 5.018980434 192.168.68.70 → 192.168.68.59 NFS 262 V4 Call GETATTR FH: 0xecd332cc
   82 5.019934959 192.168.68.59 → 192.168.68.70 NFS 310 V4 Reply (Call In 81) GETATTR
   83 5.020032853 192.168.68.70 → 192.168.68.59 NFS 262 V4 Call GETATTR FH: 0x261d4440
   84 5.020734032 192.168.68.59 → 192.168.68.70 NFS 310 V4 Reply (Call In 83) GETATTR
   85 5.020874175 192.168.68.70 → 192.168.68.59 NFS 330 V4 Call OPEN DH: 0xc9b4831b/
</code></pre>
<p>This is great, there is activity against two NFS servers, 192.168.68.59 and 192.168.68.60. But, is there a way to see the name of files?</p>
<p>tshark has a way to spit information by field. The problem is that NFS has lots of them:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# for field in $(tshark -G fields| cut -d'        ' -f3|rg -e '^nfs\.'); do echo "-e $field"; done|head -n 10
Running as user "root" and group "root". This could be dangerous.
-e nfs.unknown
-e nfs.svr4
-e nfs.knfsd_le
-e nfs.nfsd_le
-e nfs.knfsd_new
-e nfs.ontap_v3
-e nfs.ontap_v4
-e nfs.ontap_gx_v3
-e nfs.celerra_vnx
-e nfs.gluster
</code></pre>
<p>So, let's <a target="_blank" href="https://www.wireshark.org/docs/dfref/n/nfs.html">capture them</a> into a variable (<a target="_blank" href="https://wiki.wireshark.org/NFS_Preferences">also need to enable some options</a>):</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# fields=$(for field in $(tshark -G fields| cut -d'       ' -f3|rg -e '^nfs\.'); do echo "-e $field"; done)
[root@dmaf5 ~]# tshark -i eno1 --enable-protocol nfs -o nfs.file_name_snooping:true -o nfs.file_full_name_snooping:true -T fields -E header=y -E separator=, -E quote=d $fields
Running as user "root" and group "root". This could be dangerous.
nfs.unknown,nfs.svr4,nfs.knfsd_le,nfs.nfsd_le,nfs.knfsd_new,nfs.ontap_v3,nfs.ontap_v4,nfs.ontap_gx_v3,n...
</code></pre>
<p>I managed to get the filename only once, then after interrupting and restarting the program I got no luck.</p>
<p>And yet no sign of the file name. The file handle was in the contents but this is not very useful if you want a quick way to see what was accessed.</p>
<p>Is there an easier way to do this? Sysdig may offer some answers.</p>
<h3 id="heading-how-to-use-sysdig">How to Use Sysdig</h3>
<p>While trying to find the elusive mount points, I stumbled into <a target="_blank" href="https://github.com/draios/sysdig">Sysdig</a>:</p>
<p>Sysdig instruments your physical and virtual machines at the OS level by installing into the Linux kernel and capturing system calls and other OS events. Sysdig uses <a target="_blank" href="https://en.wikipedia.org/wiki/DTrace">DTrace</a> to get access to the system kernel.</p>
<p>Sysdig also makes it possible to create trace files for system activity, similarly to what you can do for networks with tools like tcpdump and Wireshark.</p>
<p>I decided to use the latest version (<a target="_blank" href="https://github.com/draios/sysdig/releases/tag/0.33.1">0.33.1</a>) for Fedora 37 where my script is running):</p>
<pre><code class="lang-shell">sudo dnf install -y https://github.com/draios/sysdig/releases/download/0.33.1/sysdig-0.33.1-x86_64.rpm
# Wait a little bit, as a kernel module needs to be compiled and prepared...
Installed:
  bison-3.8.2-3.fc37.x86_64                    dkms-3.0.11-1.fc37.noarch          elfutils-libelf-devel-0.189-3.fc37.x86_64  flex-2.6.4-11.fc37.x86_64            kernel-devel-6.4.13-100.fc37.x86_64 
  kernel-devel-matched-6.4.13-100.fc37.x86_64  libzstd-devel-1.5.5-1.fc37.x86_64  m4-1.4.19-4.fc37.x86_64                    openssl-devel-1:3.0.9-1.fc37.x86_64  sysdig-0.33.1-1.x86_64              
  zlib-devel-1.2.12-5.fc37.x86_64
</code></pre>
<p>How easy is to probe out the script so it is indeed accessing the NFS mounted directories? Let's print three fields of interest and the name of the accesed file:</p>
<pre><code class="lang-shell"># `sysdig -l` will output every single field you can capture
[root@dmaf5 ~]# sysdig -p"%proc.cmdline,%fd.name" proc.name contains python and fd.name contains /misc
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
...
</code></pre>
<p>What if you want to capture all the data, and filter later? One way to do it is capturing to a file:</p>
<pre><code class="lang-shell"># Capture for one minute...
[root@dmaf5 ~]# timeout --preserve-status 1m sysdig -w /tmp/sysdig.dump
[root@dmaf5 ~]# ls -lh /tmp/sysdig.dump
-rw-r--r--. 1 root root 32M Sep 10 19:03 /tmp/sysdig.dump
</code></pre>
<p>And then replay the contents, with filtering (replay doesn't need elevated privileges):</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# sysdig -r /tmp/sysdig.dump -p"%proc.cmdline,%fd.name" proc.name contains python and fd.name contains /misc|sort -u
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/data/nexus/log/jvm.log
python ./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose,/misc/suricata/eve.json
</code></pre>
<p>Sysdig supports scripting, using the <a target="_blank" href="https://www.lua.org/">LUA language</a>. For example, it has a very convenient version of lsof:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# sysdig -cl|rg lsof
lsof            List (and optionally filter) the open file descriptors.
</code></pre>
<p>So let's use it:</p>
<pre><code class="lang-shell">[root@dmaf5 ~]# sysdig -c lsof|rg misc
automount           52410   52410   root    8       directory   /misc
automount           52410   52413   root    8       directory   /misc
automount           52410   52414   root    8       directory   /misc
automount           52410   52415   root    8       directory   /misc
automount           52410   52418   root    8       directory   /misc
automount           52410   52421   root    8       directory   /misc
python              75840   75840   josevnz 3       file        /misc/suricata/eve.json
python              75840   75841   josevnz 3       file        /misc/suricata/eve.json
python              75840   75842   josevnz 3       file        /misc/suricata/eve.json
</code></pre>
<p>What I liked about this tool:</p>
<ul>
<li><p>Can work with older kernels (like 4.xx)</p>
</li>
<li><p>Has a powerful expression language for filtering</p>
</li>
<li><p>Easy to learn and well documented</p>
</li>
<li><p>You can write your own scripts if you know LUA</p>
</li>
</ul>
<p>Before finishing up let's look at one more tool, BPF.</p>
<h3 id="heading-how-to-use-bpf-probe">How to Use BPF probe</h3>
<p>Originally Berkeley Packet Filter, is a kernel and user-space observability scheme for Linux.</p>
<p>The BPF is a <a target="_blank" href="https://www.linuxjournal.com/content/bpf-observability-getting-started-quickly">very powerful tool</a>, and this short article won't even scratch the surface.</p>
<p>Yes, this is huge. I'm learning this myself.</p>
<p>I found that the <a target="_blank" href="https://github.com/iovisor/bcc">bcc</a> repository has lots of ready to use scripts that we could use to track our NFS access, and even check for performance (you can find more examples <a target="_blank" href="https://github.com/iovisor/bpftrace">here</a>, and on the <a target="_blank" href="https://github.com/brendangregg/bpf-perf-tools-book/tree/master">BPF Performance Book repository</a>).</p>
<p>But it is more interesting to write tools yourself that monitor pretty much anything you want. For this tutorial, I will use some ready to use programs that use the traces to capture useful information.</p>
<p>As a first step, we will need to install a high level interpreter for our scripts. Again, on my Fedora Linux machine:</p>
<pre><code class="lang-shell">[josevnz@dmaf5 ~]$ sudo dnf install -y bpftrace.x86_64 bcc-tools.x86_64
# And check if the kernel has btf enabled
[josevnz@dmaf5 ~]$ ls -la /sys/kernel/btf/vmlinux
-r--r--r--. 1 root root 5635179 Sep 12 04:21 /sys/kernel/btf/vmlinux
</code></pre>
<p>On a separate terminal run again the NFS test script:</p>
<pre><code class="lang-shell">. ~/virtualenv/tutorials/bin/activate
cd SpyOnNfs/
./scripts/test_script.py --quick_read /misc/data/nexus/log/jvm.log --follow /misc/suricata/eve.json --verbose
</code></pre>
<p>You can trace all the files opened by a program, like top:</p>
<pre><code class="lang-shell">18:59:20 loadavg: 1.20 1.00 0.74 1/1175 28520

TID     COMM             READS  WRITES R_Kb    W_Kb    T FILE
28520   clear            2      0      60      0       R xterm-256color
28203   python           7      0      56      0       R eve.json
28347   filetop          2      0      15      0       R loadavg
824     systemd-oomd     2      0      8       0       R memory.swap.current
824     systemd-oomd     2      0      8       0       R memory.low
...
</code></pre>
<p>But it doesn't print the full path. It's more useful to ask a NFS snoop and see if one of our files shows up:</p>
<pre><code class="lang-shell">[josevnz@dmaf5 SuricataLog]$ sudo /usr/share/bcc/tools/nfsslower 1
# Commented out some warnings ...
Tracing NFS operations that are slower than 1 ms... Ctrl-C to quit
TIME     COMM           PID    T BYTES   OFF_KB   LAT(ms) FILENAME
19:02:25 python         28202  R 1460    62150       1.96 eve.json
19:02:28 python         28202  R 2446    62151       2.09 eve.json
19:02:31 python         28202  R 970     62154       1.99 eve.json
19:02:34 python         28202  R 3335    62155       2.43 eve.json
19:02:37 python         28202  R 4564    62158       1.84 eve.json
19:02:40 python         28202  R 5876    62162       1.89 eve.json
19:02:43 python         28202  R 4504    62168       1.61 eve.json
19:02:46 python         28202  R 3131    62173       1.92 eve.json
</code></pre>
<p>This is much better. Also, we can see than the latency is almost two milliseconds.</p>
<p>We can also monitor mount/ umount operations:</p>
<pre><code class="lang-shell">[josevnz@dmaf5 SuricataLog]$ sudo /usr/share/bcc/tools/mountsnoop 
# Commented out some warnings ...
2 warnings generated.
COMM             PID     TID     MNT_NS      CALL
mount.nfs        29012   29012   4026531841  mount("orangepi5:/data", "/misc/data", "nfs", MS_RDONLY, "sloppy,soft,rsize=16384,wsize=16384,vers=4.2,addr=192.168.68.59,clientaddr=192.168.68.68") = 0
</code></pre>
<p>This is good as well, we can see the activity over NFS we wanted to confirm.</p>
<h2 id="heading-next-steps">Next Steps</h2>
<p>You learned several tools and as you may have guessed, you can use them to snoop on more than just opened files on NFS.</p>
<p>It is always useful to know more than one tool. Sysdig has a special mention for being very versatile, powerful and yet easy to use. Also, it can be extended with scripts written in the LUA language.</p>
<p>BPF is another alternative and will give you incredible access to the kernel calls. Be prepared to spend time reading and learning how to use the tools.</p>
<p>The code for the scripts used on this tutorial can be obtained from my <a target="_blank" href="https://github.com/josevnz/tutorials/tree/main/docs/SpyOnNfs">GitHub repository: SpyOnNfs</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ TCP and UDP Protocols – Explained in Plain English ]]>
                </title>
                <description>
                    <![CDATA[ Did you know that it's thanks to the TCP and UDP protocols that the internet works? But what do these acronyms mean? Well, TCP stands for Transmission Control Protocol and UDP stands for User Datagram Protocol Ok, but what are they? Why are they usef... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tcp-and-udp-protocols/</link>
                <guid isPermaLink="false">66ba5347154fcfa01a69956c</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tiago Capelo Monteiro ]]>
                </dc:creator>
                <pubDate>Thu, 10 Aug 2023 22:19:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/pexels-pixabay-159304.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Did you know that it's thanks to the TCP and UDP protocols that the internet works?</p>
<p>But what do these acronyms mean?</p>
<p>Well, TCP stands for Transmission Control Protocol and UDP stands for User Datagram Protocol</p>
<p>Ok, but what are they? Why are they useful? Why is it thanks to these protocols that the internet works?</p>
<p>In this article, we'll start with a simple analogy to help you understand the ideas behind TCP and UDP. Then I'll explain how they work in plain English. Next we'll discuss why these protocols are important, and we'll understand their key differences.</p>
<h2 id="heading-what-are-tcp-and-udp-explained-with-an-analogy">What are TCP and UDP? Explained with an Analogy</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/letter.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Photo by Suzy Hazelwood from Pexels: https://www.pexels.com/photo/shallow-focus-of-letter-paper-1157151/</em></p>
<p>You can think about TCP and UDP in a similar way as you think about a mail service.</p>
<p>Just like a <strong>mail service</strong> sends <strong>letters</strong> to <strong>individuals, TCP and UDP</strong> send <strong>packets</strong> to <strong>computers</strong>.</p>
<p>Packets are just formatted units of data in bytes.</p>
<p>TCP works more like a registered mail service. With registered mail, the sender sends a parcel to a recipient, and they're notified when the parcel is delivered. The sender can also track the parcel if it is lost or delayed.</p>
<p>On the other hand, UDP is like a regular mail service. The sender sends a parcel without any confirmation of delivery. There is also no tracking or guarantee that the parcel is going to be delivered.</p>
<h2 id="heading-how-do-tcp-and-udp-work">How Do TCP and UDP Work?</h2>
<p>Both the UDP and TCP are protocols used to ensure that data is reliably and securely transmitted between devices over a network.</p>
<p>TCP creates a connection between the sender and receiver and then data is transmitted between packets.</p>
<p>TCP also ensures that all packets are delivered in order. Additionally, it has mechanisms for resending lost packets and managing flow control. </p>
<p>Meanwhile, UDP sends packets without establishing a connection. Because of this, packets can be lost or arrive out of order as there is no mechanism to request retransmission.</p>
<h2 id="heading-tcp-vs-udp-whats-the-difference">TCP vs UDP – What's the Difference?</h2>
<p>Both UDP and TCP were developed starting in the 1980s.</p>
<p>TCP is important in programming because it provides a reliable and secure way for devices to communicate with each other over a network.</p>
<p>Without TCP, it would be difficult for devices to communicate securely, and many of the applications that we use today would not exist.</p>
<p>For example email communication, file transfers, and online transactions would all be very difficult without TCP.</p>
<p>TCP is preferred for secure, ordered, and reliable data transmission, as well as for delivering large amounts of data with minimal delay and mitigating network congestion.</p>
<p>UDP is also important for connections that require a lot broadband where security is not an issue.</p>
<p>For example video streaming services, online gaming platforms, and IoT devices can all use UDP to transmit data.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With these protocols, the internet can operate safely and devices can communicate with each other effectively.</p>
<p>These concepts are key to understand if you're interested in Computer Networking. If you want to learn more about networking, you can <a target="_blank" href="https://www.freecodecamp.org/news/computer-networking-how-applications-talk-over-the-internet/">read this tutorial</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Networking in Flutter By Building a Simple App ]]>
                </title>
                <description>
                    <![CDATA[ Almost all apps you use today run by accessing the internet. You can hardly find an app that runs without connecting to the internet.  The internet has become an integral part of our lives, as it solves one of the most critical problems we have to ha... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-networking-in-flutter/</link>
                <guid isPermaLink="false">66ba10e3228e16bed602a8a5</guid>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Mon, 15 May 2023 18:42:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Networking-in-Flutter---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Almost all apps you use today run by accessing the internet. You can hardly find an app that runs without connecting to the internet. </p>
<p>The internet has become an integral part of our lives, as it solves one of the most critical problems we have to handle: data transfer. We're constantly either receiving or sending data to someone – whether it's a social media app, news app, or whatever type it may be, there's some form of data transfer. </p>
<p>Because of this, it's super important to learn networking if you're learning mobile app development. In this article I'll be explaining how to build a super simple mobile app that fetches data from internet and renders it on the app. </p>
<h2 id="heading-how-to-create-the-project">How to Create the Project</h2>
<p>Navigate to the folder where you want to create your project in the terminal and run the following command:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/5minslearn/Flutter-Boilerplate.git
</code></pre>
<p>Navigate to the Flutter-Boilerplate folder and run the <code>flutter pub get</code> command to install the dependencies. </p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> Flutter-Boilerplate/
flutter pub get
</code></pre>
<p>That's it. We've got our dependencies installed.</p>
<p>Open the project in Visual Studio Code by running the <code>code ./</code> command in the terminal.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-40.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Flutter app from boiler plate</em></p>
<p>Start your emulator/connect your device and press <code>F5</code> in VS Code to run your app.</p>
<p>At the moment, the app will just contain an empty screen as shown in the below screenshot. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-41.png" alt="Image" width="600" height="400" loading="lazy">
<em>Flutter app with empty screen</em></p>
<p>Let's build our networking app. </p>
<h2 id="heading-where-to-get-the-data">Where to Get the Data</h2>
<p>This is the most obvious question. If we were to fetch something from the internet and render, we need an API server exposing the data we need. But, most people cannot afford to do that for learning purposes. To overcome this, many people are offering free API services. </p>
<p>You can consume the data from their API services for learning purposes. But, we cannot validate the originality of the data, as most of them will be random. </p>
<p>In this tutorial, we'll be using the API exposed by <a target="_blank" href="https://sampleapis.com/">https://sampleapis.com/</a>. They expose an API endpoint that lists Coding Resources. The URL of the endpoint is <a target="_blank" href="https://api.sampleapis.com/codingresources/codingResources">https://api.sampleapis.com/codingresources/codingResources</a>. </p>
<p>In our app, we'll fetch the data from this endpoint and list them in our app. </p>
<h2 id="heading-install-the-dependencies">Install the Dependencies</h2>
<p>Let's install the dependencies we need to build this app. They are:</p>
<ol>
<li>The <code>http</code> package</li>
<li>The <code>url_launcher</code> package</li>
</ol>
<p>We'll use the <code>http</code> package to make a call to the API endpoint. And we'll use the <code>url_launcher</code> package to open a URL in an external browser. </p>
<p>Open the <code>pubspec.yml</code> file and add the following two packages in the dependencies section:</p>
<pre><code class="lang-bash">  http: ^0.13.6
  url_launcher: ^6.1.11
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>Add dependencies</em></p>
<p>If you're using VS Code as your IDE, the dependencies will be installed automatically by saving this file. For the other IDEs, run <code>flutter pub get</code> on your project root folder to install the dependencies. </p>
<h2 id="heading-how-to-fetch-the-data-from-the-api">How to Fetch the Data from the API</h2>
<p>We got our dependencies ready. Let's make a request to our API and get the data. </p>
<p>Import the <code>http</code> package in the <code>lib/main.dart</code> file. </p>
<pre><code class="lang-bash">import <span class="hljs-string">'package:http/http.dart'</span> as http;
</code></pre>
<p>Initialize a list object in the <code>_MyHomePageState</code> class by adding the following code:</p>
<pre><code class="lang-dart"><span class="hljs-built_in">List</span> _resources = [];
</code></pre>
<p>Let’s write a method that makes a call to our API endpoint and decode them into a JSON object. </p>
<pre><code class="lang-dart">  <span class="hljs-keyword">void</span> _fetchResources() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">final</span> response = <span class="hljs-keyword">await</span> http.<span class="hljs-keyword">get</span>(<span class="hljs-built_in">Uri</span>.parse(
        <span class="hljs-string">'https://api.sampleapis.com/codingresources/codingResources'</span>));
    <span class="hljs-keyword">if</span> (response.statusCode == <span class="hljs-number">200</span>) {
      <span class="hljs-keyword">final</span> data = json.decode(response.body) <span class="hljs-keyword">as</span> <span class="hljs-built_in">List</span>;
      setState(() {
        _resources = data;
      });
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">throw</span> Exception(<span class="hljs-string">'Failed to load resources'</span>);
    }
  }
</code></pre>
<p>Paste the above code into the <code>MyHomePageState</code> class. In the above method, we’re making a call to the API endpoint (<a target="_blank" href="https://api.sampleapis.com/codingresources/codingResources">https://api.sampleapis.com/codingresources/codingResources</a>). From the response, we’re validating if it's successful in receiving the data by checking if its status code is <code>200</code> (and throwing an error if it’s not). We then decode the received data and save it in our app’s state. </p>
<p>You may notice an error after pasting the above code at the <code>json.decode</code> part. In order to decode JSON, we need import a <code>convert</code> package in our file. Add the following code at the top of the file:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:convert'</span>;
</code></pre>
<p>The error should be gone now. </p>
<p>We have a method that makes a call to the API endpoint and saves the data in the state. Our next step is to trigger this method when we open the app. </p>
<p>We can do that by overriding the <code>initState</code> method. </p>
<pre><code class="lang-dart">  <span class="hljs-meta">@override</span>
  <span class="hljs-keyword">void</span> initState() {
    <span class="hljs-keyword">super</span>.initState();
    _fetchResources();
  }
</code></pre>
<p>Quoting from the Flutter <a target="_blank" href="https://api.flutter.dev/flutter/widgets/State/initState.html">documentation</a>, </p>
<blockquote>
<p>"<code>initState</code> is called when this object is inserted into the tree. The framework will call this method exactly once for each <a target="_blank" href="https://api.flutter.dev/flutter/widgets/State-class.html">State</a> object it creates."</p>
</blockquote>
<p>In the above code, we called our method <code>_fetchResources()</code> in the <code>initState()</code> method. </p>
<h2 id="heading-how-to-build-the-ui">How to Build the UI</h2>
<p>We got the list of items whenever we open the app. Our next step is to render them on the UI. </p>
<p>Copy the below code and replace it with the <code>build</code> method of the <code>_MyHomePageState</code> class. </p>
<pre><code class="lang-dart"><span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: _resources.isEmpty
            ? <span class="hljs-keyword">const</span> Center(
                child: CircularProgressIndicator(),
              )
            : ListView.builder(
                itemCount: _resources.length,
                itemBuilder: (context, index) {
                  <span class="hljs-keyword">final</span> resource = _resources[index];
                  <span class="hljs-keyword">return</span> InkWell(
                      onTap: () =&gt; {},
                      child: Card(
                          child: ListTile(
                        title: Text(resource[<span class="hljs-string">'description'</span>]),
                        subtitle: Text(resource[<span class="hljs-string">'url'</span>]),
                        leading: <span class="hljs-keyword">const</span> CircleAvatar(
                            backgroundImage: NetworkImage(
                                <span class="hljs-string">"https://images.unsplash.com/photo-1547721064-da6cfb341d50"</span>)),
                        trailing: Text(resource[<span class="hljs-string">'types'</span>].join(<span class="hljs-string">', '</span>)),
                      )));
                }));
  }
</code></pre>
<p>Let’s understand the above code. </p>
<p>We show a loader if our state has empty values. If it has some values in it, we’ll iterate through as a ListView builder and we render a card widget for each item, displaying the <code>description</code>, <code>url</code>, and <code>types</code> of the resource. </p>
<p>That’s it. </p>
<p>Run the app by pressing <code>F5</code> and you should be able to see the following: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>Loading the resources</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-44.png" alt="Image" width="600" height="400" loading="lazy">
<em>Showing the resources</em></p>
<p>That’s awesome, isn’t it? </p>
<h2 id="heading-lets-fix-the-missing-part">Let's Fix the Missing Part</h2>
<p>But I feel there’s one small thing that’s missing at this point.</p>
<p>We’re able to see the list of the resources. But, we’re not able to view those resources. Some resources have a short link that we can easily remember and type. But, a few of them have a long URL which would be hard for a typical human being to remember. Let’s add a small enhancement that when we click on a resource, its link should be opened in our default browser. </p>
<p>This is very simple to implement in Flutter. This is the reason we added the <code>url_launcher</code> package at the beginning of this tutorial. </p>
<p>Import the <code>url_launcher</code> package in your app like this</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:url_launcher/url_launcher.dart'</span>;
</code></pre>
<p>Add the following method in the <code>_MyHomePageState</code> class:</p>
<pre><code class="lang-dart">_launchURL(<span class="hljs-built_in">String</span> url) <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">await</span> canLaunch(url)) {
      <span class="hljs-keyword">await</span> launch(url);
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">throw</span> <span class="hljs-string">'Could not launch <span class="hljs-subst">$url</span>'</span>;
    }
  }
</code></pre>
<p>The above method accepts a URL, validates the link, and opens it in the browser. </p>
<p>We have to call this method on tapping the card. We can achieve that by calling this method in the <code>onTap</code> property of the <code>InkWell</code> widget. </p>
<p>Here’s the code for it:</p>
<pre><code class="lang-dart">onTap: () =&gt; {_launchURL(resource[<span class="hljs-string">'url'</span>])},
</code></pre>
<p>Let’s run our app and test this. </p>
<p>You were likely disappointed on tapping a card – I certainly was while working on this. </p>
<p>You should have seen this error:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-45.png" alt="Image" width="600" height="400" loading="lazy">
<em>Error on opening a url: Exception has occurred. "Could not launch https://www.youtube.com/bocajs"</em></p>
<p>Though the URL is right, why is our system not opening this in a browser?</p>
<h2 id="heading-what-are-intent-actions">What are Intent Actions?</h2>
<p>Well, now we have to learn about intent actions. </p>
<p>Quoting it from Android Developers <a target="_blank" href="https://developer.android.com/reference/android/content/Intent">documentation</a>, </p>
<blockquote>
<p>"An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed."</p>
</blockquote>
<p>This basically means that when we hand over something to the external app, we have to declare that in our app. For Android, we have to define it in <code>AndroidManifest.xml</code> and for iOS most of these configurations go into the <code>Info.plist</code> file. </p>
<p>Add the <code>queries</code> block in the following code to your <code>AndroidManifest.xml</code> file. </p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">manifest</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">application</span>&gt;</span>
        ...
    <span class="hljs-tag">&lt;/<span class="hljs-name">application</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">queries</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">intent</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">action</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.action.VIEW"</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.BROWSABLE"</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">data</span> <span class="hljs-attr">android:scheme</span>=<span class="hljs-string">"https"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">intent</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">queries</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">manifest</span>&gt;</span>
</code></pre>
<p>Uninstall the app from your mobile and run the app again. </p>
<p>Hopefully you should be able to see the link opened in the browser. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>Link opened on a browser</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you’ve learned about networking in Flutter. We made a request to an API, rendered the list, and opened the URL in the browser. </p>
<p>This <a target="_blank" href="https://github.com/5minslearn/Flutter-Networking">repo</a> has my code. You can use it for your reference. </p>
<p>To learn more about Flutter, subscribe to my email newsletter on my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_networking">site</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_networking">https://5minslearn.gogosoon.com</a>) and follow me on social media. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Understanding VPC Architecture – How to Secure AWS EC2 Instances ]]>
                </title>
                <description>
                    <![CDATA[ AWS Virtual Private Clouds (VPCs) are the organizing structure of most AWS network operations. Without a clear understanding of how they work, it'll be hard to get security and efficiency quite right.  But before talking about VPCs directly, I'm goin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understanding-vpc-architecture-securing-aws-ec2-instances/</link>
                <guid isPermaLink="false">66b9965ca3099de4654e61b9</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 02 May 2023 13:33:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/pexels-sevenstorm-juhaszimrus-425160.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>AWS Virtual Private Clouds (VPCs) are the organizing structure of most AWS network operations. Without a clear understanding of how they work, it'll be hard to get security and efficiency quite right. </p>
<p>But before talking about VPCs directly, I'm going to take a minute or two to refresh your memories on the basics of TCP/IP networking architecture and NAT addressing. </p>
<p>But feel free to skip the next bit if you're already dug in on all that. When that's behind us, though, I'll show you what building VPCs in AWS looks like. </p>
<h2 id="heading-a-quick-tcpip-primer">A Quick TCP/IP Primer</h2>
<p>Ok. So TCP stands for Transmission Control Protocol and IP stands for Internet Protocol. If those sound a bit broad – almost as if they're trying to describe the totality of the internet – it's because just about everything we do on the internet is indeed controlled by these half century-old TCP/IP protocols.</p>
<p>This article comes from my <a target="_blank" href="https://www.udemy.com/course/securing-amazon-ec2-instances/?referralCode=E3ACB9DC5E3B77853E63">Securing Your AWS EC2 Instances course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/iCal_Tzvg9g" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>For our purposes, remember that every network-connected device must have a unique IP address. Given that, mathematically, there can be no more than four billion 32-bit IPv4 addresses, and that there are already far more than four billion network-connected devices on the internet, something had to change. </p>
<pre><code>A typical IPv4 address:
<span class="hljs-number">192.168</span><span class="hljs-number">.2</span><span class="hljs-number">.45</span>
</code></pre><p>The 128-bit IPv6 protocol was eventually introduced to allow <em>trillions</em> of unique addresses. We'll never run out of those. </p>
<pre><code>A typical IPv6 address:
fd42:e265:<span class="hljs-number">3791</span>:<span class="hljs-number">64</span>f9:<span class="hljs-number">216</span>:<span class="hljs-number">3</span>eff:fe54:fcfe/<span class="hljs-number">64</span>
</code></pre><p>But before IPv6, another brilliant solution was introduced: NAT networking. </p>
<h2 id="heading-what-is-network-address-translation-nat">What is Network Address Translation (NAT)?</h2>
<p>The NAT protocol sets aside three network segments for use in <em>private</em> networks only. Using NAT, your home can have 15 or 20 devices – including laptops, smartphones on WiFi, network printers, routers, and maybe a smart fridge or two – but between them, they'll use up only a single public IP address. </p>
<p>How does that work? Well, your internet service provider will assign that one public IP to the modem they send you. But that modem will act as a DHCP server and assign each <em>local</em> device a <em>private</em> IP address from one of those three network segments. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/slide-31.png" alt="Image" width="600" height="400" loading="lazy">
<em>A typical NAT architecture</em></p>
<p>The DHCP server will <em>translate</em> all requests moving between your local devices and internet-based services in a way that leaves those internet services thinking that your device's IP is actually the single public one. </p>
<p>But incoming network packets are actually delivered right to your device using its local NAT address. The system really is brilliant. And it added decades of life to the IPv4 system.</p>
<p>But once we have NAT in place anyway, it can actually do a whole lot more than just translate local addressing. Which brings us to why we're talking about this stuff in the context of EC2 instance security in the first place. </p>
<p>You see, NAT allows for very sophisticated network segmenting. By carefully configuring addressing and routing rules, you can turn a single local network into a multi-layered, highly-secured environment for mission-critical enterprise deployments. </p>
<p>Here's an illustration of a replicated environment using public and private subnets from AWS documentation.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/bastion_aws.png" alt="Image" width="600" height="400" loading="lazy">
<em>How bastion hosts might fit into an AWS VPC</em></p>
<p>The only connection with the outside world, such a private subnet, would have flows through a bastion host and a NAT gateway living in an adjacent public subnet. Forcing everything through those two devices lets you precisely control traffic. </p>
<p>The bastion host provides a jump box allowing admins to safely open remote SSH sessions on instances running in your private subnets. And the NAT gateway allows services running on your private instances outbound access to, for example, pull software updates. Both bastion hosts and NAT gateways will incur regular usage costs, by the way.</p>
<h2 id="heading-how-to-optimize-vpc-networks">How to Optimize VPC Networks</h2>
<p>Now I'll show you how all this works within the AWS ecosystem. From the VPC dashboard I can click Create VPC. Right away I've got a decision to make: do I want to build just a simple VPC where I can host some resources, or something more complicated?</p>
<p>If I go with VPC only, I'll just need to give the VPC a name, select my addressing environments and I'm good to go. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/ec2_security8-f007434.png" alt="Image" width="600" height="400" loading="lazy">
<em>Part of the VPC configuration interface in AWS</em></p>
<p>But we're here to test drive the <em>VPC and more</em> option. As you can see, that'll open up an infrastructure preview to the right that shows us exactly what will be created based on the current selections, and what they'll look like. </p>
<p>Right now, as you can see, we'll get one public and one private subnet in each of two availability zones, and appropriate route tables and network connections to make everything work. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/ec2_security8-f007926.png" alt="Image" width="600" height="400" loading="lazy">
<em>Note how AWS automatically assigns logical names to new subnets</em></p>
<p>Note how each object is automatically given a name that properly reflects the naming structure I specified. All this automatically conforms with security and availability best-practices</p>
<p>I can choose to specify a dedicated tenancy for new instances launched into this VPC – although, as I mentioned earlier, that probably won't be relevant for all that many cases.</p>
<p>The number of availability zones you configure will reflect the depth of fault tolerance your application needs. The more zones, the less chance your application goes down. </p>
<p>Of course, by that same token, the more zones, the more instances you'll need to run and the more you'll spend. You can see that editing this value will have an instance impact on the subnet settings to the right.</p>
<p>You can similarly control the number of public and private subnets. The options available will reflect the number of availability zones you selected above. Basically, the UI makes it pretty much impossible to do something stupid – which is something I appreciate.</p>
<p>Adjusting the subnets within the UI will automatically update the configuration to the right. Selecting a NAT gateway will generate a new object with all the appropriate connectivity built-in. </p>
<p>One last really nice tool is the fields that let us fine tune the address allocation for our subnets. This could be important if you're planning to deploy, say, large numbers of virtual containers into a couple of public subnets but nothing more than a handful of database servers in your private subnets. You'll probably need a lot more addresses in the former and fewer in the latter.</p>
<p>Once you fire up your VPC, it'll take just a few seconds for all the parts to fall into place. When that's done, you'll be able to navigate to the Your VPCs dashboard to confirm what's now available. </p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>We covered a lot of ground in this article. You learned how VPCs can be designed to employ sophisticated routing topologies that expose and block resources to efficiently meet your operational and security needs.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Network Traffic is Routed ]]>
                </title>
                <description>
                    <![CDATA[ Moving around the internet – or even over a private local network – requires all kinds of magic wand waving and sorcery.  Or, in sightly more accurate terms, it requires the combination of sophisticated engineering and the existence of key standards,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-network-traffic-is-routed/</link>
                <guid isPermaLink="false">66b995e694b336889c600432</guid>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 19 Apr 2023 22:23:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/pexels-barry-tan-7994953.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Moving around the internet – or even over a private local network – requires all kinds of magic wand waving and sorcery. </p>
<p>Or, in sightly more accurate terms, it requires the combination of sophisticated engineering and the existence of key standards, including network ports, the domain Name System (DNS) and routing policies. And we're going to learn how some of that works in this article.</p>
<p>Besides IP addresses (identifiers that could look something like <code>192.168.2.54</code> or <code>e80::1164:3e06:6716:7a0b/64</code>), network traffic can be routed between devices or even individual services running on a device using TCP and UDP ports. </p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-security-essentials-exam-study-guide/?referralCode=C2B6802EDB99578238B5">The Complete LPI Security Essentials Exam Study Guide</a>. You can also follow along using this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GaTTrXcO13I" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-routing-network-traffic-using-network-ports">Routing Network Traffic Using Network Ports</h2>
<p>Ports are numbers used to identify specific applications or services running on a device. When data is transmitted over the network, the source and destination ports are included in the data packet to ensure that the data is sent to the correct application or service.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers">There are 65,535 TCP and UDP ports in total</a>, each of which can be assigned to a specific application or service for communication over the Internet. </p>
<p>The first 1024 ports are reserved for well-known services and are typically assigned to specific applications or services by the Internet Assigned Numbers Authority. For example, HTTP (Hypertext Transfer Protocol) uses port 80, while HTTPS (HTTP Secure) uses port 443.</p>
<p>The remaining ports (above 1024) are called ephemeral ports and can be used by any application or service that needs to communicate over the Internet. When a device initiates a connection, it selects an available ephemeral port to use for the duration of the connection.</p>
<p>Devices can also be identified by unique hardware Media Access Control addresses. MAC addresses – assigned at the link-layer of the OSI model – are used to identify devices on a local network segment and to provide a way for data to be transmitted directly to the correct device. Here's a typical MAC address:</p>
<pre><code><span class="hljs-number">40</span>:b0:<span class="hljs-number">72</span>:d4:<span class="hljs-number">29</span>:ab
</code></pre><h2 id="heading-what-is-the-domain-name-system-dns">What is the Domain Name System (DNS)?</h2>
<p>The Domain Name System is a system used to translate human-readable domain names into IP addresses. This allows users to access websites and other Internet resources using easy-to-remember domain names instead of IP addresses. </p>
<p>DNS also provides other important functions, such as mapping IP addresses to multiple domain names and directing traffic to the correct server based on the location of the user.</p>
<p>Forward DNS refers to the process of converting a domain name, such as "www.example.com", into an IP address, such as "192.0.2.1". Forward DNS is used by clients to resolve domain names to IP addresses, so that they can access websites, email servers, and other network services.</p>
<p>Reverse DNS, on the other hand, is the process of converting an IP address into a domain name. Reverse DNS is used to identify the domain name associated with a particular IP address. </p>
<p>This information can be used for security purposes, such as identifying the source of an incoming network connection, or for tracking the origin of spam or malicious traffic.</p>
<p>Public DNS servers are operated by organizations such as Google, Cloudflare, and OpenDNS, and are available for use by anyone on the Internet. Public DNS servers are often used as an alternative to the DNS servers provided by Internet Service Providers, as they can offer faster resolution times, better security features, and increased privacy.</p>
<h2 id="heading-hardware-routing-devices">Hardware Routing Devices</h2>
<p>From a hardware perspective, traffic routing is managed through a loosely related family of networking devices. It should be noted that a single device will sometimes come with features normally identified with more than one category. </p>
<ul>
<li>Switches allow multiple devices on a network to communicate with each other by forwarding data packets to the intended recipient. </li>
<li>Routers connect multiple networks together and forward data packets between them. Routers use routing tables to determine the best path for the data to take. </li>
<li>Access Points allow wireless devices to connect to a wired network. They act as a bridge between the wireless devices and the network router.</li>
</ul>
<p>It's useful to bear in mind that a "default router" is the gateway IP address used by devices on a network to communicate with devices on a different network. The default router is typically the IP address of the network router.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Understanding the software and hardware tools used to connect all of our many devices across digital networks can help you troubleshoot when things go wrong. But it's also a critical component for understanding the problems – and solutions – involved with network security.</p>
<p>This article and the accompanying video are excerpted from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-security-essentials-exam-study-guide/?referralCode=C2B6802EDB99578238B5">my Complete LPI Security Essentials Exam Study Guide course</a>. And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is An ACL? Access Control Lists Explained ]]>
                </title>
                <description>
                    <![CDATA[ In computing, access control is the concept of limiting or regulating a person or machine's access to certain information or resources. One of the major mechanisms you use to do that is an access control list (ACL). An ACL is a set of rules for allow... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-deep-dive-into-access-control-lists/</link>
                <guid isPermaLink="false">66d45dd53a8352b6c5a2aa0b</guid>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chidiadi Anyanwu ]]>
                </dc:creator>
                <pubDate>Fri, 14 Apr 2023 14:43:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/towfiqu-barbhuiya-FnA5pAzqhMM-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In computing, access control is the concept of limiting or regulating a person or machine's access to certain information or resources.</p>
<p>One of the major mechanisms you use to do that is an access control list (ACL). An ACL is a set of rules for allowing or denying access to certain resources. Resources in this case may be files, networks, or devices.</p>
<p>In this article, we'll talk about what access control lists really are, and how you can use them. We're going to deal with:</p>
<ul>
<li><p>Filesystem ACLs and Network ACLs</p>
</li>
<li><p>Firewalls and stateful packet filtering</p>
</li>
<li><p>ACLs in Cloud Networking (Azure NSG, AWS SG, AWS NACL)</p>
</li>
<li><p>ACLs in DNS (BIND9)</p>
</li>
<li><p>ACLs in core networking (Cisco ACL types, Huawei ACL types)</p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To understand this article, you need a basic understanding of networking, firewalls, and cloud computing. You may particularly need to understand basic of <a target="_blank" href="https://www.linkedin.com/pulse/ip-addressing-chidiadi-anyanwu">IP addressing</a> and <a target="_blank" href="https://www.linkedin.com/pulse/dns-deep-dive-chidiadi-anyanwu/">DNS</a> concepts.</p>
<h2 id="heading-types-of-access-control-lists">Types of Access Control Lists</h2>
<p>When we talk about ACLs, many people just think of networks. But in fact, there are two types of ACLs:</p>
<ul>
<li><p>File system ACLs</p>
</li>
<li><p>Networking ACLs</p>
</li>
</ul>
<p>Filesystem ACLs help operating systems know what the user access privileges are for different files or directories in the system. NFSv4 ACLs and POSIX ACLs are examples of filesystem ACL types.</p>
<p>Networking ACLs are applied on interfaces and you use them to allow or deny traffic from certain sources or to certain destinations. This is what I'll be focusing on in this article.</p>
<h2 id="heading-structure-of-an-acl-rule">Structure Of An ACL Rule</h2>
<p>An ACL is like a group of rules identified by a name or number. An ACL rule usually has a priority number, the criteria (source address, destination address, and so on) and the allow/deny statement.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Cisco-ACL-structure.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Cisco ACL structure</em></p>
<h2 id="heading-firewalls-and-acls">Firewalls and ACLs</h2>
<p>A firewall is a security device or software that monitors the traffic going in and out of a device or network, and filters out unwanted or malicious traffic.</p>
<p>Until stateful packet inspection, ACLs were the major mechanism through which firewalls worked. With ACLs, packets are allowed and denied based on properties specified in the rules.</p>
<p>ACLs are stateless. You must create an inbound rule and a corresponding outbound rule, or else packets from one side might be blocked.</p>
<p>With stateful packet inspection (also known as dynamic packet filtering), you could then create security policies for a type of traffic. The firewall would establish a session whenever a packet is allowed, so that any response to that packet is allowed even though there was no specific policy to allow it.</p>
<p>This makes things easier and more efficient than using ACLs that are uni-directional. But it also means that more computing resources are utilized by the firewall and the network is slowed down.</p>
<p>Now, firewalls are a lot more complex than that with deep packet inspection (DPI), Intrusion Detection System (IDS)/Intrusion Prevention System (IPS) capabilities, and even antivirus capabilities, but those are outside the scope of this article.</p>
<p>Let's explore some networking situations where ACLs are used.</p>
<h2 id="heading-acls-in-cloud-networking">ACLs in Cloud Networking</h2>
<p>The major cloud service providers (CSPs) provide forms of ACLs or firewall capabilities for their customers to use in their cloud infrastructure.</p>
<p>For example, in Microsoft Azure, we have what is called Network Security Groups (NSG) and in AWS, we have Security Groups (SG) and the Network Access Control List (NACL). These are all implementations of ACL-like security.</p>
<h3 id="heading-aws">AWS</h3>
<p>An AWS security group determines what traffic is allowed to and from the resources attached to that security group. It consists of a list of inbound and outbound rules, and is stateful.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot--320--1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Default AWS Security Group</em></p>
<p>An AWS Network Access Control List is another list of rules but at the subnet level. The rules consist of the rule number, type, protocol, port range, source, destination and allow/deny fields. A NACL can be applied more than one subnet, but a subnet cannot be attached to more than one NACL.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot--319--nacl-3-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Inbound rules for AWS NACL</em></p>
<h3 id="heading-azure">Azure</h3>
<p>An Azure Network Security Group is a kind of firewall feature that works both at the subnet level and the network interface card (NIC) of the resources in your VNet. It is basically also a list of ACL rules consisting of priority number, name, port, protocol, source and destination.</p>
<p>Here, you can use IP addresses, service tags, or application security groups (ASGs) in the source and destination fields. NSGs are stateful.</p>
<p>Both the Azure NSG and the AWS NACL rules are very similar to the ACL rules used in core networking. Also, you cannot really refer to AWS Security Groups and Azure NSGs as ACLs because they're not stateless.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Microsoft-NSG-rules-image.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Azure NSG</em></p>
<h2 id="heading-acls-in-dns">ACLs in DNS</h2>
<p><a target="_blank" href="https://www.linkedin.com/pulse/dns-deep-dive-chidiadi-anyanwu/">DNS servers help resolve domain names to IP addresses</a>. If they accept and respond to requests from every device around them, it will impact their performance and make them susceptible to DDoS attacks. So, DNS administrators use ACLs to determine who can send DNS requests to the servers.</p>
<p>For example, in a BIND9 server, such an ACL will be defined in the named.conf file, and would look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/Screenshot--308--1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An ACL in BIND9</em></p>
<h2 id="heading-acls-in-core-networking">ACLs in Core Networking</h2>
<p>This is a bit more complex than the other contexts we discussed above. ACLs on network devices are configured on the interfaces, and are used in many different scenarios. There are also different types of ACLs. By network devices, I mean devices like routers, switches, firewalls, access controllers, and so on.</p>
<p>Generally, these ACLs are identified by their names or ACL numbers, and their rules follow the format:</p>
<p><em>permit/deny criteria</em></p>
<p>For Cisco devices, there are two major types of IPv4 ACLs:</p>
<ul>
<li><p>Standard access lists</p>
</li>
<li><p>Extended access lists</p>
</li>
</ul>
<h3 id="heading-standard-acls">Standard ACLs</h3>
<p>These ACLs permit or deny traffic based on only the source IP address.</p>
<pre><code class="lang-python">R1(config)<span class="hljs-comment">#access-list 10 permit 192.168.17.0 0.0.0.255</span>
</code></pre>
<p>The rule above tells the router to permit packets from the <em>192,168,17,0/24</em> subnet. Note that <em>0.0.0.255</em> is not a subnet mask. It is a wildcard that tells the device to which extent it must match the address you entered. <em>255</em> means any number goes while <em>0</em> means it must match exactly.</p>
<p>So here, the network part <em>192.168.17</em> must be exactly the same in whatever packet, while the last octet (the host part) can be whatever. You can learn more about IP addressing <a target="_blank" href="https://www.linkedin.com/pulse/ip-addressing-chidiadi-anyanwu">here</a>.</p>
<h3 id="heading-extended-acls">Extended ACLs</h3>
<p>These ACLs permit or deny traffic based on what is known in networking as the 5-tuple (source address, destination address, source port, destination port, transport layer protocol).</p>
<pre><code class="lang-python">R2(config)<span class="hljs-comment">#access-list 100 permit tcp 10.1.1.0 0.0.0.255 host 10.2.2.2 eq 80</span>
</code></pre>
<p>The command above tells the router to permit any packet using the TCP transport layer protocol, coming from the 10.1.1.0/24 network to port 80 (<a target="_blank" href="https://www.linkedin.com/pulse/http-network-protocol-chidiadi-anyanwu/">HTTP</a>) of the host, 10.2.2.2.</p>
<p>The term 5-tuple in networking probably originated from mathematics. A tuple means a record/row. 5-tuple means a row with five columns – an ordered list of 5 elements.</p>
<p>The five elements we're mostly concerned with in networking when dealing with packets are the IP addresses (source and destination), port numbers (source and destination), and transport layer protocol. So, they're usually referred to as 5-tuple.</p>
<p>ACL numbers 1 - 99 and 1300 - 1999 denote standard ACLs while numbers 100 - 199 and 2000 - 2699 denote extended ACLs.</p>
<p>Many other vendors follow this pattern, but Huawei doesn't.</p>
<p>For Huawei devices, there are 5 types of IPv4 ACLs:</p>
<ul>
<li><p>Basic ACLs ( ACL numbers 2000 - 2999)</p>
</li>
<li><p>Advanced ACLs (ACL numbers 3000 - 3999)</p>
</li>
<li><p>Layer 2 ACLs (ACL numbers 4000 - 4999)</p>
</li>
<li><p>User-defined ACLs (ACL numbers 5000 - 5999)</p>
</li>
<li><p>User ACLs (ACL numbers 6000 - 6999)</p>
</li>
</ul>
<p><strong>Basic ACL:</strong> Permits or denies traffic based on source address. The ACL number ranges from 2000 - 2999.</p>
<p><strong>Advanced ACL:</strong> Permits or denies traffic based on the 5-tuple (source IP address, destination IP address, source port, destination port, and protocol type).</p>
<p><strong>Layer 2 ACL:</strong> Permits or denies traffic based on information in the frame header (source MAC address, destination MAC address, layer 2 protocol type).</p>
<p><strong>User-defined ACL:</strong> Permits or denies traffic based on packet headers, offsets, character string masks, and user defined character strings.</p>
<p><strong>User ACL:</strong> Permits or denies traffic based on source and destination IP addresses or user control list (UCL) groups, source and destination ports, and IPv4 protocol types.</p>
<pre><code class="lang-python">acl <span class="hljs-number">3500</span>                                                
 rule <span class="hljs-number">0</span> deny tcp source <span class="hljs-number">10.1</span><span class="hljs-number">.1</span><span class="hljs-number">.0</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.255</span> destination <span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.9</span> <span class="hljs-number">0</span> destination-port eq <span class="hljs-number">80</span>                                                                
 rule <span class="hljs-number">5</span> allow tcp source <span class="hljs-number">10.1</span><span class="hljs-number">.1</span><span class="hljs-number">.0</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.255</span> destination <span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.9</span> <span class="hljs-number">0</span> destination-port eq telnet
</code></pre>
<h3 id="heading-implicit-deny">Implicit deny</h3>
<p>It is also important to note that even if you do not add any rule at the end of your ACL, the last rule there is always a deny rule. It is not shown, so it is implicit. But it is there. It denies any packet that does not match any rule in your ACL.</p>
<h3 id="heading-a-few-things-to-know">A Few Things To Know</h3>
<p>ACL rules are executed sequentially, so if you have rule 3 and rule 5, rule 3 gets executed first.</p>
<p>It is always a good practice to create rules at intervals (rule 10, rule 20, rule 30) rather than just serially (rule 1, rule 2, rule 3). The reason is that you may want to add a rule in-between two existing rules, and you want the system to execute it in that particular order. It saves stress if there was space for that from the beginning.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Access control is critical to security. Digitally, ACLs have been the go-to mechanism for quick and easy access control. Though other methods like role-based access control (RBAC) and attribute-based access control (ABAC) have emerged, ACL still has its place in access control.</p>
<p>Thanks for reading. If you enjoyed this article, please share it so others can see it too.</p>
<p>You can also <a target="_blank" href="https://linkedin.com/in/chidiadi-anyanwu">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ HTTP Networking in JavaScript – Handbook for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ HTTP is the backbone of the modern internet. In this text-based course, you'll learn how the HTTP protocol works and how it's used in real-world web development. All the code samples for this course are in JavaScript, but the networking concepts you'... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/http-full-course/</link>
                <guid isPermaLink="false">66b9e9ec39e4436f19005afa</guid>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ http ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lane Wagner ]]>
                </dc:creator>
                <pubDate>Tue, 14 Feb 2023 00:42:39 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738338854008/9272a213-f1ed-40d0-8d33-f57a11b3756c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>HTTP is the backbone of the modern internet. In this text-based course, you'll learn how the HTTP protocol works and how it's used in real-world web development.</p>
<p>All the code samples for this course are in JavaScript, but the networking concepts you'll learn here apply generally to all coding languages. <em>If you're not familiar with JavaScript yet, you can check out</em> <a target="_blank" href="https://boot.dev/learn/learn-javascript"><em>my JS course here</em></a><em>.</em></p>
<p>I've included all the learning material you'll need here in this article, but if you would like a more hands-on experience, you can take the <a target="_blank" href="https://boot.dev/learn/learn-http">interactive version of this course with coding challenges on Boot.dev here.</a></p>
<p>I've also published a free video version of this course on the freeCodeCamp YouTube channel:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/2JYT5f2isg4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>If you like this video, you can check out my other tutorials on my <a target="_blank" href="https://youtube.com/@bootdotdev">Boot.dev YouTube channel here</a>.</p>
<p>All that said, let's jump into learning about HTTP!</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-why-http">Why HTTP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#What-is-dns">What is DNS?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-uris">What Are URIs?</a></p>
</li>
<li><p><a class="post-section-overview" href="#chapter-4-async-await">Async/Await</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-error-handling">Error Handling</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-http-headers">HTTP Headers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-json">What is JSON?</a></p>
</li>
<li><p><a class="post-section-overview" href="#chapter-8-http-methods">HTTP Methods</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-url-paths-and-parameters">URL Paths and Parameters</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-https">What is HTTPs?</a></p>
</li>
</ol>
<h2 id="heading-why-http">Why HTTP?</h2>
<h3 id="heading-communicating-on-the-web">Communicating on the web</h3>
<p>Instagram would be pretty terrible if you had to manually copy your photos to your friend's phone when you wanted to share them. Modern applications need to be able to communicate information <em>between devices</em> over the internet.</p>
<ul>
<li><p>Gmail doesn't just store your emails in variables on your computer, it stores them on computers in their data centers.</p>
</li>
<li><p>You don't lose your Slack messages if you drop your computer in a lake – those messages exist on Slack's <a target="_blank" href="https://en.wikipedia.org/wiki/Web_server">servers</a>.</p>
</li>
</ul>
<h3 id="heading-how-does-web-communication-work">How does web communication work?</h3>
<p>When two computers communicate with each other, they need to use the same rules. An English speaker can't communicate verbally with a Japanese speaker, and similarly, two computers need to speak the same language to communicate.</p>
<p>This "language" that computers use is called a <a target="_blank" href="https://en.wikipedia.org/wiki/Communication_protocol">protocol</a>. The most popular protocol for web communication is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview">HTTP</a>, which stands for Hypertext Transfer Protocol.</p>
<h3 id="heading-interacting-with-a-server">Interacting with a server</h3>
<p>In this course, a lot of the code samples will interact with the <a target="_blank" href="https://pokeapi.co/">PokeAPI</a>. It serves data about Pokémon.</p>
<p>Here's some code that retrieves a list of Pokémon from the PokeAPI:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> pokemonResp = <span class="hljs-keyword">await</span> getItemData()

logPokemons(pokemonResp.results)

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getItemData</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://pokeapi.co/api/v2/pokemon/'</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
    <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    }
  })
  <span class="hljs-keyword">return</span> response.json()
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logPokemons</span>(<span class="hljs-params">pokemons</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> pokemon <span class="hljs-keyword">of</span> pokemons) {
    <span class="hljs-built_in">console</span>.log(pokemon.name)
  } 
}
</code></pre>
<p>When you run this code, you'll notice that none of the data that is logged to the console was generated within our code! That's because the data we retrieved is being sent over the internet from our servers via HTTP. Don't worry, we'll explain more about that later.</p>
<h3 id="heading-http-requests-and-responses">HTTP Requests and Responses</h3>
<p>At the heart of HTTP is a simple request-response system. The "requesting" computer, also known as the "<a target="_blank" href="https://en.wikipedia.org/wiki/Client_\(computing\)">client</a>", asks another computer for some information. That computer, the "<a target="_blank" href="https://en.wikipedia.org/wiki/Server_\(computing\)">server</a>" sends back a response with the information that was requested.</p>
<p><img src="https://i.imgur.com/ReFw6nN.png" alt="Image" width="925" height="297" loading="lazy"></p>
<p>We'll talk about the specifics of how the "requests" and "responses" are formatted later. For now, just think of it as a simple question-and-answer system.</p>
<ul>
<li><p>Request: "What are the items in the Fantasy Quest game?"</p>
</li>
<li><p>Response: A list of the items in the Fantasy Quest game</p>
</li>
</ul>
<h3 id="heading-http-powers-websites">HTTP powers websites</h3>
<p>As we discussed, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview">HTTP</a>, or Hypertext Transfer Protocol, is a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Protocol">protocol</a> designed to transfer information between computers.</p>
<p>There are other protocols for communicating over the internet, but HTTP is the most popular and is <em>particularly great for websites and web applications</em>.</p>
<p>Each time you visit a website, your browser is making an HTTP request to that website's server. The server responds with all the text, images, and styling information that your browser needs to render its pretty website.</p>
<p><img src="https://i.imgur.com/EflKJzq.jpg" alt="Image" width="1080" height="1080" loading="lazy"></p>
<h3 id="heading-http-urls">HTTP URLs</h3>
<p>A URL, or <a target="_blank" href="https://www.freecodecamp.org/news/url-definition/">Uniform Resource Locator</a>, is essentially the address of another computer, or "server" on the internet. Part of the URL specifies how to reach the server, and part of it tells the server what information we want - but more on that later.</p>
<p>For now, it's important to understand that a URL represents a piece of information on another computer that we want access to. We can get access to it by making a <em>request</em>, and reading the <em>response</em> that the server replies with.</p>
<h3 id="heading-how-to-use-urls-in-http">How to Use URLs in HTTP</h3>
<p>The <code>http://</code> at the beginning of a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL">website URL</a> specifies that the <code>http</code> protocol will be used for communication.</p>
<p><img src="https://i.imgur.com/6jiaXBn.png" alt="Image" width="368" height="137" loading="lazy"></p>
<p>Other communication protocols use URLs as well, (hence "Uniform Resource Locator"). That's why we need to be specific when we're making HTTP requests by prefixing the URL with <code>http://</code></p>
<h3 id="heading-requests-and-responses-review">Requests and Responses Review</h3>
<ul>
<li><p>A "client" is a computer making an HTTP request</p>
</li>
<li><p>A "server" is a computer responding to an HTTP request</p>
</li>
<li><p>A computer can be a client, a server, both, or neither. "Client" and "server" are just words we use to describe what computers are doing within a communication system.</p>
</li>
<li><p>Clients send requests and receive responses</p>
</li>
<li><p>Servers receive requests and send responses</p>
</li>
</ul>
<h2 id="heading-javascripts-fetch-api">JavaScript's Fetch API</h2>
<p>In this course, we'll be using JavaScript's built-in <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch API</a> to make HTTP requests.</p>
<p>The <code>fetch()</code> function is made available to us by the JavaScript language running in the browser. All we have to do is provide it with the parameters it requires.</p>
<h3 id="heading-how-to-use-fetch"><strong>How to Use Fetch</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url, settings)
<span class="hljs-keyword">const</span> responseData = <span class="hljs-keyword">await</span> response.json()
</code></pre>
<p>We'll go in-depth on the various things happening in this standard <code>fetch</code> call later, but let's cover some basics for now.</p>
<ul>
<li><p><code>response</code> is the data that comes back from the server</p>
</li>
<li><p><code>url</code> is the URL we are making a request to</p>
</li>
<li><p><code>settings</code> is an object containing some request-specific settings</p>
</li>
<li><p>The <code>await</code> keyword tells JavaScript to wait until the request comes back from the server before continuing</p>
</li>
<li><p><code>response.json()</code> converts the response data from the server into a JavaScript object</p>
</li>
</ul>
<p>See if you can spot the issue with this code snippet:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> pokemonResp = getItemData()

logPokemons(pokemonResp.results)

<span class="hljs-comment">// the bug is above this line</span>

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getItemData</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://pokeapi.co/api/v2/pokemon/'</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
    <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    }
  })
  <span class="hljs-keyword">return</span> response.json()
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logPokemons</span>(<span class="hljs-params">pokemons</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> pokemon <span class="hljs-keyword">of</span> pokemons) {
    <span class="hljs-built_in">console</span>.log(pokemon.name)
  } 
}
</code></pre>
<p>Hint: We're not waiting for the data to be sent back across the network.</p>
<h3 id="heading-web-clients">Web Clients</h3>
<p>A web client is a device making requests to a web server. A client can be any type of device but is often something users physically interact with. For example:</p>
<ul>
<li><p>A desktop computer</p>
</li>
<li><p>A mobile phone</p>
</li>
<li><p>A tablet</p>
</li>
</ul>
<p>In a website or web application, we call the user's device the "front-end".<br>A front-end client makes requests to a back-end server.</p>
<p><img src="https://i.imgur.com/zldXGet.jpg" alt="Image" width="1920" height="1080" loading="lazy"></p>
<h3 id="heading-web-servers">Web Servers</h3>
<p>Up to this point, most of the data you have worked with in your code has simply been generated and stored locally in variables.</p>
<p>While you'll always use variables to store and manipulate data while your program is running, most websites and apps use a web server to store, sort, and serve that data so that it sticks around for longer than a single session, and can be accessed by multiple devices.</p>
<h3 id="heading-listening-and-serving-data"><strong>Listening and serving data</strong></h3>
<p>Similar to how a server at a restaurant brings your food to the table, a <a target="_blank" href="https://en.wikipedia.org/wiki/Web_server">web server</a>) serves web resources, such as web pages, images, and other data. The server is turned on and "listening" for inbound requests constantly so that the second it receives a new request, it can send an appropriate response.</p>
<h3 id="heading-the-server-is-the-back-end">The server is the back-end</h3>
<p>While the "front-end" of a website or web application is the device the user interacts with, the "back-end" is the server that keeps all the data housed in a central location. If you're still confused, <a target="_blank" href="https://blog.boot.dev/backend/frontend-vs-backend-meaning/">check out this article comparing front-end and back-end development</a>.</p>
<h3 id="heading-a-server-is-just-a-computer">A server is just a computer</h3>
<p>"Server" is just the name we give to a computer that is taking on the role of serving data across a network connection.</p>
<p>A good server is turned on and available 24 hours a day, 7 days a week. While your laptop <em>can</em> be used as a server, it makes more sense to use a computer in a data center that's designed to be up and running constantly.</p>
<h2 id="heading-what-is-dns">What is DNS?</h2>
<h3 id="heading-web-addresses">Web Addresses</h3>
<p>In the real world, we use addresses to help us find where a friend lives, where a business is located, or where a party is being thrown.</p>
<p>In computing, web clients find other computers over the internet using <a target="_blank" href="https://en.wikipedia.org/wiki/Internet_Protocol">Internet Protocol or IP</a> addresses.</p>
<p>An IP address is a numerical label that serves two main functions:</p>
<ol>
<li><p>Location Addressing</p>
</li>
<li><p>Network Identification</p>
</li>
</ol>
<h3 id="heading-domain-names-and-ip-addresses">Domain names and IP Addresses</h3>
<p>Each device connected to the internet has a unique IP address. When we browse the internet, the domains we navigate to are all associated with a particular IP address.</p>
<p>For example, this Wikipedia URL points to a page about miniature pigs: <code>https://en.wikipedia.org/wiki/Miniature_pig</code><br>The <a target="_blank" href="https://en.wikipedia.org/wiki/Domain_Name_System">domain</a> portion of the URL is <code>en.wikipedia.org</code>. <code>en.wikipedia.org</code> converts to a specific IP address, and that IP address tells your computer exactly where to communicate with that Wikipedia page.</p>
<p>Cloudflare is a tech company that provides a cool public HTTP server that we can use to look up the IP address of any domain. Take a look at this sample code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchIPAddress</span>(<span class="hljs-params">domain</span>) </span>{
  <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://cloudflare-dns.com/dns-query?name=<span class="hljs-subst">${domain}</span>&amp;type=A`</span>, {
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'accept'</span>: <span class="hljs-string">'application/dns-json'</span>
    }
  })
  <span class="hljs-keyword">const</span> respObject = <span class="hljs-keyword">await</span> resp.json()
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> record <span class="hljs-keyword">of</span> respObject.Answer) {
    <span class="hljs-keyword">return</span> record.data
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
}

<span class="hljs-keyword">const</span> domain = <span class="hljs-string">'api.boot.dev'</span>
<span class="hljs-keyword">const</span> ipAddress = <span class="hljs-keyword">await</span> fetchIPAddress(domain)
<span class="hljs-keyword">if</span> (!ipAddress) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'something went wrong in fetchIPAddress'</span>)
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`found IP address for domain <span class="hljs-subst">${domain}</span>: <span class="hljs-subst">${ipAddress}</span>`</span>)
}
</code></pre>
<p>To recap, a "domain name" is part of a URL. It's the part that tells the computer <em>where the server is located on the internet</em> by being converted into a numerical IP address.</p>
<p>We'll cover exactly how an IP address is used by your computer to find a path to the server in a later networking course. For now, it's just important to understand that an IP address is what your computer is using at a lower level to communicate on a network.</p>
<p>Deploying a real website to the internet is actually quite simple. It involves only a couple of steps:</p>
<ol>
<li><p>Create a server that hosts your website files and connect it to the internet</p>
</li>
<li><p>Acquire a domain name</p>
</li>
<li><p>Connect the domain name to the IP address of your server</p>
</li>
<li><p>Your server is accessible via the internet!</p>
</li>
</ol>
<p><img src="https://i.imgur.com/vjjPt2a.png" alt="Image" width="310" height="163" loading="lazy"></p>
<p>As we discussed, the "domain name" or "hostname" is part of a URL. We'll get to the other parts of a URL later.</p>
<p>For example, the URL <code>https://example.com/path</code> has a hostname of <code>example.com</code>. The <code>https://</code> and <code>/path</code> portions are not part of the <code>domain name -&gt; IP address</code> mapping that we've been learning about.</p>
<h3 id="heading-using-the-url-api-in-javascript">Using the URL API in JavaScript</h3>
<p>The <code>URL</code> API is built into JavaScript. You can create a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL">new URL object</a> like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> urlObj = <span class="hljs-keyword">new</span> URL(<span class="hljs-string">'https://example.com/example-path'</span>)
</code></pre>
<p>And then you can <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/URL">extract just the hostname</a>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> urlObj.hostname
</code></pre>
<h3 id="heading-dns-review">DNS Review</h3>
<p>So we've talked about domain names and what their purpose is, but we haven't talked about the system that's used to do that conversion.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/what-is-dns/">DNS</a>, or the "Domain Name System", is the phonebook of the internet. Humans connect to websites through <a target="_blank" href="https://en.wikipedia.org/wiki/Domain_name">domain names</a>, like <a target="_blank" href="https://boot.dev">Boot.dev</a>.</p>
<p>DNS "resolves" these domain names to find the associated <a target="_blank" href="https://en.wikipedia.org/wiki/Internet_Protocol">IP addresses</a> so that web clients can load the resources for the specific address.</p>
<p><img src="https://i.imgur.com/yvfSbVL.png" alt="Image" width="1024" height="512" loading="lazy"></p>
<h3 id="heading-how-does-dns-work">How does DNS Work?</h3>
<p>We'll go into more detail on DNS in a future course, but to give you a simplified idea of how it works, let's introduce ICANN. <a target="_blank" href="https://www.icann.org/">ICANN</a> is a not-for-profit organization that manages DNS for the entire internet.</p>
<p>Whenever your computer attempts to resolve a domain name, it contacts one of ICANN's "<a target="_blank" href="https://en.wikipedia.org/wiki/Root_name_server">root nameservers</a>" whose address is included in your computer's networking configuration.</p>
<p>From there, that nameserver can gather the domain records for a specific domain name from their distributed DNS database.</p>
<p>If you think of DNS as a phonebook, ICANN is the publisher that keeps the phonebook in print and available.</p>
<h3 id="heading-subdomains">Subdomains</h3>
<p>We learned about how a domain name resolves to an IP address, which is just a computer on a network - often the internet.</p>
<p>A subdomain prefixes a domain name, allowing a domain to route network traffic to many different servers and resources.</p>
<p>For example, the <a target="_blank" href="https://boot.dev">Boot.dev</a> website is hosted on a different computer than our blog. Our blog, found at <a target="_blank" href="https://blog.boot.dev">blog.boot.dev</a> is hosted on our "blog" subdomain.</p>
<h2 id="heading-what-are-uris">What are URIs?</h2>
<p>We briefly touched on URLs earlier, but now let's dive a little deeper into the subject.</p>
<p>A <a target="_blank" href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier">URI</a>, or Uniform Resource <em>Identifier</em>, is a unique character sequence that identifies a resource that is (almost always) accessed via the internet.</p>
<p>Just like JavaScript has syntax rules, so do URIs. These rules help ensure uniformity so that any program can interpret the meaning of the URI in the same way.</p>
<p>URIs come in two main types:</p>
<ul>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/URL">URLs</a></p>
</li>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Uniform_Resource_Name">URNs</a></p>
</li>
</ul>
<p>We will focus specifically on URLs in this course, but it's important to know that URLs are only one kind of URI.</p>
<p><img src="https://i.imgur.com/VzqzckC.png" alt="Image" width="500" height="394" loading="lazy"></p>
<p>URLs have quite a few sections, some of which are required, others not.<br>Let's use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL">URL API</a> to parse a URL and print all the different parts. We'll learn more about each part later, for now, let's just split and print a URL.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printURLParts</span>(<span class="hljs-params">urlString</span>) </span>{
  <span class="hljs-keyword">const</span> urlObj = <span class="hljs-keyword">new</span> URL(urlString)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`protocol: <span class="hljs-subst">${urlObj.protocol}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`username: <span class="hljs-subst">${urlObj.username}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`password: <span class="hljs-subst">${urlObj.password}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`hostname: <span class="hljs-subst">${urlObj.hostname}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`port: <span class="hljs-subst">${urlObj.port}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`pathname: <span class="hljs-subst">${urlObj.pathname}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`search: <span class="hljs-subst">${urlObj.search}</span>`</span>)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`hash: <span class="hljs-subst">${urlObj.hash}</span>`</span>)
}

<span class="hljs-keyword">const</span> fantasyQuestURL = <span class="hljs-string">'http://dragonslayer:pwn3d@fantasyquest.com:8080/maps?sort=rank#id'</span>
printURLParts(fantasyQuestURL)
</code></pre>
<h3 id="heading-further-dissecting-a-url">Further dissecting a URL</h3>
<p>There are 8 main parts to a URL, though not all the sections are always present. Each piece plays a specific role in helping clients locate the specified resource.<br>The 8 sections are:</p>
<p><img src="https://i.imgur.com/iI3sUVh.png" alt="Image" width="1280" height="720" loading="lazy"></p>
<ul>
<li><p>The protocol is required</p>
</li>
<li><p>Usernames and passwords are optional</p>
</li>
<li><p>A domain is required</p>
</li>
<li><p>The default port for a given protocol is used if one is not provided</p>
</li>
<li><p>The default ( <code>/</code> ) path is used if one isn't provided</p>
</li>
<li><p>A query is optional</p>
</li>
<li><p>A fragment is optional</p>
</li>
</ul>
<h3 id="heading-dont-get-too-hung-up-on-memorizing-this-stuff">Don't get too hung up on memorizing this stuff</h3>
<p>Because names for the different sections are often used interchangeably, and because not all the parts of the URL are always present, it can be hard to keep things straight.</p>
<p>Don't worry about memorizing this stuff! Try to just get familiar with these URL concepts from a high level. Like any good developer, you can just look it up again the next time you need to know more.</p>
<h3 id="heading-the-protocol">The Protocol</h3>
<p>The "protocol", also referred to as the "scheme", is the first component of a URL. Its purpose is to define the rules by which the data being communicated is displayed, encoded, or formatted.</p>
<p>Some examples of different URL protocols:</p>
<ul>
<li><p>http</p>
</li>
<li><p>ftp</p>
</li>
<li><p>mailto</p>
</li>
<li><p>https</p>
</li>
</ul>
<p>For example:</p>
<ul>
<li><p><code>http://example.com</code></p>
</li>
<li><p><code>mailto:noreply@fantasyquest.app</code></p>
</li>
</ul>
<h3 id="heading-not-all-schemes-require-a">Not all schemes require a "//"</h3>
<p>The "http" in a URL is always followed by <code>://</code>. All URLs have the colon, but the <code>//</code> part is only included for schemes that have an <a target="_blank" href="https://www.rfc-editor.org/rfc/rfc3986#section-3.2">authority component</a>.</p>
<p>As you can see above, the <code>mailto</code> scheme doesn't use an authority component, so it doesn't need the slashes.</p>
<h3 id="heading-url-ports">URL Ports</h3>
<p>The port in a URL is a virtual point where network connections are made. Ports are managed by a computer's operating system and are numbered from <code>0</code> to <code>65,535</code>.</p>
<p>Whenever you connect to another computer over a network, you're connecting to a specific port on that computer, which is being listened to by a specific piece of software on that computer. A port can only be used by one program at a time, which is why there are so many possible ports.</p>
<p>The port component of a URL is often not visible when browsing normal sites on the internet, because 99% of the time you're using the default ports for the HTTP and HTTPS schemes: <code>80</code> and <code>443</code>, respectively.</p>
<p>Whenever you aren't using a default port, you need to specify it in the URL. For example, port <code>8080</code> is often used by web developers when they're running their server in "test mode" so that they don't use the "production" port "80".</p>
<p><img src="https://i.imgur.com/h3kBsRC.png" alt="Image" width="625" height="129" loading="lazy"></p>
<h3 id="heading-url-paths">URL Paths</h3>
<p>In the early days of the internet, a URL's path often was a reflection of the file path on the server to the resource the client was requesting.</p>
<p>For example, if the website <code>https://exampleblog.com</code> had a web server running within its <code>/home</code> directory, then a request to the <code>https://exampleblog.com/site/index.html</code> URL might expect the <code>index.html</code> file from within the <code>/home/site</code> directory to be returned.</p>
<p>Websites used to be very simple. They were just a collection of text documents stored on a server. A simple piece of server software could handle incoming HTTP requests and respond with the documents according to the path component of the URLs.</p>
<h3 id="heading-these-days-its-not-always-about-the-filesystem">These days, it's not always about the filesystem</h3>
<p>On many modern web servers, a URL's path isn't a reflection of the server's filesystem hierarchy. Paths in URLs are essentially just another type of parameter that can be passed to the server when making a request.</p>
<p>Conventionally, two different URL paths should denote different resources. For example, different pages on a website, or maybe different data types from a game server.</p>
<h3 id="heading-query-parameters">Query parameters</h3>
<p>Query parameters in a URL are <em>not</em> always present. In the context of websites, query parameters are often used for marketing analytics or for changing a variable on the web page. With website URLs, query parameters <em>rarely</em> change <em>which</em> page you're viewing, though they often will change the page's <em>contents</em>.</p>
<p>That said, query parameters can be used for anything the server chooses to use them for, just like the URL's path.</p>
<h3 id="heading-how-google-uses-query-parameters">How Google uses query parameters</h3>
<ol>
<li><p>Open a new tab and go to <a target="_blank" href="https://google.com">google.com</a></p>
</li>
<li><p>Search for "hello world"</p>
</li>
<li><p>Take a look at your current URL. It should start with <code>https://www.google.com/search?q=hello+world</code></p>
</li>
<li><p>Change the URL to say <code>https://www.google.com/search?q=hello+universe</code></p>
</li>
<li><p>Press "enter"</p>
</li>
</ol>
<p>You should see new search results for the query "hello universe". Google chose to use query parameters to represent the value of your search query. It makes sense - each search result page is <em>essentially</em> the same page as far as structure and formatting are concerned - it's just showing you different results based on the search query.</p>
<h2 id="heading-asyncawait">Async/Await</h2>
<p>You're probably already familiar with <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Synchronous">synchronous</a> code, which means code that <em>runs in sequence</em>. Each line of code executes in order, one after the next.</p>
<p><img src="https://i.imgur.com/03FFGu0.png" alt="Image" width="587" height="335" loading="lazy"></p>
<p>Example of synchronous code:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I print first"</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I print second"</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I print third"</span>);
</code></pre>
<p>Asynchronous or <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Asynchronous">async</a> code runs in <em>parallel</em>. That means code further down runs <em>at the same time that</em> a previous line of code is still running. A good way to visualize this is with the JavaScript function <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/setTimeout">setTimeout()</a>.</p>
<p><code>setTimeout</code> accepts a function and a number of milliseconds as inputs. It waits until the number of milliseconds has elapsed, and then it executes the function it was given.</p>
<p>Example of asynchronous code:</p>
<pre><code class="lang-js">jsconsole.log(<span class="hljs-string">"I print first"</span>);
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I print third because I'm waiting 100 milliseconds"</span>), <span class="hljs-number">100</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I print second"</span>);
</code></pre>
<p>Try altering the waiting times in the async code below to get the messages to print in the proper order:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> craftingCompleteWait = <span class="hljs-number">0</span>
<span class="hljs-keyword">const</span> combiningMaterialsWait = <span class="hljs-number">0</span>
<span class="hljs-keyword">const</span> smeltingIronBarsWait = <span class="hljs-number">0</span>
<span class="hljs-keyword">const</span> shapingIronWait = <span class="hljs-number">0</span>

<span class="hljs-comment">// Don't touch below this line</span>

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Iron Longsword Complete!'</span>), craftingCompleteWait)
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Combining Materials...'</span>), combiningMaterialsWait)
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Smelting Iron Bars...'</span>), smeltingIronBarsWait)
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Shaping Iron...'</span>), shapingIronWait)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Firing up the forge...'</span>)

<span class="hljs-keyword">await</span> sleep(<span class="hljs-number">2500</span>)
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sleep</span>(<span class="hljs-params">ms</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, ms))
}
</code></pre>
<p>Expected order:</p>
<ol>
<li><p>Firing up the forge..</p>
</li>
<li><p>Smelting Iron Bars...</p>
</li>
<li><p>Combining Materials...</p>
</li>
<li><p>Shaping Iron...</p>
</li>
<li><p>Iron Longsword Complete!</p>
</li>
</ol>
<h3 id="heading-why-do-we-want-async-code">Why do we want async code?</h3>
<p>We try to keep most of our code synchronous because it's easier to understand, and therefore often has fewer bugs. But sometimes we <em>need</em> our code to be asynchronous.</p>
<p>For example, whenever you update your user settings on a website, your browser will need to communicate those new settings to the server. The time it takes your HTTP request to physically travel across all the wiring of the internet is usually around 100 milliseconds. It would be a very poor experience if your webpage were to freeze while waiting for the network request to finish. You wouldn't even be able to move the mouse while waiting!</p>
<p>By making network requests <em>asynchronously</em>, we let the webpage execute other code while waiting for the HTTP response to come back. This keeps the user experience snappy and user-friendly.</p>
<p>As a general rule, we should only use async code when we need to for performance reasons. Synchronous code is simpler.</p>
<p><img src="https://i.imgur.com/03FFGu0.png" alt="Image" width="587" height="335" loading="lazy"></p>
<h3 id="heading-promises-in-javascript">Promises in JavaScript</h3>
<p>A Promise in JavaScript is very similar to making a promise in the real world. When we make a promise, we are making a commitment to something.</p>
<p>For example, <em>I promise to explain JavaScript promises to you</em>. My promise to you has 2 potential outcomes: it is either fulfilled, meaning I eventually explained promises to you, or it is rejected, meaning I failed to keep my promise and didn't explain promises.</p>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise Object</a> represents the eventual fulfillment or rejection of our promise and holds the resulting values. In the meantime, while we're waiting for the promise to be fulfilled, our code continues executing.</p>
<p>Promises are the most popular modern way to write asynchronous code in JavaScript.</p>
<h3 id="heading-how-to-declare-a-promise">How to Declare a Promise</h3>
<p>Here is an example of a promise that will resolve and return the string "resolved!" or reject and return the string "rejected!" after 1 second.</p>
<pre><code class="lang-plaintext">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    if (getRandomBool()) {
      resolve("resolved!")
    } else {
      reject("rejected!")
    }
  }, 1000)
})

function getRandomBool(){
  return Math.random() &lt; .5
}
</code></pre>
<h3 id="heading-how-to-use-a-promise">How to Use a Promise</h3>
<p>Now that we've created a promise, how do we use it?</p>
<p>The <code>Promise</code> object has <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">.then</a> and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">.catch</a> that make it easy to work with. Think of <code>.then</code> as the <em>expected</em> follow-up to a promise, and <code>.catch</code> as the "something went wrong" follow-up.</p>
<p>If a promise <em>resolves</em>, its <code>.then</code> function will execute. If the promise rejects, its <code>.catch</code> method will execute.</p>
<p>Here's an example of using <code>.then</code> and <code>.catch</code> with the promise we made above:</p>
<pre><code class="lang-js">promise.then(<span class="hljs-function">(<span class="hljs-params">message</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The promise finally <span class="hljs-subst">${message}</span>`</span>)
}).catch(<span class="hljs-function">(<span class="hljs-params">message</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The promise finally <span class="hljs-subst">${message}</span>`</span>)
})

<span class="hljs-comment">// prints:</span>
<span class="hljs-comment">// The promise finally resolved!</span>
<span class="hljs-comment">// or</span>
<span class="hljs-comment">// the promise finally rejected!</span>
</code></pre>
<h3 id="heading-why-are-promises-useful">Why are Promises useful?</h3>
<p>Promises are the cleanest (but not the only) way to handle the common scenario where we need to make requests to a server, which is typically done via an HTTP request. In fact, the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch()</a> function we were using earlier in the course returns a promise!</p>
<h3 id="heading-io-or-inputoutput">I/O, or "input/output"</h3>
<p>Almost every time you use a promise in JavaScript it will be to handle some form of I/O. I/O, or input/output, refers to when our code needs to interact with systems outside of the (relatively) simple world of local variables and functions.<br>Common examples of I/O include:</p>
<ul>
<li><p>HTTP requests</p>
</li>
<li><p>Reading files from the hard drive</p>
</li>
<li><p>Interacting with a Bluetooth device</p>
</li>
</ul>
<p>Promises help us perform I/O without forcing our entire program to freeze up while we wait for a response.</p>
<h3 id="heading-promises-and-the-await-keyword">Promises and the "await" keyword</h3>
<p>We have used the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a> keyword a few times in this course, so it's time we finally understand what's going on under the hood.</p>
<p>The <code>await</code> keyword is used to <em>wait</em> for a promise to resolve. Once it has been resolved, the <code>await</code> expression returns the value of the resolved <code>Promise</code>.</p>
<h3 id="heading-example-with-then-callback">Example with .then callback</h3>
<pre><code class="lang-js">promise.then(<span class="hljs-function">(<span class="hljs-params">message</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Resolved with <span class="hljs-subst">${message}</span>`</span>)
}).
</code></pre>
<h3 id="heading-example-of-awaiting-a-promise">Example of awaiting a promise</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> message = <span class="hljs-keyword">await</span> promise
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Resolved with <span class="hljs-subst">${message}</span>`</span>)
</code></pre>
<h3 id="heading-the-async-keyword">The async keyword</h3>
<p>While the <code>await</code> keyword can be used in place of <code>.then()</code> to <em>resolve</em> a promise, the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async</a> keyword can be used in place of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise">new promise()</a> to <em>create</em> a new promise.</p>
<p>When a function is prefixed with the <code>async</code> keyword, it will <em>automatically</em> return a promise. That promise resolves with the value that your code returns from the function. You can think of <code>async</code> as "wrapping" your function within a promise.</p>
<p>These are equivalent:</p>
<h3 id="heading-new-promise">New Promise()</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPromiseForUserData</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    fetchDataFromServerAsync().then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">user</span>)</span>{
      resolve(user)
    })
  })
}

<span class="hljs-keyword">const</span> promise = getPromiseForUserData()
</code></pre>
<h3 id="heading-async">Async</h3>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPromiseForUserData</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchDataFromServer()
  <span class="hljs-keyword">return</span> user
}

<span class="hljs-keyword">const</span> promise = getPromiseForUserData()
</code></pre>
<h3 id="heading-then-vs-await">.then() vs await</h3>
<p>In the early days of web browsers, promises and the <code>await</code> keyword didn't exist, so the only way to do something asynchronously was to use callbacks.</p>
<p>A "callback function" is a function that you hand to another function. That function then calls your callback later on. The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/setTimeout">setTimeout</a> function we've used in the past is a good example.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callbackFunction</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"calling back now!"</span>)
}
<span class="hljs-keyword">const</span> milliseconds = <span class="hljs-number">1000</span>
<span class="hljs-built_in">setTimeout</span>(callbackFunction, milliseconds)
</code></pre>
<p>While even the <code>.then()</code> syntax is generally easier to use than callbacks without the <code>Promise</code> API, the <code>await</code> syntax makes them even easier to use. You should use <code>async</code> and <code>await</code> over <code>.then</code> and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise">new Promise()</a> as a general rule.</p>
<p>To demonstrate, which of these is easier to understand?</p>
<pre><code class="lang-js">fetchUser.then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">user</span>)</span>{
  <span class="hljs-keyword">return</span> fetchLocationForUser(user)
}).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location</span>)</span>{
  <span class="hljs-keyword">return</span> fetchServerForLocation(location)
}).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">server</span>)</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The server is <span class="hljs-subst">${server}</span>`</span>)
});
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUser()
<span class="hljs-keyword">const</span> location = <span class="hljs-keyword">await</span> fetchLocationForUser(user)
<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">await</span> fetchServerForLocation(location)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The server is <span class="hljs-subst">${server}</span>`</span>)
</code></pre>
<p>They both do the same thing, but the second example is so much easier to understand! The <code>async</code> and <code>await</code> keywords weren't released until <em>after</em> the <code>.then</code> API, which is why there is still a lot of legacy <code>.then()</code> code out there.</p>
<h2 id="heading-error-handling">Error Handling</h2>
<p>When something goes wrong while a program is running, JavaScript uses the <code>try/catch</code> paradigm for handling those errors. Try/catch is fairly common, and <a target="_blank" href="https://boot.dev/learn/learn-python">Python</a> uses a similar mechanism.</p>
<h3 id="heading-first-an-error-is-thrown">First, an error is thrown</h3>
<p>For example, let's say we try to access a property on an undefined variable. JavaScript will automatically "throw" an error.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> speed = car.speed
<span class="hljs-comment">// The code crashes with the following error:</span>
<span class="hljs-comment">// "ReferenceError: car is not defined"</span>
</code></pre>
<h3 id="heading-trying-and-catching-errors">Trying and catching errors</h3>
<p>By wrapping that code in a try/catch block, we can handle the case where <code>car</code> is not yet defined.</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> speed = car.speed
} <span class="hljs-keyword">catch</span> (err) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`An error was thrown: <span class="hljs-subst">${err}</span>`</span>)
  <span class="hljs-comment">// the code cleanly logs:</span>
  <span class="hljs-comment">// "An error was thrown: ReferenceError: car is not defined"</span>
}
</code></pre>
<h3 id="heading-bugs-vs-errors">Bugs vs Errors</h3>
<p>Error handling via try/catch is not the same as debugging. Likewise, errors are not the same as bugs.</p>
<ul>
<li><p>Good code with no bugs can still produce errors that are gracefully handled</p>
</li>
<li><p>Bugs are, by definition, bits of code that aren't working as intended</p>
</li>
</ul>
<h3 id="heading-what-is-debugging">What is Debugging?</h3>
<p>"Debugging" a program is the process of going through your code to find where it is not behaving as expected. Debugging is a manual process performed by the developer.</p>
<p>Examples of debugging:</p>
<ul>
<li><p>Adding a missing parameter to a function call</p>
</li>
<li><p>Updating a broken URL that an HTTP call was trying to reach</p>
</li>
<li><p>Fixing a date-picker component in an app that wasn't displaying properly</p>
</li>
</ul>
<h3 id="heading-what-is-error-handling">What is Error Handling?</h3>
<p>"Error handling" is code that can handle <em>expected</em> edge cases in your program. Error handling is an automated process that we design into our production code to protect it from things like weak internet connections, bad user input, or bugs in other people's code that we have to interface with.</p>
<p>Examples of error handling:</p>
<ul>
<li><p>Using a try/catch block to detect an issue with user input</p>
</li>
<li><p>Using a try/catch block to gracefully fail when no internet connection is available</p>
</li>
</ul>
<h3 id="heading-in-short-dont-use-trycatch-to-try-to-handle-bugs">In short, don't use try/catch to try to handle bugs</h3>
<p>If your code has a <a target="_blank" href="https://en.wikipedia.org/wiki/Software_bug">bug</a>, try/catch won't help you. You need to just go find the bug and fix it.</p>
<p>If something out of your control can produce issues in your code, you should use try/catch or other error-handling logic to deal with it.</p>
<p>For example, there could be a prompt in a game for users to type in a new character name, but we don't want them to use punctuation. Validating their input and displaying an error message if something is wrong with it would be a form of "error handling".</p>
<h3 id="heading-asyncawait-makes-error-handling-easier">async/await makes error handling easier</h3>
<p><code>try</code> and <code>catch</code> are the standard way to handle errors in JavaScript, the trouble is, the original Promise API with <code>.then</code> didn't allow us to make use of <code>try</code> and <code>catch</code> blocks.</p>
<p>Luckily, the <code>async</code> and <code>await</code> keywords <em>do</em> allow it - yet another reason to prefer the newer syntax.</p>
<h3 id="heading-catch-callback-on-promises">.catch() callback on promises</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">.catch()</a> method works similarly to the .then() method, but it fires when a promise is <em>rejected</em> instead of resolved.</p>
<h3 id="heading-example-with-then-and-catch-callbacks">Example with .then and .catch callbacks</h3>
<pre><code class="lang-js">fetchUser().then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">user</span>)</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`user fetched: <span class="hljs-subst">${user}</span>`</span>)
}).catch(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>)</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`an error was thrown: <span class="hljs-subst">${err}</span>`</span>)
});
</code></pre>
<h3 id="heading-example-of-awaiting-a-promise-1">Example of awaiting a promise</h3>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUser()
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`user fetched: <span class="hljs-subst">${user}</span>`</span>)
} <span class="hljs-keyword">catch</span> (err) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`an error was thrown: <span class="hljs-subst">${err}</span>`</span>)
}
</code></pre>
<p>As you can see, the <code>async/await</code> version looks just like normal <code>try/catch</code> JavaScript.</p>
<h2 id="heading-http-headers">HTTP Headers</h2>
<p>An <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/HTTP_header">HTTP header</a> allows clients and servers to pass <em>additional</em> information with each request or response. Headers are just case-insensitive <a target="_blank" href="https://en.wikipedia.org/wiki/Name%E2%80%93value_pair">key-value pairs</a> that pass additional <a target="_blank" href="https://en.wikipedia.org/wiki/Metadata">metadata</a> about the request or response.</p>
<p>HTTP requests from a web browser carry with them many headers, including but not limited to:</p>
<ul>
<li><p>The type of client (for example Google Chrome)</p>
</li>
<li><p>The Operating system (for example Windows)</p>
</li>
<li><p>The preferred language (for example US English)</p>
</li>
</ul>
<p>As developers, we can also define custom headers in each request.</p>
<h3 id="heading-headers-api">Headers API</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Headers">Headers</a> API allows us to perform various actions on our request and response headers such as retrieving, setting, and removing them. We can access the headers object through the <code>Request.headers</code> and <code>Response.headers</code> properties.</p>
<h3 id="heading-how-to-use-the-browsers-developer-tools">How to Use the Browser's Developer Tools</h3>
<p>Modern web browsers offer developers a powerful set of <em>developer tools</em>. The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">Developer Tools</a> are a front-end web developer's best friend. For example, using the dev tools you can:</p>
<ul>
<li><p>View the web page's JavaScript console output</p>
</li>
<li><p>Inspect the page's HTML, CSS, and JavaScript code</p>
</li>
<li><p>View network requests and responses, along with their headers</p>
</li>
</ul>
<p>The method for accessing dev tools varies from browser to browser. If you're on Chrome, you can just right-click anywhere within a web page and click the "inspect" option. Follow this link for more info on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools#:~:text=How%20do%20you%20pull%20it%20up%3F%20Three%20ways%3A">how to access dev tools</a>.</p>
<h3 id="heading-the-network-tab">The network tab</h3>
<p>While all of the tabs within the dev tools are very useful, we will be focusing specifically on the <em>Network tab</em> in this chapter so we can play with HTTP headers.</p>
<p>The Network tab monitors your browser's network activity and records all of the requests and responses the browser is making, including how long each of those requests and responses takes to fully process.</p>
<p>If you navigate to the Network tab and don't see any requests appear, try refreshing the page.</p>
<p><img src="https://i.imgur.com/STKdceG.png" alt="Image" width="580" height="372" loading="lazy"></p>
<h3 id="heading-why-are-headers-useful">Why are headers useful?</h3>
<p>Headers are useful for several reasons, from design to security. But most often headers are used as <a target="_blank" href="https://en.wikipedia.org/wiki/Metadata">metadata</a> or data <em>about</em> the request.</p>
<p>So, for example, let's say we wanted to ask for a player's level from a game's server. We need to send that player's ID to the server so it knows which player to send back the information for. That ID <em>is my request</em>, it's not information <em>about my request</em>.</p>
<p>A good example of a use case for headers is <a target="_blank" href="https://auth0.com/intro-to-iam/what-is-authentication/">authentication</a>. Often times a user's credentials are included in request headers. Credentials don't have much to do with the request <em>itself</em>, but simply authorize the requester to be allowed to make the request in question.</p>
<h2 id="heading-what-is-json">What is JSON?</h2>
<p>JavaScript Object Notation, or <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON">JSON</a>, is a standard for representing <em>structured</em> data based on JavaScript's object syntax.</p>
<p>JSON is commonly used to transmit data in web apps using HTTP. The HTTP <code>fetch()</code> requests we have been using in this course have been returning data as JSON data.</p>
<h3 id="heading-json-syntax">JSON Syntax</h3>
<p>Because we already understand what JavaScript objects look like, understanding JSON is easy. JSON is just a stringified JavaScript object. The following is valid JSON data:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"movies"</span>: [
        {
            <span class="hljs-attr">"id"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"genre"</span>: <span class="hljs-string">"Action"</span>,
            <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Iron Man"</span>,
            <span class="hljs-attr">"director"</span>: <span class="hljs-string">"Jon Favreau"</span>
        },
        {
            <span class="hljs-attr">"id"</span>: <span class="hljs-number">2</span>,
            <span class="hljs-attr">"genre"</span>: <span class="hljs-string">"Action"</span>,
            <span class="hljs-attr">"title"</span>: <span class="hljs-string">"The Avengers"</span>,
            <span class="hljs-attr">"director"</span>: <span class="hljs-string">"Joss Whedon"</span>
        }
    ]
}
</code></pre>
<h3 id="heading-how-to-parse-http-responses-as-json">How to Parse HTTP Responses as JSON</h3>
<p>JavaScript provides us with some easy tools to help us work with JSON. After making an HTTP request with the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch() API</a>, we get a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Response">Response object</a>. That response object offers us some methods that help us interact with the response.</p>
<p>One such method is the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Response/json">.json()</a> method. The <code>.json()</code> method takes the response stream returned by a fetch request and returns a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a> that resolves into a JavaScript object parsed from the JSON body of the HTTP response.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(...)
<span class="hljs-keyword">const</span> javascriptObjectResponse = <span class="hljs-keyword">await</span> resp.json()
</code></pre>
<p>It's important to note that the result of the <code>.json()</code> method is <em>NOT</em> JSON. It is the result of taking JSON data from the HTTP response body and parsing that input into a JavaScript Object.</p>
<h3 id="heading-json-review">JSON Review</h3>
<p>JSON is a <em>stringified representation</em> of a JavaScript object, which makes it perfect for saving to a file or sending in an HTTP request.</p>
<p>Remember, an actual JavaScript object is something that exists only within your program's variables. If we want to send an object outside our program, for example, across the internet in an HTTP request, we need to convert it to JSON first.</p>
<h3 id="heading-its-not-just-used-in-javascript">It's not just used in JavaScript</h3>
<p>Just because JSON is called <em>JavaScript</em> Object Notation doesn't mean it's only used by JavaScript! JSON is a common standard that is recognized and supported by every major programming language.</p>
<p>For example, even though Boot.dev's backend API is written in <a target="_blank" href="https://boot.dev/learn/learn-golang">Go</a>, we still use <a target="_blank" href="https://blog.boot.dev/golang/json-golang/">JSON</a> as the communication format between the front-end and backend.</p>
<p>By the way, this course has been about interacting with back-end servers from a front-end perspective. But if you're curious about how you can become a back-end engineer, <a target="_blank" href="https://blog.boot.dev/backend/become-backend-developer/">check out this guide</a> I've put together. For reference, it takes most people <a target="_blank" href="https://blog.boot.dev/backend/how-long-to-become-backend-dev/">between 6-18 months</a> to learn enough to get their first <a target="_blank" href="https://blog.boot.dev/backend/backend-job-description/">back-end job</a>.</p>
<h3 id="heading-common-json-use-cases">Common JSON use-cases</h3>
<ul>
<li><p>In HTTP request and response bodies</p>
</li>
<li><p>As formats for text files. <code>.json</code> files are often used as configuration files.</p>
</li>
<li><p>In NoSQL databases like MongoDB, ElasticSearch, and Firestore</p>
</li>
</ul>
<h3 id="heading-how-to-pronounce-json">How to Pronounce JSON</h3>
<p>I pronounce it "Jay-sawn", but I've also heard people pronounce it "Jason", like the name.</p>
<h3 id="heading-how-to-send-json">How to Send JSON</h3>
<p>JSON isn't just something we get from the server, we can also <em>send</em> JSON data.<br>In JavaScript, two of the main methods we have access to are <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">JSON.parse()</a>, and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">JSON.stringify()</a>.</p>
<h4 id="heading-jsonstringify"><code>JSON.stringify()</code></h4>
<p><code>JSON.stringify()</code> is particularly useful for <em>sending</em> JSON.</p>
<p>As you may expect, the JSON <code>stringify()</code> method does the opposite of parse. It takes a JavaScript object or value as input and converts it into a string. This is useful when we need to serialize the objects into strings to send them to our server or store them in a database.</p>
<p>Here's a snippet of code that sends a JSON payload to a remote server:</p>
<pre><code class="lang-plaintext">async function sendPayload(data, headers) {
  const response = await fetch(url, {
    method: 'POST',
    mode: 'cors',
    headers: headers,
    body: JSON.stringify(data)
  })
  return response.json()
}
</code></pre>
<h3 id="heading-how-to-parse-json">How to Parse JSON</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">JSON.parse()</a> method takes a JSON string as input and constructs the JavaScript value/object described by the string. This allows us to work with the JSON as a normal JavaScript object.</p>
<p>Seeing as JSON objects have a tree-like structure, it can be helpful to know how to <a target="_blank" href="https://blog.boot.dev/javascript/how-to-recursively-traverse-objects/">traverse them recursively</a> if needs be.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> json = <span class="hljs-string">'{"title": "Avengers Endgame", "Rating":4.7, "inTheaters":false}'</span>;
<span class="hljs-keyword">const</span> obj = <span class="hljs-built_in">JSON</span>.parse(json)

<span class="hljs-built_in">console</span>.log(obj.title)
<span class="hljs-comment">// Avengers Endgame</span>
</code></pre>
<h3 id="heading-xml">XML</h3>
<p>We can't talk about JSON without mentioning <a target="_blank" href="https://en.wikipedia.org/wiki/XML#:~:text=Extensible%20Markup%20Language%20\(XML\)%20is,%2Dreadable%20and%20machine%2Dreadable.">XML</a>. Extensible Markup Language, or <code>XML</code> is a text-based format for representing structured information, just like JSON - it just looks a bit different.</p>
<p>XML is a markup language like <a target="_blank" href="https://en.wikipedia.org/wiki/HTML">HTML</a>, but it's more generalized in that it does <em>not</em> use predefined tags. Just like how in a JSON object keys can be called anything, XML tags can also have any name.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">root</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">genre</span>&gt;</span>Action<span class="hljs-tag">&lt;/<span class="hljs-name">genre</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Iron Man<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">director</span>&gt;</span>Jon Favreau<span class="hljs-tag">&lt;/<span class="hljs-name">director</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">root</span>&gt;</span>
</code></pre>
<p>The same data in JSON form:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"1"</span>,
  <span class="hljs-attr">"genre"</span>: <span class="hljs-string">"Action"</span>,
  <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Iron Man"</span>,
  <span class="hljs-attr">"director"</span>: <span class="hljs-string">"Jon Favreau"</span>
}
</code></pre>
<h3 id="heading-why-use-xml">Why use XML?</h3>
<p>XML and JSON both accomplish similar tasks, so which should you use?</p>
<p>XML used to be used for the same things that today JSON is used for. Configuration files, HTTP bodies, and other data-transfer use cases can work just fine using JSON or XML. Here's my advice: generally speaking, if JSON works, you should favor it over XML these days. JSON is lighter-weight, easier to read, and has better support in most modern programming languages.</p>
<p>There are some cases where XML might still be the better, or maybe even the necessary choice, but those cases will be rare.</p>
<h2 id="heading-http-methods">HTTP Methods</h2>
<p>HTTP defines a set of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">methods</a> that we use every time we make a request. We have used some of these methods in previous exercises, but it's time we dive into them and understand the differences and use cases behind the different methods.</p>
<h3 id="heading-the-get-method">The GET method</h3>
<p>The <a target="_blank" href="https://www.freecodecamp.org/news/javascript-get-request-tutorial/">GET method</a> is used to "get" a representation of a specified resource. You are not taking the data away from the server, but rather getting a representation, or copy, of the resource in its current state.</p>
<p>A get request is considered a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP">safe</a> method to call multiple times because it doesn't alter the state of the server.</p>
<h3 id="heading-how-to-make-a-get-request-using-the-fetch-api">How to Make a GET Request using the Fetch API</h3>
<p>The fetch() method accepts an optional <code>init</code> object parameter as its second argument that we can use to define things like:</p>
<ul>
<li><p><code>method</code>: The HTTP method of the request, like <code>GET</code>.</p>
</li>
<li><p><code>headers</code>: The headers to send.</p>
</li>
<li><p><code>mode</code>: Used for security, we'll talk about this in future courses</p>
</li>
<li><p><code>body</code>: The body of the request. Often encoded as JSON.</p>
</li>
</ul>
<p>Example <code>GET</code> request using fetch:</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> fetch(url, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-string">'sec-ch-ua-platform'</span>: <span class="hljs-string">'macOS'</span>
  }
})
</code></pre>
<h3 id="heading-why-do-we-use-http-methods">Why do we use HTTP methods?</h3>
<p>As we touched on before, the primary purpose of HTTP methods is to indicate to the server what we want to do with the resource we're trying to interact with.</p>
<p>At the end of the day, an HTTP method is just a string, like <code>GET</code>, <code>POST</code>, <code>PUT</code>, or <code>DELETE</code>. But by <em>convention</em>, backend developers almost always write their server code so that the methods correspond with different "CRUD" actions.</p>
<p>The "CRUD" actions are:</p>
<ul>
<li><p>Create</p>
</li>
<li><p>Read</p>
</li>
<li><p>Update</p>
</li>
<li><p>Delete</p>
</li>
</ul>
<p>The bulk of the logic in most web applications is "CRUD" logic. The web interface allows users to create, read, update and delete various resources.</p>
<p>Think of a social media site - users are basically creating, reading, updating and deleting their social posts. They are also creating, reading, updating and deleting their user accounts. It's CRUD all the way down!</p>
<p>As it happens, the 4 most common HTTP methods map nicely to the CRUD actions:</p>
<ul>
<li><p><code>POST</code> = create</p>
</li>
<li><p><code>GET</code> = read</p>
</li>
<li><p><code>PUT</code> = update</p>
</li>
<li><p><code>DELETE</code> = delete</p>
</li>
</ul>
<h3 id="heading-post-requests">POST Requests</h3>
<p>An <a target="_blank" href="https://www.freecodecamp.org/news/javascript-post-request-how-to-send-an-http-post-request-in-js/">HTTP POST request</a> sends data to a server, typically to create a new resource. The <code>body</code> of the request is the <em>payload</em> that is being sent to the server with the request. Its type is indicated by the <code>Content-Type</code> header.</p>
<h3 id="heading-how-to-add-a-body">How to Add a <code>body</code></h3>
<p>The <code>body</code> of the request is the <em>payload</em> that is being sent to the server with the request. Its type is indicated by the <code>Content-Type</code> header - for us, that's going to be JSON.</p>
<p><code>POST</code> requests are generally <em>not</em> safe methods to call multiple times, because it alters the state of the server. You wouldn't want to accidentally create 2 accounts for the same user, for example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> fetch(url, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
  },
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(data)
})
</code></pre>
<h3 id="heading-http-status-codes">HTTP Status Codes</h3>
<p>Now that we understand how to write HTTP requests from scratch, we need to learn how to ensure that the server is doing what we want.</p>
<p>Earlier in the course, we learned about how to access the browser's <em>developer tools</em> and use those tools to inspect HTTP requests. We can use that same process to check on the requests we are making and verify what they are doing so we can address potential problems.</p>
<p>When looking at requests, we can check on the <code>Status Code</code> of the request to get some information if the request was successful or not.</p>
<ul>
<li><p><code>100-199</code>: Informational responses. These are very rare.</p>
</li>
<li><p><code>200-299</code>: Successful responses. Hopefully, most responses are 200's!</p>
</li>
<li><p><code>300-399</code>: Redirection messages. These are typically invisible because the browser or HTTP client will automatically do the redirect.</p>
</li>
<li><p><code>400-499</code>: Client errors. You'll see these often, especially when trying to debug a client application</p>
</li>
<li><p><code>500-599</code>: Server errors. You'll see these sometimes, usually only if there is a bug on the server.</p>
</li>
</ul>
<p>Here are some of the most common status codes, but you can see a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">full list here</a> if you're interested.</p>
<ul>
<li><p><code>200</code> - OK. This is by far the most common code, it just means that everything worked as expected.</p>
</li>
<li><p><code>201</code> - Created. This means that a resource was created successfully. Typically in response to a <code>POST</code> request.</p>
</li>
<li><p><code>301</code> - Moved permanently. This means the resource was moved to a new place, and the response will include where that new place is. Websites often use <code>301</code> redirects when they change their domain name, for example.</p>
</li>
<li><p><code>400</code> - Bad request. A general error indicating the client made a mistake in their request.</p>
</li>
<li><p><code>403</code> - Unauthorized. This means the client doesn't have the correct permissions. Maybe they didn't include a required authorization header, for example.</p>
</li>
<li><p><code>404</code> - Not found. You'll see this on websites quite often. It just means the resource doesn't exist.</p>
</li>
<li><p><code>500</code> - Internal server error. This means something went wrong on the server, likely a bug on their end.</p>
</li>
</ul>
<h3 id="heading-you-dont-need-to-memorize-them">You don't need to memorize them</h3>
<p>You need to know the basics, like "2XX is good", "4XX is a client error", and "5XX is a server error". That said, you don't need to memorize all the codes, they're easy to look up.</p>
<p><img src="https://i.imgur.com/FJl2z9O.jpg" alt="Image" width="549" height="454" loading="lazy"></p>
<p>Let's check some status codes!</p>
<p>The <code>.status</code> property on a Response object will give you the code. Here's an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStatusCode</span>(<span class="hljs-params">url, headers</span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
    <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
    <span class="hljs-attr">headers</span>: headers
  })
  <span class="hljs-keyword">return</span> response.status
}
</code></pre>
<h3 id="heading-put-method">PUT Method</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT">HTTP PUT method</a> creates a new resource or replaces a representation of the target resource with the contents of the request's <code>body</code>. In short, it updates a resource's properties.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> fetch(url, {
   <span class="hljs-attr">method</span>: <span class="hljs-string">'PUT'</span>,
   <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>,
   <span class="hljs-attr">headers</span>: {
   <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
   },
   <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(data)
})
</code></pre>
<h3 id="heading-post-vs-put">POST vs PUT</h3>
<p>You may be thinking <code>PUT</code> is similar to <code>POST</code> or <code>PATCH</code>, and frankly, you'd be right. The main difference is that PUT is meant to be <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Idempotent">idempotent</a>, meaning multiple identical PUT requests should have the same effect on the server.</p>
<p>In contrast, several identical <code>POST</code> requests would have additional side effects, such as creating multiple copies of the resource.</p>
<h3 id="heading-http-patch-vs-put">HTTP Patch vs PUT</h3>
<p>You may encounter <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH">PATCH</a> methods from time to time. While it is not nearly as common as the other methods, like <code>PUT</code>, it's important to know about it and what it does. The <code>PATCH</code> method is intended to <em>partially</em> modify a resource.</p>
<p>Long story short, <code>PATCH</code> isn't nearly as popular as <code>PUT</code>, and many servers, even if they allow partial updates, will still just use the <code>PUT</code> method for that.</p>
<h3 id="heading-http-delete">HTTP Delete</h3>
<p>The <code>DELETE</code> method does exactly as you would expect: it's conventionally used to delete a specified resource.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This deletes the location with ID: 52fdfc07-2182-454f-963f-5f0f9a621d72</span>
<span class="hljs-keyword">const</span> url = <span class="hljs-string">'https://example-api.com/locations/52fdfc07-2182-454f-963f-5f0f9a621d72'</span>

<span class="hljs-keyword">await</span> fetch(url, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">'DELETE'</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'cors'</span>
})
</code></pre>
<h2 id="heading-url-paths-and-parameters">URL Paths and Parameters</h2>
<p>The URL Path comes right after the domain (or port if one is provided) in a URL string.</p>
<p>In this URL, the path is <code>/root/next</code>: <code>http://testdomain.com/root/next</code>.</p>
<h3 id="heading-what-paths-meant-in-the-early-internet">What paths meant in the early internet</h3>
<p>In the early days of the internet, and sometimes still today, many web servers simply served raw files from the server's file system.</p>
<p>For example, if I wanted you to be able to access some text documents, I could start a web server in my <code>documents</code> directory. If you made a request to my server, you would be able to access different documents by using the path that matched my local file structure.</p>
<p>If I had a file in my local <code>/documents/hello.txt</code>, you could access it by making a <code>GET</code> request to <code>http://example.com/documents/hello.txt</code>.</p>
<h3 id="heading-how-paths-are-used-today">How paths are used today</h3>
<p>Most modern web servers don't use that simple mapping of <code>URL path</code> -&gt; <code>file path</code>. Technically, a URL path is just a string that the web server can do what it wants with, and modern websites take advantage of that flexibility.</p>
<p>Some common examples of what paths are used for include:</p>
<ul>
<li><p>The hierarchy of pages on a website, whether or not that reflects a server's file structure</p>
</li>
<li><p>Parameters being passed into an HTTP request, like an ID of a resource</p>
</li>
<li><p>The version of the API</p>
</li>
<li><p>The type of resource being requested</p>
</li>
</ul>
<h3 id="heading-restful-apis">RESTful APIs</h3>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/REST">Representational State Transfer, or REST</a>, is a popular convention that HTTP servers follow. Not all HTTP APIs are "REST APIs", or "RESTful", but it is <em>very</em> common.</p>
<p>RESTful servers follow a loose set of rules that makes it easy to build reliable and predictable web APIs. REST is more or less a set of conventions about how HTTP <em>should</em> be used.</p>
<h3 id="heading-separate-and-agnostic">Separate and agnostic</h3>
<p>The big idea behind REST is that resources are transferred via well-recognized, language-agnostic client/server interactions.</p>
<p>A RESTful style means the implementation of the client and server can be done independently of one another, as long as some simple standards, like the names of the available resources, have been established.</p>
<h3 id="heading-stateless">Stateless</h3>
<p>A RESTful architecture is stateless. This means that the server does not need to know what state the client is in, nor does the client need to know what state the server is in.</p>
<p>Statelessness in REST is enforced by interacting with resources instead of commands. Keep in mind, this doesn't mean the applications are stateless - on the contrary, what would "updating a resource" even mean if the server wasn't keeping track of its state?</p>
<h3 id="heading-paths-in-rest">Paths in REST</h3>
<p>In a RESTful API, the last section of the <code>path</code> of a URL should specify which resource is being accessed. Then, as we talked about in the "methods" section, depending on whether the request is a <code>GET</code>, <code>POST</code>, <code>PUT</code> or <code>DELETE</code>, the resource is read, created, updated, or deleted.</p>
<p>For example, in the <a target="_blank" href="https://pokeapi.co/">PokeAPI</a>:</p>
<ul>
<li><p><a target="_blank" href="https://pokeapi.co/api/v2/pokemon/"><code>https://pokeapi.co/api/v2/pokemon/</code></a></p>
</li>
<li><p><a target="_blank" href="https://pokeapi.co/api/v2/pokemon/"><code>https://pokeapi.co/api/v2/location/</code></a></p>
</li>
</ul>
<p>The first part of the path specifies that we're interacting with an API rather than a website. The next part specifies the version, in this case, version 2, or <code>v2</code>.</p>
<p>Finally, the last part denotes which resource is being accessed, be it a <code>location</code> or <code>pokemon</code>.</p>
<h3 id="heading-url-query-parameters">URL Query Parameters</h3>
<p>A URL's query parameters appear next in the URL structure but are <em>not</em> always present - they're optional. For example:</p>
<p><a target="_blank" href="https://www.google.com/search?q=boot.dev">https://www.google.com/search?q=boot.dev</a></p>
<p><code>q=boot.dev</code> is a query parameter. Like headers, query parameters are <code>key / value</code> pairs. In this case, <code>q</code> is the key and <code>boot.dev</code> is the value.</p>
<h3 id="heading-the-documentation-of-an-http-server">The Documentation of an HTTP Server</h3>
<p>You may be wondering:</p>
<blockquote>
<p>How the heck am I supposed to memorize how all these different servers work???</p>
</blockquote>
<p>The good news is that <em>you don't need to</em>. When you work with a backend server, it's the responsibility of that server's developers to provide you with instructions, or <em>documentation</em> that explains how to interact with it.</p>
<p>For example, the documentation should tell you:</p>
<ul>
<li><p>The domain of the server</p>
</li>
<li><p>The resources you can interact with (HTTP paths)</p>
</li>
<li><p>The supported query parameters</p>
</li>
<li><p>The supported HTTP methods</p>
</li>
<li><p>Anything else you'll need to know to work with the server</p>
</li>
</ul>
<p><img src="https://i.imgur.com/GIlWhYF.jpg" alt="Image" width="500" height="553" loading="lazy"></p>
<p>The server has control</p>
<p>As we mentioned earlier, the server has complete control over how the path in a URL is interpreted and used in a request. The same goes for query parameters.</p>
<p>Not all servers support query parameters for every type of request, it just depends, so you'll need to consult the docs.</p>
<h3 id="heading-multiple-query-parameters">Multiple Query Parameters</h3>
<p>We mentioned that query parameters are <code>key/value</code> pairs - that means we can have multiple pairs.</p>
<p><code>http://example.com?firstName=lane&amp;lastName=wagner</code></p>
<p>In the example above:</p>
<ul>
<li><p><code>firstName</code> = <code>lane</code></p>
</li>
<li><p><code>lastName</code> = <code>wagner</code></p>
</li>
</ul>
<p>The <code>?</code> separates the query parameters from the rest of the URL. The <code>&amp;</code> is then used to separate <em>every pair</em> of query parameters after that.</p>
<p>For example, make this request to limit the number of Pokémon returned from the PokeAPI to <code>2</code>:</p>
<pre><code class="lang-plaintext">https://pokeapi.co/api/v2/location/?limit=2
</code></pre>
<h2 id="heading-what-is-https">What is HTTPs?</h2>
<p>Hypertext Transfer Protocol <em>Secure</em> or <a target="_blank" href="https://www.freecodecamp.org/news/what-is-https-http-vs-https-meaning-and-how-it-works/">HTTPS</a> is an extension of the HTTP protocol. HTTPS secures the data transfer between client and server by <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Encryption">encrypting</a> all of the communication.</p>
<p>HTTPS allows a client to safely share sensitive information with the server through an HTTP request, such as credit card information, passwords, or bank account numbers.</p>
<p>HTTPS requires that the client use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/SSL">SSL</a> or <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tls-transport-layer-security-encryption-explained-in-plain-english/">TLS</a> to protect requests and traffic by encrypting the information in the request. HTTPS is just HTTP with extra security.</p>
<p><img src="https://i.imgur.com/iOkQUdG.png" alt="Image" width="517" height="487" loading="lazy"></p>
<p><em>HTTP vs HTTPS</em></p>
<h3 id="heading-https-keeps-your-messages-private-but-not-your-identity">HTTPS keeps your messages private, but not your identity</h3>
<p>We won't cover <em>how</em> encryption works in this course, but we will in later courses. For now, it's important to note that while HTTPS encrypts <em>what you are saying</em>, it doesn't necessarily protect <em>who you are</em>. Tools like <a target="_blank" href="https://nordvpn.com/what-is-a-vpn/">VPNs</a> are needed for remaining anonymous online.</p>
<h3 id="heading-https-ensures-that-youre-talking-to-the-right-person-or-server">HTTPS ensures that you're talking to the right person (or server)</h3>
<p>In addition to encrypting the information within a request, HTTPS uses <a target="_blank" href="https://en.wikipedia.org/wiki/Digital_signature">digital signatures</a> to prove that you're communicating with the server that you think you are.</p>
<p>If a hacker were to intercept an HTTPS request by tapping into a network cable, they wouldn't be able to successfully pretend they are your bank's web server.</p>
<p>Assuming that a server supports HTTPs, you use it by simply changing the protocol on your request URL: <code>https://boot.dev</code></p>
<h3 id="heading-want-to-put-what-youve-learned-into-practice-with-a-project">Want to put what you've learned into practice with a project?</h3>
<p>Check out this <a target="_blank" href="https://boot.dev/build/link-analyzer">project guide where you'll build a web crawler in JavaScript</a> from scratch. It will have you using the Fetch API and parsing JSON data like a pro! You don't need to build the project, but it's a great way to practice what you're learned.</p>
<h2 id="heading-congratulations-on-making-it-to-the-end">Congratulations on making it to the end!</h2>
<p>If you're interested in doing the interactive coding assignments and quizzes for this course you can check out the <a target="_blank" href="https://boot.dev/learn/learn-object-oriented-programming">Learn HTTP course</a> over on <a target="_blank" href="https://boot.dev/">Boot.dev</a>.</p>
<p>This course is a part of my <a target="_blank" href="https://boot.dev/tracks/backend">full back-end developer career path</a>, made up of other courses and projects if you're interested in checking those out.</p>
<p>If you want to see the other content I'm creating related to web development, check out some of my links below:</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/wagslane">Lane on Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://youtube.com/@bootdotdev">Lane on YouTube</a></p>
</li>
<li><p><a target="_blank" href="https://wagslane.dev">Lane's Personal Site</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Wireshark – Computer Networking Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ In this post, you will learn about the single most important and useful tool in Computer Networks – Wireshark. This post relies on basic knowledge of computer networks. Be sure to check my previous post about the five layers model if you need a refre... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-wireshark-computer-networking/</link>
                <guid isPermaLink="false">66c17c3dea5637f064224a0a</guid>
                
                    <category>
                        <![CDATA[ computer network ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #infosec ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Omer Rosenbaum ]]>
                </dc:creator>
                <pubDate>Mon, 23 Jan 2023 23:35:33 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/Computer-Networks-Ethernet--3-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this post, you will learn about the single most important and useful tool in Computer Networks – Wireshark.</p>
<p>This post relies on basic knowledge of computer networks. Be sure to check my <a target="_blank" href="https://www.freecodecamp.org/news/the-five-layers-model-explained/">previous post about the five layers model</a> if you need a refresher.</p>
<h1 id="heading-what-is-wireshark">What is Wireshark?</h1>
<p>Wireshark is a sniffer, as well as a packet analyzer.</p>
<p>What does that mean?</p>
<p>You can think of a <strong>sniffer</strong> as a measuring device. We use it to examine what’s going on inside a network cable, or in the air if we are dealing with a wireless network. A sniffer shows us the data that passes through our network card.</p>
<p>But Wireshark does more than that. A sniffer could just display a stream of bits - ones and zeroes, that the network card sees. Wireshark is also a <strong>packer analyzer</strong> that displays lots of meaningful data about the frames that it sees.</p>
<p>Wireshark is an open-source and free tool, and is widely used to analyze network traffic.</p>
<p>Wireshark can be helpful in many cases. It might be helpful for debugging problems in your network, for instance – if you can’t connect from one computer to another, and want to understand what’s going on. </p>
<p>It can also help programmers. For example, imagine that you were implementing a chat program between two clients, and something was not working. In order to understand what exactly is being sent, you may use Wireshark to see the data transmitted over the wire.</p>
<p>So, let’s get to know Wireshark.</p>
<h1 id="heading-how-to-download-and-install-wireshark">How to Download and Install Wireshark</h1>
<p>Start by downloading Wireshark from its official website:</p>
<p><a target="_blank" href="https://www.wireshark.org/#download">https://www.wireshark.org/#download</a></p>
<p>Follow the instructions on the installer and you should be good to go.</p>
<h1 id="heading-how-to-sniff-traffic-with-wireshark">How to Sniff Traffic with Wireshark</h1>
<p>Launch Wireshark, and start by sniffing some data. For that, you can hit <code>Ctrl+K</code> (PC) or <code>Cmd+K</code> (Mac)  to get the <code>Capture Options</code> window. Notice that you can reach this window in other ways. You can go to <code>Capture-&gt;Options</code>. Alternatively, you can click the <code>Capture Options</code> icon.</p>
<p>I encourage you to use keyboard shortcuts and get comfortable with them right from the start, as they'll allow you to save time and work more efficiently.</p>
<p>So, again, I’ve used <code>Ctrl+K</code> (or <code>Cmd+K</code>) and got this screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-208.png" alt="Image" width="600" height="400" loading="lazy">
<em>The <code>Capture Options</code> window in Wireshark (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>Here we can see a list of interfaces, and I happen to have quite a few. Which one is relevant? If you’re not sure at this point, you can look at the <code>Traffic</code> column, and see which interfaces currently have traffic. </p>
<p>Here we can see that <code>Wi-Fi 3</code> has got traffic going through it, as the line is high. Select the relevant network interface, and then hit <code>Enter</code>, or click the button <code>Start</code>.</p>
<p>Let Wireshark sniff the network for a bit, and then stop the sniff using <code>Ctrl+E</code> / <code>Cmd+E</code>. Again, this can be achieved in other ways – such as going to <code>Capture-&gt;Stop</code> or clicking the <code>Stop</code> icon.</p>
<p>Consider the different sections:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-210.png" alt="Image" width="600" height="400" loading="lazy">
<em>Wireshark's sections (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>The section marked in red includes Wireshark’s menu, with all kinds of interesting options.</p>
<p>The main toolbar is marked in blue, providing quick access to some items from the menu.</p>
<p>Next, marked in green, is the <strong>display filter</strong>. We will get back to it shortly, as this is one of the most important features of Wireshark.</p>
<p>Then follows:</p>
<h1 id="heading-the-packet-list-pane">The Packet List Pane</h1>
<p>The packet list pane is marked in orange. It displays a short summary of each packet captured.</p>
<p>(Note: the term Frame belongs to a sequence of bytes in the <a target="_blank" href="https://www.freecodecamp.org/news/the-five-layers-model-explained/">Data Link layer</a>, while a Packet is a sequence of bytes from the <a target="_blank" href="https://www.freecodecamp.org/news/the-five-layers-model-explained/">Network layer</a>. In this post I will use the terms interchangeably, though to be accurate, every packet is a frame, but not every frame is a packet, as there are frames that don't hold network layer data.)</p>
<p>As you can see in the image above, we have a few columns here:</p>
<p>NUMBER (No.) – The number of the packet in the capture file. This number won’t change, even if we use filters. This is just a sequential number – the first frame that you have sniffed gets the number 1, the second frame gets the number 2, and so on.</p>
<p>Time – The timestamp of the packet. It shows how much time has passed from the very first packet we have sniffed until we sniffed the packet in question. Therefore, the time for packet number 1 is always 0.</p>
<p>Source – The address where this packet is coming from. Don’t worry if you don’t understand the format of the addresses just yet, we will cover different addresses in future tutorials.</p>
<p>Destination – The address where this packet is going.</p>
<p>Protocol – The protocol name in a short version. This will be the top protocol – that is, the protocol of the highest layer.</p>
<p>Length – The length of each packet, in bytes.</p>
<p>Info – Additional information about the packet content. This changes according to the protocol.</p>
<p>By clicking on packets in this pane, you control what is displayed in the other two panes which I will now describe.</p>
<h1 id="heading-the-packet-details-pane">The Packet Details Pane</h1>
<p>Click on one of the captured packets. In the example below I clicked on packet number 147:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-211.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting a specific packet changes the packet details pane (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>Now, the <strong>packet details pane</strong> displays the packet selected in the packet list pane in more detail. You can see the layers here. </p>
<p>In the example above, we have Ethernet II as the second layer, IPv4 as the third layer, UDP as the fourth layer, and some data as a payload.</p>
<p>When we click on a specific layer, we actually see the <strong>header</strong> of that layer.</p>
<p>Notice that we don’t see the first layer on its own. As a reminder, the first layer is responsible for <strong>transmitting a single bit</strong> – 0 or 1 – over the network (if you need a refresher about the different layers, <a target="_blank" href="https://www.freecodecamp.org/news/the-five-layers-model-explained/">check out this post</a>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-215.png" alt="Image" width="600" height="400" loading="lazy">
<em>The packet bytes pane in Wireshark (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>Below the packet details pane, we have the <strong>packet bytes pane</strong>. It displays the data from the packet selected in the packet list pane. This is the actual data being sent over the wire. We can see the data in hexadecimal base, as well as ASCII form.</p>
<h1 id="heading-how-to-use-the-display-filter">How to Use the Display Filter</h1>
<p>Wireshark has many different functions, and today we will focus on one thing – the display filter. </p>
<p>As you can see, once you start sniffing data, you get a LOT of traffic. But you definitely don’t want to look at everything. </p>
<p>Recall the example from before – using Wireshark in order to debug a chat program that you’ve implemented. In that case, you would like to see the traffic related to the chat program only.</p>
<p>Let’s say I want to filter only messages sent by the source address of frame number 149 ( <code>192.168.1.3</code> ). I will cover IP addresses in future posts, but for now you can see that it consists four numbers, delimited by a dot:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-217.png" alt="Image" width="600" height="400" loading="lazy">
<em>The <code>display filter</code> in Wireshark (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>Now, even if you don’t know how to filter only packets sent from this IP address, you can use Wireshark to show you how it’s done. </p>
<p>For that, go to the right field we would like to filter – in this case, the source IP address. Then right click -&gt; and choose <code>filter -&gt; Apply as Filter</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-218.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying a display filter (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>After applying the filter, you only see packets that have been sent from this address. Also, you can look at the display filter line and see the command used. In this way, you can learn about the display filter syntax (in this example, it is <code>ip.src</code> for the IP source address field):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-219.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying a display filter (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>Now, try to filter only packets that have been sent from this address, and <strong>to</strong> the address <code>172.217.16.142</code> (as in Frame 130 in the image above). How would you do that?</p>
<p>Well, you could go to the relevant field – in this case, the IP destination address. Now, right click -&gt; <code>Apply as Filter</code> -&gt; and select <code>...and Selected</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-220.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying a display filter (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>If you look at the display filter line after applying this filter:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-221.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying a display filter (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>You can also learn that you can use the <code>&amp;&amp;</code> operand in order to perform <code>and</code>. You could also write the word <code>and</code>, instead, and get the same result.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-222.png" alt="Image" width="600" height="400" loading="lazy">
<em>Applying multiple conditions using <code>&amp;amp;&amp;amp;</code> or <code>and</code> (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<h1 id="heading-how-to-use-wireshark-to-research-the-ping-utility">How to Use Wireshark to Research the Ping Utility</h1>
<p><strong>Ping</strong> is a useful utility to check for remote servers’ connectivity.</p>
<p><a target="_blank" href="https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/">This page</a> explains how to use <code>ping</code> in Windows, and <a target="_blank" href="https://macpaw.com/how-to/use-terminal-on-mac">this page</a> explains how to do that in OSX.</p>
<p>Now, we can try to <code>ping &lt;address&gt;</code> using the command line. By default, ping sends <code>4</code> requests and waits for a <strong>pong</strong> answer. If we want it to send a single request, we could use <code>-n 1</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-224.png" alt="Image" width="600" height="400" loading="lazy">
<em>Using the command line to ping Google (Source: <a target="_blank" href="https://www.youtube.com/watch?v=nbTJXIdEzlo">Brief</a>)</em></p>
<p>You can see that Google has responded. The time it took for the message to return was 92 milliseconds. We will learn about the meaning of TTL in future posts.</p>
<p>Ping is useful to determine whether a remote service is available, and how fast it is to reach that service. If it takes a very long time to reach a reliable server such as google.com, we might have a connectivity problem.</p>
<h2 id="heading-try-it-yourself">Try it yourself</h2>
<p>Now, try to use Wireshark to answer the following questions:</p>
<p>1) What protocol does the <strong>ping</strong> utility use?</p>
<p>2) Using only Wireshark, compute the RTT (Round Trip Time) – how long it took since your ping request was sent and until the ping reply was received?</p>
<p>Next, run the following command:</p>
<p><code>ping -n 1 -l 342 www.google.com</code></p>
<p>3) What is the main difference between the packet sent by this command, and the packet sent by the previous command? Where in Wireshark can you see this difference, inspecting the packets?  </p>
<p>4) What is the content (data) provided in the ping request packet? What is the content provided in the ping response packet?</p>
<h2 id="heading-lets-solve-it-together">Let's solve it together</h2>
<p>So the first question is:</p>
<h3 id="heading-what-protocol-does-the-ping-utility-use">What protocol does the ping utility use?</h3>
<p>To answer that question, start sniffing in Wireshark, and simply run the <code>ping</code> command. Stop the sniff, and consider the packets pane:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-225.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sniffing while running ping (source: <a target="_blank" href="https://www.youtube.com/watch?v=B5iEmaZK9xI&amp;t=2s">Brief</a>)</em></p>
<p>Wireshark marks the packets as <code>Echo (ping) request</code> and <code>Echo (ping) reply</code>.</p>
<p>Considering these packets, we can see they consist of <code>Ethernet</code> for the Data Link layer (though that may differ from one network to another), <code>IPv4</code> as the Network layer, and then <code>ICMP</code> as the protocol for Ping itself. So the answer we found is: <strong>ICMP</strong>.</p>
<p>Next question:</p>
<h3 id="heading-using-only-wireshark-compute-the-round-trip-time">Using only Wireshark, compute the Round Trip Time</h3>
<p>Looking at the captured packets, we can see the <code>Time</code> column, and subtract the time of the Pong packet ( <code>7.888...</code> ) from the time of the Ping packet ( <code>7.796...</code>).</p>
<p>So in this case the RTT was: <strong>92 ms</strong>. Of course, the value can be different when you run the <code>ping</code> utility.</p>
<h3 id="heading-what-is-the-main-difference-between-the-packet-sent-by-this-command-and-the-packet-sent-by-the-previous-command">What is the main difference between the packet sent by this command, and the packet sent by the previous command?</h3>
<p>For question number 3, we are asked to run the following command:</p>
<blockquote>
<p>ping -n 1 -l 342 www.google.com</p>
</blockquote>
<p>Looking at the first run of <code>ping</code>, we can see the length of the packets are <code>74</code> bytes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-225.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sniffing while running ping (source: <a target="_blank" href="https://www.youtube.com/watch?v=B5iEmaZK9xI&amp;t=2s">Brief</a>)</em></p>
<p>Observing the packets sent after running <code>ping</code> with the <code>-l 342</code> argument, we can see that the value is bigger:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-228.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sniffing while running ping (source: <a target="_blank" href="https://www.youtube.com/watch?v=B5iEmaZK9xI&amp;t=2s">Brief</a>)</em></p>
<p>So the main difference is the amount of bytes sent as the data.</p>
<p>Question number four:</p>
<h3 id="heading-what-is-the-content-data-provided-in-the-ping-request-packet">What is the content (data) provided in the ping request packet?</h3>
<h3 id="heading-what-is-the-content-provided-in-the-ping-response-packet">What is the content provided in the ping response packet?</h3>
<p>Click on the request packet to observe the data sent:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-230.png" alt="Image" width="600" height="400" loading="lazy">
<em>Observing the data sent by the <code>ping</code> utility (source: <a target="_blank" href="https://www.youtube.com/watch?v=B5iEmaZK9xI&amp;t=2s">Brief</a>)</em></p>
<p>The answer for the ping request is <code>a</code> through <code>w</code>, over and over again.</p>
<p>Regarding the ping response – it is the same as the request.</p>
<h1 id="heading-summary">Summary</h1>
<p>Wireshark is a wonderful tool for anyone working with Computer Networks. It can help you understand how protocols work and also help you debug applications or network issues. </p>
<p>As you have seen, you can learn how things work by simply running Wireshark in the background while using them and then inspect the traffic. With this tool under your belt, the sky is the limit. </p>
<p>In future tutorials, we will also rely on our knowledge of Wireshark and use it to further understand various concepts in computer networks.</p>
<h2 id="heading-about-the-author">About the Author</h2>
<p><a target="_blank" href="https://www.linkedin.com/in/omer-rosenbaum-034a08b9/">Omer Rosenbaum</a> is <a target="_blank" href="https://swimm.io/">Swimm</a>’s Chief Technology Officer. He's the author of the Brief <a target="_blank" href="https://youtube.com/@BriefVid">YouTube Channel</a>. He's also a cyber training expert and founder of Checkpoint Security Academy. He's the author of <a target="_blank" href="https://data.cyber.org.il/networks/networks.pdf">Computer Networks (in Hebrew)</a>. You can find him on <a target="_blank" href="https://twitter.com/Omer_Ros">Twitter</a>.</p>
<h3 id="heading-additional-references">Additional References</h3>
<ul>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PL9lx0DXCC4BMS7dB7vsrKI5wzFyVIk2Kg">Computer Networks Playlist - on my Brief channel</a>.</li>
<li><a target="_blank" href="https://www.wireshark.org/">Wireshark's website</a>.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Native Networking – How To Perform API Requests In React Native using the FetchAPI ]]>
                </title>
                <description>
                    <![CDATA[ APIs, or application program interfaces, are essential mechanisms for businesses in all industries. They allow for a secure exchange of data between two different systems, such as a web application and a database. Think of when you are using a mobile... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-native-networking-api-requests-using-fetchapi/</link>
                <guid isPermaLink="false">66d46194d7a4e35e384349c9</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kingsley Ubah ]]>
                </dc:creator>
                <pubDate>Fri, 20 Jan 2023 19:35:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/pexels-pixabay-276502--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>APIs, or application program interfaces, are essential mechanisms for businesses in all industries. They allow for a secure exchange of data between two different systems, such as a web application and a database.</p>
<p>Think of when you are using a mobile app to order food from a restaurant. The restaurant's menu, pricing, and ordering information could all be stored in a database that is managed by a back-end application.</p>
<p>To enable the mobile app to access the data, the app must make an API request to the back-end application. The request will include information such as the restaurant's location, the menu items, and the desired order.</p>
<p>The back-end application will then respond with the requested information. The mobile app can then use the data to create a user-friendly interface for ordering food.</p>
<p>API requests can also be used to update the database with new data, providing a way for the application to save and store new information. You can also set up with in-app subscription events. For example, when a user's subscription is about to expire, an API request is sent to a notification system to alert the them.</p>
<p>In this tutorial, you’ll learn how to make GET, POST, PUT and DELETE requests to APIs in a React Native app using the FetchAPI. You can access the full code from this tutorial <a target="_blank" href="https://snack.expo.dev/@ubahthebuilder/b61a85">here</a>.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow this tutorial, you’ll need just two things:</p>
<ul>
<li><p>A basic understanding of React Native</p>
</li>
<li><p><a target="_blank" href="https://snack.expo.dev/">Expo Snack</a></p>
</li>
</ul>
<p>Expo Snack is an online development environment for React Native which essentially lets you run React Native apps on your web browser. This removes the hassle of setting up your local React Native environment from scratch.</p>
<h2 id="heading-setting-up-the-app">Setting up the app</h2>
<p>Go to <a target="_blank" href="https://snack.expo.dev/">Expo Snack</a> to initialize a new React Native project, then go to the App.js file and clear the file’s content.</p>
<p>Start by importing React, useState, and useEffect hooks from React as well as the Text, View, and StyleSheet components from React Native.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{useState, useEffect} <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Text, View, StyleSheet } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
</code></pre>
<p>Next, define an App component function. Inside the function body, we set the data state to an empty array, the loading state to true, then we return a simple “Hello World” text for now.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState([]);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}
</code></pre>
<p>Later on, when we retrieve data from JSONPlaceholder API (see next section), we’ll populate out the data state with it and render the data from the App component as text.</p>
<h2 id="heading-the-api-well-be-working-with">The API we’ll be working with</h2>
<p>The API we’ll be fetching our data from is <a target="_blank" href="https://jsonplaceholder.typicode.com/">JSONPlaceholder.</a> This is a free fake API for testing and prototyping purposes.</p>
<p>The API comes with 6 common resources which you can read, edit, update or delete by making API requests.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/https___jsonplaceholder.typicode.com_posts-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Array of 100 post objects</em></p>
<p>So here each post is an object with four properties: userId, id, title and body. There are 100 objects in the array.</p>
<p>You can:</p>
<ul>
<li><p>create a new post by making a POST request to this API (that is, add a new object)</p>
</li>
<li><p>read a specific post by making a GET request to this API (that is, read an object)</p>
</li>
<li><p>update an existing post by making a PUT request to this API (that is, modify an object)</p>
</li>
<li><p>delete an existing post by making a DELETE request to this API (that is, remove an object)</p>
</li>
</ul>
<p>Let’s start with making GET requests in our React Native app.</p>
<h2 id="heading-how-to-make-a-get-request-in-react-native">How to Make a GET Request in React Native</h2>
<p>An API GET request is a type of API request used to retrieve data from a server. The request is sent via a HTTP GET method and data is returned in the form of a JSON or XML object.</p>
<p>Let’s make a GET request in our React Native app. First, store the URL you want to make the request to inside a variable (paste this code under state variable declaration):</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> url = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>
</code></pre>
<p>Next, use the fetch method to execute the API request to the URL. Wrap the fetch inside of useEffect (this hook allows us to perform side effects in our code, for example API calls):</p>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
  fetch(url)
    .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
    .then(<span class="hljs-function">(<span class="hljs-params">json</span>) =&gt;</span> setData(json))
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(error))
    .finally(<span class="hljs-function">() =&gt;</span> setLoading(<span class="hljs-literal">false</span>));
}, []);
</code></pre>
<p>So what’s happening here inside <code>useEffect</code>? First we make a GET call to the URL. Once the data is returned, we parse it to JSON with <code>resp.json()</code>, and in the next <code>then</code> block we call <code>setData</code> to update the state with the post.</p>
<p>In the event of any error, the <code>catch</code> method will run (which logs the error to the console). Finally, we set the loading state to <code>false</code>.</p>
<p>Finally, we render the post gotten from the API:</p>
<pre><code class="lang-js">&lt;View style={styles.container}&gt;
  {loading ? (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span></span>
  ) : (
    data.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.title}</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>{post.body}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
      );
    })
  )}
&lt;/View&gt;;
</code></pre>
<p>So if the API request is still in progress, we show the “Loading” text on our app. Once the data is retrieved, we loop through the array and render the title and text of each post.</p>
<p>To style it up a bit, paste the following stylesheet underneath App:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"center"</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#ecf0f1"</span>,
    <span class="hljs-attr">padding</span>: <span class="hljs-number">8</span>,
  },
  <span class="hljs-attr">title</span>: {
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">fontWeight</span>: <span class="hljs-string">"bold"</span>,
  },
});
</code></pre>
<p>Here’s the result when the posts are returned from the API.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/vigorous-carrot---Snack.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Final look</em></p>
<p>As you can see, we successfully fetched the list of posts from the API and rendered each of them in our React Native app.</p>
<p>Now if you want to retrieve a specific resource (like a specific post) as opposed to a collection of resources like a list of posts, all you need to do is add the resource ID to the URL like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> url = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts/1"</span>
</code></pre>
<p>If we make a GET request to the above API endpoint, the server will only gives us back the post with an ID of 1.</p>
<p>Let’s move on to other types of requests.</p>
<h2 id="heading-how-to-make-a-post-request-in-react-native">How to Make a POST Request in React Native</h2>
<p>An API POST request is a type of API request that is used to create or update a resource on a web server.</p>
<p>It sends data to the server in the form of a request body which usually contains information such as the title, description, and other relevant details. If the data is accepted, the server responds with a success code and the resource is created or updated.</p>
<p>When making a POST request with the FetchAPI, you must specify the method as ‘POST’. Here’s an example of a POST to the fake server from our React Native app:</p>
<pre><code class="lang-js">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>,
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">userId</span>: <span class="hljs-number">55</span>,
    <span class="hljs-attr">id</span>: <span class="hljs-number">101</span>,
    <span class="hljs-attr">title</span>: <span class="hljs-string">"Post title"</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-string">"Post body"</span>,
  }),
})
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.json())
  .then(<span class="hljs-function">(<span class="hljs-params">responseData</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(responseData));
  })
  .done();
</code></pre>
<p>The value of the body property must always be a JSON object with JSON string values (hence the <code>JSON.stringify</code> call).</p>
<p>Once the server is done processing the request, it sends back a response to tell you if the resource was created on the server or not (and why it failed).</p>
<h2 id="heading-how-to-make-a-put-request-in-react-native">How to Make a PUT Request in React Native</h2>
<p>If a POST request is used to create a new resource on a server, a PUT request is used to update a specific resource on that server.</p>
<p>In a PUT request, you need to specify the ID of the resource you want to update on the server as well as the new values. Here’s an example which updates the title and body of post one on the server:</p>
<pre><code class="lang-js">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts/1"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"PUT"</span>,
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">userId</span>: <span class="hljs-number">55</span>,
    <span class="hljs-attr">id</span>: <span class="hljs-number">101</span>,
    <span class="hljs-attr">title</span>: <span class="hljs-string">"New Post title"</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-string">"New Post body"</span>,
  }),
})
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.json())
  .then(<span class="hljs-function">(<span class="hljs-params">responseData</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(responseData));
  })
  .done();
</code></pre>
<p>Similar to a POST request, the server sends back a response to tell you if the resource was updated on the server or not (and why it failed).</p>
<h2 id="heading-how-to-make-a-delete-request-in-react-native">How to Make a DELETE Request in React Native</h2>
<p>As you might have guessed, a DELETE request is used to delete a specific resource from a server.</p>
<p>In a DELETE request, you only specify the ID of resource you want to delete on the server:</p>
<pre><code class="lang-js">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts/1"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"DELETE"</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>,
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
})
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.json())
  .then(<span class="hljs-function">(<span class="hljs-params">responseData</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(responseData));
  })
  .done();
</code></pre>
<p>Once the server is done with processing the request, it sends back a response to tell you if the resource was deleted on the server or not (and why it failed).</p>
<h2 id="heading-how-to-integrate-other-third-party-apis-to-react-native">How to Integrate Other Third-Party APIs to React Native</h2>
<p>Third-party APIs are created and maintained by organizations other than the main developer of the application. They are used to provide access to certain external data sources so that developers can incorporate them into their applications.</p>
<p>With the widespread use of React Native for developing mobile applications, third-party APIs can be easily integrated to create powerful and feature-rich applications.</p>
<p>One of the main benefits of using third-party APIs is that they are often updated frequently, which means that the developers can quickly access the latest features and data sources. This can be especially useful when developing mobile applications, as they often require access to the latest features and data sources.</p>
<p>Additionally, you can also use third-party APIs to add features that are hard or impossible to create in-house as it requires substantial human, financial, and time resources.</p>
<p>For example, there are complex APIs for <a target="_blank" href="https://developers.facebook.com/docs/facebook-login/web/">Facebook login</a>, <a target="_blank" href="https://stripe.com/docs/api">payment processing</a>, <a target="_blank" href="https://openweathermap.org/api">weather report</a>, <a target="_blank" href="https://adapty.io/blog/react-native-in-app-purchases-implementation-tutorial">integrating in-app purchases infrastructure</a>, and so on.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This tutorial walked you through the steps of making API requests in React Native using the built-in Fetch library.</p>
<p>I hope you enjoyed this as much as I did writing it. Have a great week.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Handle Errors in Computer Networks ]]>
                </title>
                <description>
                    <![CDATA[ There are some magical things about the Internet, and one thing in particular is that it works. In spite of so many obstacles, we can deliver our packets over the globe, and do so fast. Even more specifically, one amazing thing about the Internet is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-handle-errors-in-computer-networks/</link>
                <guid isPermaLink="false">66c17c3858ee0865d2671b5d</guid>
                
                    <category>
                        <![CDATA[ computer network ]]>
                    </category>
                
                    <category>
                        <![CDATA[ computer networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ error ]]>
                    </category>
                
                    <category>
                        <![CDATA[ error handling ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Omer Rosenbaum ]]>
                </dc:creator>
                <pubDate>Wed, 18 Jan 2023 16:05:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/Copy-of-Computer-Networks-Hub-Switch.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>There are some magical things about the Internet, and one thing in particular is that it works. In spite of so many obstacles, we can deliver our packets over the globe, and do so fast.</p>
<p>Even more specifically, one amazing thing about the Internet is its ability to handle errors. </p>
<p>What do I mean by errors? When a packet or a frame is received by a machine, we say it contains an error if the data that had been sent is not the data that was received. For instance, a single <code>1</code> was mistakenly received as a <code>0</code> after its transmission. </p>
<p>This can happen due to many different reasons. Perhaps there was some disturbance in the wire where the data was transmitted – say, a child rode her bicycle over the wire. Perhaps there was some collision in the air as many people transmitted at once. Maybe it was a device's error.</p>
<p>Regardless of the specific reason, you still get valid data on the Internet. Without handling errors, you may read the last sentence and instead of <code>errors</code> read <code>errbbb</code>. Weird, isn't it? So how does the Internet handle errors?</p>
<p>There are two main approaches for handling errors – detection, and correction. We shall start by describing detection, and then talk about correction.</p>
<h1 id="heading-what-is-error-detection">What is Error Detection?</h1>
<p>When dealing with error detection, we are looking for a boolean result – <code>True</code>, or <code>False</code>. Is the frame/packet valid, or not. That is all. We don’t want to know where the error occurred. If the frame is invalid, we will simply drop it.</p>
<p>So when the receiver receives a frame, they will determine whether an error has occurred. If the frame is valid, they will read it. If the frame contains errors - the receiver will drop it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-84.png" alt="Image" width="600" height="400" loading="lazy">
_Error Detection: we only want to know if the frame/packet is valid or not. (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>One method for error detection is using a <strong>checksum</strong>. A common implementation of a checksum is called <strong>CRC – Cyclic Redundancy Check</strong>. </p>
<p>In this post we will not trouble ourselves with the mathematical implementation of CRCs in the real world (if you're interested, check out <a target="_blank" href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">Wikipedia</a>). Rather, we'll simply try to understand the concept. To do so, let’s implement a very simple checksum mechanism ourselves.</p>
<p>Consider a protocol for transmitting 10-digit phone numbers between endpoints. This protocol is extremely simple: each packet includes exactly 10 bytes, each one representing a digit. For example, a packet might include the following digits:</p>
<p><code>5551234567</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-85.png" alt="Image" width="600" height="400" loading="lazy">
_A packet with a payload of 10 digits (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>For simplicity's sake, we will omit the headers of the packet and focus solely on the payload. </p>
<p>Now, we will add a checksum. Say that we <strong>add</strong> all the digits. So in this example, we would calculate <code>5</code> + <code>5</code> +<code>5</code> +<code>1</code>+… all the way through <code>7</code>. We would get <code>43</code>. This would be our checksum value.</p>
<p>Now, the sender won’t only send the phone number, but also the checksum value right after it. In this example, the sender would send:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-86.png" alt="Image" width="600" height="400" loading="lazy">
_The packet's data is followed by a checksum. (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Now, as the receiver, you can do the same thing. You will read the phone number, and calculate the checksum. You will add the digits, and get <code>43</code>. </p>
<p>Since you've received the correct result (that is, your calculation based on the data matches the checksum value sent in the packet), you can assume that the frame is valid.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-89.png" alt="Image" width="600" height="400" loading="lazy">
_The sender compares their calculated checksum value and the checksum in the packet. If the values match, the packet is assumed to be valid (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>What happens in case of an error? 🤔</p>
<p>Let’s say, for instance, that the digit <code>2</code> was replaced by an <code>8</code>. Now, even though the sender sent the same stream as before ( <code>555123456743</code> ), you, as the receiver, see something a bit different:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-90.png" alt="Image" width="600" height="400" loading="lazy">
_A packet containing an error (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Now, you are calculating the checksum, adding all the digits. You get <code>49</code>. Since this value is different from the checksum value specified in the original frame, <code>43</code>, the frame is considered to be invalid and you drop it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-91.png" alt="Image" width="600" height="400" loading="lazy">
_The sender compares their calculated checksum value and the checksum in the packet. If the values don't match, the packet is assumed to be invalid (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Are there problems with this method? 🤔</p>
<p>Yes, there are. Consider, for example, what happens if there are two errors – and instead of the original stream ( <code>555123456743</code> ), you receive the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-92.png" alt="Image" width="600" height="400" loading="lazy">
_A packet received with two errors, resulting in the stream <code>456123456743</code> (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>What happens when you add the digits?</p>
<p>Even though the digits are not the same as the original packet, the checksum will remain correct, and the frame will be regarded as valid.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-93.png" alt="Image" width="600" height="400" loading="lazy">
_Despite the errors, the checksum value happens to be correct, resulting in a false assumption that the packet is valid (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Real checksum functions, such as CRCs, are of course much better implemented than the one in our example – but in extremely rare cases, such problems may occur. </p>
<p>Notice that using this kind of method, error detection, we don’t know where the problem occurred, but only whether the frame is valid or not. If the checksum value is invalid, we assume that the frame is invalid and drop it.</p>
<h1 id="heading-what-is-error-correction">What is Error Correction?</h1>
<p>As mentioned earlier, detection is not the only way to handle errors. Another approach might be to find the error and correct it. How can we do that?</p>
<p>An extremely simple way would be to transmit the data many times – let’s say, three times. For example, the stream <code>5551234567</code> would be transmitted as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-94.png" alt="Image" width="600" height="400" loading="lazy">
_Sending the same data multiple times (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>So we basically sent the data three times.</p>
<p>Now, in case of an error in one digit, the receiver can look at the other two digits, and choose the one that appears two times out of three.</p>
<p>So, for instance, if we had a problem and <code>2</code> was replaced with an <code>8</code>, the receiver would get this stream:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-95.png" alt="Image" width="600" height="400" loading="lazy">
_An error in one of the occurrences of the data (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Now, as a receiver, you can say: “I have <code>2</code>, <code>8</code>, <code>2</code>… so it was probably <code>2</code> in the original message”.</p>
<p>Is this problematic? Well, in some rare cases, we might get the same error twice. So it is possible, even though unlikely, that two of the original twos have been received as eights.</p>
<p>So while the sender sent this stream:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-94.png" alt="Image" width="600" height="400" loading="lazy">
_Sending the same data multiple times (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>The first <code>2</code> was mistakenly read as an <code>8</code>, and also the second <code>2</code> was received as an <code>8</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-96.png" alt="Image" width="600" height="400" loading="lazy">
_Two identical errors; Rare, but possible (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p> Now, it looks as if the original message included an <code>8</code>, and not a <code>2</code>.</p>
<p>What can you do in order to lower the probability of such scenario?</p>
<p>The most simple solution would be to simply send the data even more times. Let’s say, five times. So now we duplicate all the data, and send it 5 times in total… </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-97.png" alt="Image" width="600" height="400" loading="lazy">
_Sending the data five(!) times (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Now, say that two errors occurred, and again two of the <code>2</code> digits were replaced with <code>8</code>s.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-98.png" alt="Image" width="600" height="400" loading="lazy">
_Two identical errors; Rare, but possible (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Clearly, it is very unlikely to get the same error twice, but even in this case, we still get <code>2</code> three times, so as the receiver you can tell, with a high probability, that the original message contained a <code>2</code>, rather than an <code>8</code>.</p>
<h2 id="heading-whats-the-overhead">What's the Overhead?</h2>
<p>Now would be a good time to introduce the term <strong>overhead</strong>. When we say overhead, we basically mean data or time needed to convey the actual message. Let’s first understand what this term means in general, and then consider it in the context of handling errors.</p>
<p>Let’s say that I have a lesson to teach in my university. My goal is to teach the lesson itself, which is also called the <strong>payload</strong> in that context – that is, the actual data or message I would like to convey.</p>
<p>In order to teach the lesson, or to convey the payload, I first have to physically get to the university – so I get out of my home, walk to the bus station, wait for the bus, take the bus, get off the bus, walk to the building, wait for the lesson to start – and only then do I actually get to teach the lesson. </p>
<p>This entire process is <strong>overhead</strong> that I have to pay in order to deliver the <strong>payload</strong>, in this case – to teach the lesson.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-99.png" alt="Image" width="600" height="400" loading="lazy">
_Overhead and Payload are two extremely important terms in Computer Networks (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>The same applies in computer networks. Our <strong>payload</strong> is the data, and there is always some <strong>overhead</strong> associated with sending it. </p>
<h2 id="heading-back-to-handling-errors">Back to Handling Errors</h2>
<p>In the context here – sending the data three times, as suggested earlier, means that for every byte of payload we have two bytes of overhead. If we send the data five times, then for every byte of payload, we have four bytes of overhead. That’s a LOT!</p>
<p>Consider error <em>detection</em>, on the other hand. In our example protocol for sending phone numbers, how much overhead did we have?</p>
<p>Recall that for every ten-digit phone number, that is ten bytes, we included a two-digit checksum value. In other words, we had two bytes of overhead for ten bytes of payload. It is clear that in our example, error detection yields much smaller overhead in comparison to error correction.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-100.png" alt="Image" width="600" height="400" loading="lazy">
_In the sample protocol, for every ten-digit phone number (ten bytes of payload), we included a two-digit checksum value (two bytes of overhead) (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>There are better ways to achieve error correction with high accuracy than to simply send the data so many times, but they are more complicated and out of scope for this post. Even with very complicated error correction techniques, they still require lots of overhead when compared to error detection.</p>
<p>Also, notice that except for the bytes sent as overhead in case of error correction, error detection is much simpler. </p>
<h1 id="heading-error-correction-vs-error-detection-which-is-better">Error Correction vs Error Detection – Which is Better?</h1>
<p>We already concluded that error detection is simpler, and with a smaller payload compared to error correction.</p>
<h3 id="heading-so-when-would-we-prefer-error-correction">So, when would we prefer error correction?</h3>
<p>One case might be when we have a one-way link. That is, a network where we can only transfer data in one direction. </p>
<p>For example, say you have a secret agent that you need to send a message to. The agent knows that they need to look up to the sky at exactly midnight, and they will see a series of flashes indicating the secret message. </p>
<p>The secret agent cannot reply, or their location and identity will be revealed. In addition, you don’t want to send the message over and over again, as not to draw much attention, and to make it harder for someone to intercept the message.</p>
<p>In this case, you definitely want your agent to receive the exact message that you’ve sent. Consider a case where you want to send them the message “do not place the bomb”. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-101.png" alt="Image" width="600" height="400" loading="lazy">
_A sensitive message for a secret agent (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>Of course, you don’t want to risk the unfortunate scenario of the agent reading the message as “do <strong>now</strong> place the bomb”, due to an error.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-102.png" alt="Image" width="600" height="400" loading="lazy">
_An error may change the meaning of the message substantially (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>If you use error <em>detection</em>, the agent might be aware that the message they received is invalid in case of an error, but they won’t be able to tell you that they need you to send the message again. As you want the agent to be able to read your message correctly and without sending any data back to us, error correction is preferred.</p>
<p>So, one-way link is one case where we prefer error correction. What about other cases?</p>
<p>Sometimes you just <em>can’t</em> send the data again, perhaps because it has been erased from the memory of your machine. That is, the data is deleted right after it has been sent. In this case, you'd clearly prefer error correction, as sending the data again, as we would do with error detection, is just impossible.</p>
<p>Also, if sending the data again is possible, but extremely expensive, error correction may be preferable. </p>
<p>For example, if you send a message to the moon, say, with a spaceship – it might be really expensive to send it over again in case of an error. Using error correction, you send the data only once and the receiver should be able to deal with it, even if an error occurred.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-103.png" alt="Image" width="600" height="400" loading="lazy">
_Cases where correction is preferred (<a target="_blank" href="https://www.youtube.com/watch?v=H_bYtVDF6T4&amp;ab_channel=Brief">Source: Brief</a>)_</p>
<p>In general, we prefer error correction when retransmitting the data is costly or impossible. </p>
<h3 id="heading-when-would-we-prefer-error-detection">When would we prefer error detection?</h3>
<p>Well, in case we can retransmit the data, we usually prefer error detection since it comes with very little overhead compared to error correction. Especially, when sending the data is relatively cheap.</p>
<p>For example, on the Internet, if an error occurs when you send a frame, no problem – you can simply send it again! </p>
<p>For example, when I covered <a target="_blank" href="https://www.freecodecamp.org/news/the-complete-guide-to-the-ethernet-protocol/">the Ethernet protocol in a previous post</a>, I mentioned that Ethernet protocol uses change detection, namely <code>CRC32</code> – that is, 32 bits (or 4 bytes) of a checksum for every frame. </p>
<p>Note that it doesn’t mean that error detection is simply better. It just better fits the Internet than error correction. As mentioned before, error correction is preferable in other cases.</p>
<h1 id="heading-wrapping-up">Wrapping Up</h1>
<p>In this tutorial, we discussed various methods for handling errors. We looked at <strong>error detection</strong>, where we only know whether a frame is valid or not. We also considered <strong>error correction</strong>, where the receiver can restore the correct value of an erroneous frame. We also introduced the term <strong>overhead</strong>. </p>
<p>We then understood why we use error detection on the Internet, rather than error correction. Stay tuned for more posts in this series about Computer Networks 💪🏻</p>
<h2 id="heading-about-the-author"><strong>About the Author</strong></h2>
<p><a target="_blank" href="https://www.linkedin.com/in/omer-rosenbaum-034a08b9/">Omer Rosenbaum</a> is <a target="_blank" href="https://swimm.io/">Swimm</a>’s Chief Technology Officer. He's the author of the Brief <a target="_blank" href="https://youtube.com/@BriefVid">YouTube Channel</a>. He's also a cyber training expert and founder of Checkpoint Security Academy. He's the author of <a target="_blank" href="https://data.cyber.org.il/networks/networks.pdf">Computer Networks (in Hebrew)</a>. You can find him on <a target="_blank" href="https://twitter.com/Omer_Ros">Twitter</a>.</p>
<h2 id="heading-additional-resources"><strong>Additional Resources</strong></h2>
<ul>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PL9lx0DXCC4BMS7dB7vsrKI5wzFyVIk2Kg">Computer Networks Playlist - on my Brief channel</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC - Wikipedia</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/the-complete-guide-to-the-ethernet-protocol/">The Complete Guide to Ethernet Protocol</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
