Golang http ServeContent Function

The http.ServeContent function in Golang is part of the net/http package and is used to serve content directly from a given io.ReadSeeker, such as a file, with detailed control over the HTTP headers like Content-Type, Content-Length, and Last-Modified. This function is useful when you need to serve content that is dynamically generated or read from a non-file source but still want to provide the appropriate HTTP headers.

Table of Contents

  1. Introduction
  2. http.ServeContent Function Syntax
  3. Examples
    • Basic Usage
    • Serving Dynamic Content with Custom Headers
    • Serving a File with Custom HTTP Headers
  4. Real-World Use Case
  5. Conclusion

Introduction

The http.ServeContent function allows you to serve content with precise control over the HTTP response headers. Unlike http.ServeFile, which serves files directly from the filesystem, http.ServeContent allows you to serve content from any io.ReadSeeker source, such as an in-memory buffer or a dynamically generated stream. This function is particularly useful when you need to customize the response headers or serve content that is not stored as a file on disk.

http.ServeContent Function Syntax

The syntax for the http.ServeContent function is as follows:

func ServeContent(w http.ResponseWriter, r *http.Request, name string, modtime time.Time, content io.ReadSeeker)

Parameters:

  • w: The http.ResponseWriter used to write the HTTP response.
  • r: The *http.Request representing the incoming HTTP request.
  • name: A string specifying the name of the content being served (used to determine the Content-Type).
  • modtime: A time.Time value representing the last modification time of the content, used to set the Last-Modified header.
  • content: An io.ReadSeeker representing the content to be served. This could be a file, a buffer, or any other readable and seekable data source.

Returns:

  • The function does not return any value. It writes the content directly to the HTTP response.

Examples

Basic Usage

This example demonstrates how to use the http.ServeContent function to serve content from a file with custom control over the response headers.

Example

package main

import (
	"net/http"
	"os"
	"time"
)

func main() {
	// Register a handler for serving content
	http.HandleFunc("/content", func(w http.ResponseWriter, r *http.Request) {
		// Open the file to be served
		file, err := os.Open("example.txt")
		if err != nil {
			http.Error(w, "File not found", http.StatusNotFound)
			return
		}
		defer file.Close()

		// Get the file information to obtain the modification time
		fileInfo, err := file.Stat()
		if err != nil {
			http.Error(w, "Could not get file info", http.StatusInternalServerError)
			return
		}

		// Serve the file content with http.ServeContent
		http.ServeContent(w, r, fileInfo.Name(), fileInfo.ModTime(), file)
	})

	// Start the server on port 8080
	http.ListenAndServe(":8080", nil)
}

Explanation:

  • The code opens a file (example.txt) and serves its content using http.ServeContent.
  • The ServeContent function sets appropriate headers such as Content-Type, Content-Length, and Last-Modified based on the file's metadata.

Serving Dynamic Content with Custom Headers

This example shows how to serve dynamically generated content with custom headers using http.ServeContent.

Example

package main

import (
	"bytes"
	"net/http"
	"time"
)

func main() {
	// Register a handler for serving dynamic content
	http.HandleFunc("/dynamic", func(w http.ResponseWriter, r *http.Request) {
		// Generate dynamic content
		content := "Hello, this is dynamically generated content."
		contentReader := bytes.NewReader([]byte(content))

		// Serve the content with a custom modification time
		http.ServeContent(w, r, "dynamic.txt", time.Now(), contentReader)
	})

	// Start the server on port 8080
	http.ListenAndServe(":8080", nil)
}

Explanation:

  • The example generates dynamic content in memory and serves it using http.ServeContent.
  • A bytes.Reader is used as the io.ReadSeeker to serve the content, with a custom modification time set to the current time.

Serving a File with Custom HTTP Headers

This example demonstrates how to serve a file while customizing HTTP headers like Content-Disposition.

Example

package main

import (
	"net/http"
	"os"
	"time"
)

func main() {
	// Register a handler for serving a file with custom headers
	http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
		// Open the file to be served
		file, err := os.Open("example.pdf")
		if err != nil {
			http.Error(w, "File not found", http.StatusNotFound)
			return
		}
		defer file.Close()

		// Get the file information
		fileInfo, err := file.Stat()
		if err != nil {
			http.Error(w, "Could not get file info", http.StatusInternalServerError)
			return
		}

		// Set a custom Content-Disposition header
		w.Header().Set("Content-Disposition", "attachment; filename=\"example.pdf\"")

		// Serve the file content
		http.ServeContent(w, r, fileInfo.Name(), fileInfo.ModTime(), file)
	})

	// Start the server on port 8080
	http.ListenAndServe(":8080", nil)
}

Explanation:

  • The code serves a PDF file (example.pdf) and sets a Content-Disposition header to prompt the user to download the file.
  • http.ServeContent handles the content delivery, while the custom header ensures the file is presented as a download.

Real-World Use Case

Serving Video Content with Custom HTTP Headers

In real-world applications, http.ServeContent can be used to serve video content while providing appropriate headers for streaming, such as Content-Range and Accept-Ranges.

Example: Serving Video with Streaming Support

package main

import (
	"net/http"
	"os"
	"time"
)

func main() {
	// Register a handler for serving video content
	http.HandleFunc("/video", func(w http.ResponseWriter, r *http.Request) {
		// Open the video file to be served
		videoFile, err := os.Open("video.mp4")
		if err != nil {
			http.Error(w, "Video file not found", http.StatusNotFound)
			return
		}
		defer videoFile.Close()

		// Get the file information
		fileInfo, err := videoFile.Stat()
		if err != nil {
			http.Error(w, "Could not get video file info", http.StatusInternalServerError)
			return
		}

		// Serve the video content with streaming support
		http.ServeContent(w, r, fileInfo.Name(), fileInfo.ModTime(), videoFile)
	})

	// Start the server on port 8080
	http.ListenAndServe(":8080", nil)
}

Explanation:

  • The code serves a video file (video.mp4) using http.ServeContent, allowing clients to stream the video with support for range requests.
  • The function handles setting the appropriate headers for video streaming, such as Accept-Ranges and Content-Range.

Conclusion

The http.ServeContent function in Go is used for serving content with fine-grained control over the HTTP response headers. It is particularly useful when you need to serve dynamically generated content, non-file content, or files with custom HTTP headers. By leveraging http.ServeContent, you can provide a robust and flexible solution for delivering content over HTTP, ensuring that the appropriate metadata and headers are included in the response.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare