http-https

star 2

HTTP/HTTPS protocol implementation and best practices

ffsshhttiikk By ffsshhttiikk schedule Updated 2/28/2026

name: http-https description: HTTP/HTTPS protocol implementation and best practices category: networking difficulty: intermediate tags: [http, https, protocol, web, rest] author: OpenCode Community version: 1.0 last_updated: 2024-01-15

HTTP/HTTPS Protocols

What I Do

I am HTTP/HTTPS, the application layer protocol enabling communication between clients and servers on the World Wide Web. I define the rules for requesting and transferring web resources through methods (GET, POST, PUT, DELETE, etc.), status codes, headers, and message bodies. HTTPS adds Transport Layer Security (TLS) encryption to protect data in transit. I support persistent connections, chunked transfer encoding, content negotiation, and caching mechanisms. HTTP/2 and HTTP/3 introduce multiplexing, header compression, and server push for improved performance. I form the foundation for RESTful APIs, web services, and modern web applications.

When to Use Me

  • Building RESTful APIs and web services
  • Client-server communication in web applications
  • Implementing microservices architecture
  • Webhook and callback integrations
  • File upload and download services
  • Real-time communication (WebSocket, Server-Sent Events)
  • API authentication and authorization
  • Content delivery and caching strategies

Core Concepts

HTTP Methods: GET (retrieve), POST (create), PUT (update), PATCH (partial update), DELETE (remove).

Status Codes: 1xx (informational), 2xx (success), 3xx (redirection), 4xx (client error), 5xx (server error).

Headers: Metadata controlling caching, authentication, content type, and request behavior.

Body/Payload: Request or response content in various formats (JSON, XML, multipart, streaming).

Cookies and Sessions: State management across HTTP requests.

Caching: Headers (Cache-Control, ETag, Last-Modified) controlling response caching.

Content Negotiation: Headers (Accept, Accept-Language) for format and language preferences.

HTTPS/TLS: Encryption, certificate validation, and secure communication.

Code Examples

Example 1: HTTP Client with Retry and Circuit Breaker (Go)

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "math"
    "net/http"
    "sync"
    "time"
)

type HTTPClient struct {
    client          *http.Client
    baseURL         string
    defaultTimeout  time.Duration
    retryConfig     RetryConfig
    circuitBreaker  *CircuitBreaker
}

type RetryConfig struct {
    MaxRetries     int
    InitialDelay   time.Duration
    MaxDelay       time.Duration
    Multiplier     float64
}

type CircuitBreaker struct {
    name            string
    failureCount    int
    failureThreshold int
    resetTimeout    time.Duration
    lastFailure     time.Time
    state           string // closed, open, half-open
    mutex           sync.RWMutex
}

func NewHTTPClient(baseURL string, timeout time.Duration) *HTTPClient {
    return &HTTPClient{
        client: &http.Client{
            Timeout: timeout,
            Transport: &http.Transport{
                MaxIdleConns:        100,
                MaxIdleConnsPerHost:  10,
                IdleConnTimeout:      90 * time.Second,
                MaxConnsPerHost:      100,
            },
        },
        baseURL:        baseURL,
        defaultTimeout: timeout,
        retryConfig: RetryConfig{
            MaxRetries:   3,
            InitialDelay: 100 * time.Millisecond,
            MaxDelay:      10 * time.Second,
            Multiplier:    2.0,
        },
        circuitBreaker: &CircuitBreaker{
            name:            "http-circuit-breaker",
            failureThreshold: 5,
            resetTimeout:    30 * time.Second,
            state:           "closed",
        },
    }
}

func (c *HTTPClient) Get(ctx context.Context, endpoint string, headers map[string]string) (*HTTPResponse, error) {
    return c.doRequest(ctx, http.MethodGet, endpoint, nil, headers)
}

func (c *HTTPClient) Post(ctx context.Context, endpoint string, body interface{}, headers map[string]string) (*HTTPResponse, error) {
    return c.doRequest(ctx, http.MethodPost, endpoint, body, headers)
}

func (c *HTTPClient) Put(ctx context.Context, endpoint string, body interface{}, headers map[string]string) (*HTTPResponse, error) {
    return c.doRequest(ctx, http.MethodPut, endpoint, body, headers)
}

func (c *HTTPClient) Delete(ctx context.Context, endpoint string, headers map[string]string) (*HTTPResponse, error) {
    return c.doRequest(ctx, http.MethodDelete, endpoint, nil, headers)
}

func (c *HTTPClient) doRequest(ctx context.Context, method, endpoint string, body interface{}, headers map[string]string) (*HTTPResponse, error) {
    if !c.circuitBreaker.canExecute() {
        return nil, fmt.Errorf("circuit breaker is open")
    }
    
    var bodyReader io.Reader
    if body != nil {
        jsonBody, err := json.Marshal(body)
        if err != nil {
            return nil, fmt.Errorf("failed to marshal request body: %w", err)
        }
        bodyReader = bytes.NewReader(jsonBody)
        if headers == nil {
            headers = make(map[string]string)
        }
        headers["Content-Type"] = "application/json"
    }
    
    url := c.baseURL + endpoint
    req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
    if err != nil {
        return nil, fmt.Errorf("failed to create request: %w", err)
    }
    
    for key, value := range headers {
        req.Header.Set(key, value)
    }
    
    var lastErr error
    var response *http.Response
    
    delay := c.retryConfig.InitialDelay
    
    for attempt := 0; attempt <= c.retryConfig.MaxRetries; attempt++ {
        response, lastErr = c.client.Do(req)
        
        if lastErr == nil {
            break
        }
        
        if attempt == c.retryConfig.MaxRetries {
            c.circuitBreaker.recordFailure()
            return nil, fmt.Errorf("request failed after %d attempts: %w", c.retryConfig.MaxRetries, lastErr)
        }
        
        select {
        case <-ctx.Done():
            return nil, ctx.Err()
        case <-time.After(delay):
        }
        
        delay = time.Duration(float64(delay) * c.retryConfig.Multiplier)
        delay = time.Duration(math.Min(float64(delay), float64(c.retryConfig.MaxDelay)))
    }
    
    defer response.Body.Close()
    
    responseBody, err := io.ReadAll(response.Body)
    if err != nil {
        return nil, fmt.Errorf("failed to read response body: %w", err)
    }
    
    httpResponse := &HTTPResponse{
        StatusCode: response.StatusCode,
        Headers:    response.Header,
        Body:       responseBody,
    }
    
    if response.StatusCode >= 400 {
        c.circuitBreaker.recordFailure()
        return httpResponse, fmt.Errorf("HTTP error %d: %s", response.StatusCode, string(responseBody))
    }
    
    c.circuitBreaker.recordSuccess()
    return httpResponse, nil
}

func (cb *CircuitBreaker) canExecute() bool {
    cb.mutex.RLock()
    defer cb.mutex.RUnlock()
    
    if cb.state == "open" {
        if time.Since(cb.lastFailure) > cb.resetTimeout {
            cb.mutex.RUnlock()
            cb.mutex.Lock()
            cb.state = "half-open"
            cb.mutex.Unlock()
            cb.mutex.RLock()
        }
    }
    return cb.state != "open"
}

func (cb *CircuitBreaker) recordFailure() {
    cb.mutex.Lock()
    defer cb.mutex.Unlock()
    
    cb.failureCount++
    cb.lastFailure = time.Now()
    
    if cb.failureCount >= cb.failureThreshold {
        cb.state = "open"
    }
}

func (cb *CircuitBreaker) recordSuccess() {
    cb.mutex.Lock()
    defer cb.mutex.Unlock()
    
    cb.failureCount = 0
    cb.state = "closed"
}

type HTTPResponse struct {
    StatusCode int
    Headers    http.Header
    Body       []byte
}

func (r *HTTPResponse) UnmarshalJSON(v interface{}) error {
    return json.Unmarshal(r.Body, v)
}

Example 2: Middleware-Based HTTP Server (Node.js)

const http = require('http');

class HTTPMiddleware {
    constructor() {
        this.middleware = [];
    }
    
    use(fn) {
        this.middleware.push(fn);
        return this;
    }
    
    async handle(request, response) {
        const context = {
            request,
            response,
            state: {},
            status: 200
        };
        
        for (const fn of this.middleware) {
            await fn(context);
            
            if (context.response.writableEnded) {
                return;
            }
            
            if (context.status >= 400) {
                break;
            }
        }
        
        if (!context.response.writableEnded) {
            response.statusCode = context.status;
            response.end(JSON.stringify(context.body || {}));
        }
    }
}

class HTTPServer {
    constructor(port = 3000) {
        this.port = port;
        this.middleware = new HTTPMiddleware();
        this.routes = new Map();
        this.server = null;
    }
    
    use(fn) {
        this.middleware.use(fn);
        return this;
    }
    
    get(path, handler) {
        this.addRoute('GET', path, handler);
        return this;
    }
    
    post(path, handler) {
        this.addRoute('POST', path, handler);
        return this;
    }
    
    put(path, handler) {
        this.addRoute('PUT', path, handler);
        return this;
    }
    
    delete(path, handler) {
        this.addRoute('DELETE', path, handler);
        return this;
    }
    
    addRoute(method, path, handler) {
        const pattern = this.pathToRegex(path);
        this.routes.set(`${method}:${pattern}`, { pattern, handler });
    }
    
    pathToRegex(path) {
        const pattern = path
            .replace(/\//g, '\\/')
            .replace(/:(\w+)/g, '(?<$1>[^/]+)');
        return new RegExp(`^${pattern}$`);
    }
    
    findRoute(method, path) {
        for (const [key, route] of this.routes) {
            const [routeMethod, pattern] = key.split(':');
            if (routeMethod !== method) continue;
            
            const match = path.match(pattern);
            if (match) {
                return { handler: route.handler, params: match.groups };
            }
        }
        return null;
    }
    
    async handleRequest(req, res) {
        const url = new URL(req.url, `http://${req.headers.host}`);
        const route = this.findRoute(req.method, url.pathname);
        
        const context = {
            request: req,
            response: res,
            method: req.method,
            path: url.pathname,
            query: Object.fromEntries(url.searchParams),
            params: route?.params || {},
            body: null,
            status: 200
        };
        
        // Parse body for POST/PUT
        if (['POST', 'PUT', 'PATCH'].includes(req.method)) {
            await this.parseBody(req);
            context.body = req.body;
        }
        
        // Run middleware
        for (const fn of this.middleware.middleware) {
            await fn(context);
            if (res.writableEnded) return;
        }
        
        // Handle route
        if (route) {
            await route.handler(context);
        } else {
            context.status = 404;
            context.body = { error: 'Not Found' };
            res.statusCode = 404;
            res.end(JSON.stringify(context.body));
        }
    }
    
    async parseBody(req) {
        return new Promise((resolve) => {
            let body = '';
            req.on('data', chunk => body += chunk.toString());
            req.on('end', () => {
                try {
                    req.body = JSON.parse(body || '{}');
                } catch {
                    req.body = {};
                }
                resolve();
            });
        });
    }
    
    listen() {
        this.server = http.createServer(this.handleRequest.bind(this));
        this.server.listen(this.port, () => {
            console.log(`Server running on port ${this.port}`);
        });
        return this.server;
    }
}

// Usage
const app = new HTTPServer(3000);

// Logging middleware
app.use(async (ctx) => {
    console.log(`${ctx.method} ${ctx.path} - ${ctx.status}`);
});

// CORS middleware
app.use(async (ctx) => {
    ctx.response.setHeader('Access-Control-Allow-Origin', '*');
    ctx.response.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    ctx.response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
});

// Auth middleware
app.use(async (ctx) => {
    const auth = ctx.request.headers.authorization;
    if (!auth && !ctx.request.url.includes('/public')) {
        ctx.status = 401;
        ctx.body = { error: 'Unauthorized' };
    }
});

// Routes
app.get('/api/users', async (ctx) => {
    ctx.body = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
});

app.get('/api/users/:id', async (ctx) => {
    ctx.body = { id: ctx.params.id, name: `User ${ctx.params.id}` };
});

app.post('/api/users', async (ctx) => {
    ctx.body = { id: 3, ...ctx.body };
    ctx.status = 201;
});

app.listen();

Example 3: Secure HTTPS Server with TLS (Python)

import ssl
import http.server
import socketserver
import json
import os
from urllib.parse import urlparse, parse_qs
from typing import Dict, Any, Optional
from datetime import datetime

class HTTPSServer:
    def __init__(
        self,
        host: str = '0.0.0.0',
        port: int = 8443,
        cert_path: str = 'cert.pem',
        key_path: str = 'key.pem'
    ):
        self.host = host
        self.port = port
        self.cert_path = cert_path
        self.key_path = key_path
        self.routes: Dict[str, Dict[str, Any]] = {}
        self.middleware: list = []
        
    def route(self, path: str, methods: list = ['GET']):
        def decorator(func):
            self.routes[f"{methods[0]}:{path}"] = {
                'handler': func,
                'methods': methods
            }
            return func
        return decorator
    
    def use(self, middleware_func):
        self.middleware.append(middleware_func)
        return middleware_func
    
    def create_ssl_context(self) -> ssl.SSLContext:
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        context.load_cert_chain(self.cert_path, self.key_path)
        context.minimum_version = ssl.TLSVersion.TLSv1_3
        context.set_alpn_protocols(['h2', 'http/1.1'])
        context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
        return context
    
    def run(self):
        context = self.create_ssl_context()
        
        class RequestHandler(http.server.BaseHTTPRequestHandler):
            def log_message(self, format, *args):
                print(f"[{datetime.now().isoformat()}] {args[0]}")
            
            def do_method(self, method: str):
                parsed = urlparse(self.path)
                path = parsed.path
                query = parse_qs(parsed.query)
                
                handler_key = f"{method}:{path}"
                if handler_key not in self.server.routes:
                    self.send_error(404, 'Not Found')
                    return
                
                route = self.server.routes[handler_key]
                if method not in route['methods']:
                    self.send_error(405, 'Method Not Allowed')
                    return
                
                try:
                    # Read request body
                    content_length = int(self.headers.get('Content-Length', 0))
                    body = self.rfile.read(content_length) if content_length > 0 else None
                    
                    request_context = {
                        'method': method,
                        'path': path,
                        'query': query,
                        'body': json.loads(body.decode('utf-8')) if body else None,
                        'headers': dict(self.headers),
                        'params': {}
                    }
                    
                    # Run middleware
                    for middleware in self.server.middleware:
                        result = middleware(request_context)
                        if result and 'response' in result:
                            self.send_json_response(result['response'])
                            return
                    
                    # Handle route
                    response = route['handler'](request_context)
                    self.send_json_response(response)
                    
                except Exception as e:
                    self.send_json_response({'error': str(e)}, status=500)
            
            def do_GET(self):
                self.do_method('GET')
            
            def do_POST(self):
                self.do_method('POST')
            
            def do_PUT(self):
                self.do_method('PUT')
            
            def do_DELETE(self):
                self.do_method('DELETE')
            
            def send_json_response(self, data: dict, status: int = 200):
                response_body = json.dumps(data, default=str).encode('utf-8')
                self.send_response(status)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', len(response_body))
                self.send_header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
                self.end_headers()
                self.wfile.write(response_body)
        
        socketserver.TCPServer.allow_reuse_address = True
        with socketserver.TCPServer((self.host, self.port), RequestHandler) as httpd:
            httpd.routes = self.routes
            httpd.middleware = self.middleware
            print(f"HTTPS Server running on https://{self.host}:{self.port}")
            httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
            httpd.serve_forever()


# Usage
app = HTTPSServer(host='0.0.0.0', port=8443)

# Middleware
@app.use
def cors_middleware(request):
    if 'Origin' in request['headers']:
        return {
            'response': {
                'headers': {
                    'Access-Control-Allow-Origin': request['headers']['Origin'],
                    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
                    'Access-Control-Allow-Headers': 'Content-Type, Authorization'
                }
            }
        }

@app.use
def auth_middleware(request):
    protected_paths = ['/api/admin', '/api/users']
    if any(request['path'].startswith(p) for p in protected_paths):
        auth = request['headers'].get('Authorization', '')
        if not auth.startswith('Bearer '):
            return {'response': {'error': 'Unauthorized'}, 'status': 401}

# Routes
@app.route('/api/health', methods=['GET'])
def health_check(request):
    return {'status': 'healthy', 'timestamp': datetime.now().isoformat()}

@app.route('/api/users', methods=['GET'])
def get_users(request):
    return [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]

@app.route('/api/users/:id', methods=['GET'])
def get_user(request):
    return {'id': request['params']['id'], 'name': f"User {request['params']['id']}"}

@app.route('/api/users', methods=['POST'])
def create_user(request):
    return {'id': 3, **request['body']}, 201

# Generate self-signed certificate for testing
# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

if __name__ == '__main__':
    if os.path.exists('cert.pem') and os.path.exists('key.pem'):
        app.run()
    else:
        print("Please generate TLS certificate and key first:")
        print("openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes")

Example 4: HTTP/2 Server with Server Push (Go)

package main

import (
    "crypto/tls"
    "fmt"
    "io"
    "log"
    "net/http"
    "time"
)

type HTTP2Server struct {
    server *http.Server
    router *Router
}

type Router struct {
    routes map[string]http.Handler
}

func NewRouter() *Router {
    return &Router{
        routes: make(map[string]http.Handler),
    }
}

func (r *Router) GET(path string, handler http.HandlerFunc) {
    r.routes["GET:"+path] = handler
}

func (r *Router) POST(path string, handler http.HandlerFunc) {
    r.routes["POST:"+path] = handler
}

func (r *Router) Handle(path string, handler http.Handler) {
    r.routes["HANDLER:"+path] = handler
}

func NewHTTP2Server(addr string) *HTTP2Server {
    router := NewRouter()
    
    mux := http.NewServeMux()
    
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if handler, ok := router.routes["GET:"+r.URL.Path]; ok {
            handler.ServeHTTP(w, r)
            return
        }
        http.NotFound(w, r)
    })
    
    // HTTP/2 server configuration
    server := &http.Server{
        Addr:         addr,
        Handler:      mux,
        ReadTimeout:  15 * time.Second,
        WriteTimeout: 15 * time.Second,
        IdleTimeout:  60 * time.Second,
    }
    
    return &HTTP2Server{
        server: server,
        router: router,
    }
}

func (s *HTTP2Server) ConfigureTLS(minVersion uint16) {
    s.server.TLSConfig = &tls.Config{
        MinVersion:               minVersion,
        CurvePreferences:        []tls.CurveID{tls.CurveP256, tls.X25519},
        CipherSuites: []uint16{
            tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
            tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
        },
        NextProtos: []string{"h2", "http/1.1"},
    }
}

func (s *HTTP2Server) Start() error {
    s.router.GET("/index.html", func(w http.ResponseWriter, r *http.Request) {
        // Server Push for critical resources
        pusher, ok := w.(http.Pusher)
        if ok {
            // Push CSS
            if err := pusher.Push("/styles.css", nil); err != nil {
                log.Printf("Failed to push styles.css: %v", err)
            }
            // Push JavaScript
            if err := pusher.Push("/app.js", nil); err != nil {
                log.Printf("Failed to push app.js: %v", err)
            }
            // Push images
            if err := pusher.Push("/logo.png", nil); err != nil {
                log.Printf("Failed to push logo.png: %v", err)
            }
        }
        
        w.Header().Set("Content-Type", "text/html")
        io.WriteString(w, `<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
    <h1>HTTP/2 Server Push Demo</h1>
    <script src="/app.js"></script>
</body>
</html>`)
    })
    
    s.router.GET("/styles.css", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/css")
        io.WriteString(w, `body { font-family: Arial, sans-serif; margin: 40px; }`)
    })
    
    s.router.GET("/app.js", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/javascript")
        io.WriteString(w, `console.log('Hello from HTTP/2!');`)
    })
    
    s.router.GET("/api/users", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Header().Set("Cache-Control", "public, max-age=3600")
        io.WriteString(w, `[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]`)
    })
    
    s.router.GET("/api/users/:id", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        io.WriteString(w, `{"id":1,"name":"Alice"}`)
    })
    
    s.router.POST("/api/users", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusCreated)
        io.WriteString(w, `{"id":3,"name":"New User"}`)
    })
    
    log.Printf("HTTP/2 Server starting on %s", s.server.Addr)
    return s.server.ListenAndServeTLS("cert.pem", "key.pem")
}

Example 5: WebSocket Implementation (TypeScript)

import { IncomingMessage, Server as HttpServer } from 'http';
import { Server as SocketIOServer, Socket, ServerOptions } from 'socket.io';
import { URL } from 'url';
import { verify } from 'jsonwebtoken';

interface WebSocketMessage {
    type: string;
    payload: any;
    timestamp: number;
}

interface AuthenticatedSocket extends Socket {
    userId?: string;
    user?: any;
}

class WebSocketServer {
    private io: SocketIOServer;
    private rooms: Map<string, Set<string>> = new Map();
    private userSockets: Map<string, Set<string>> = new Map();
    
    constructor(server: HttpServer, options: Partial<ServerOptions> = {}) {
        this.io = new SocketIOServer(server, {
            cors: {
                origin: process.env.ALLOWED_ORIGINS?.split(',') || '*',
                methods: ['GET', 'POST'],
                credentials: true
            },
            pingTimeout: 60000,
            pingInterval: 25000,
            ...options
        });
        
        this.setupMiddleware();
        this.setupEventHandlers();
    }
    
    private setupMiddleware(): void {
        this.io.use(async (socket: AuthenticatedSocket, next) => {
            try {
                const token = socket.handshake.auth?.token || 
                              socket.handshake.headers?.authorization?.replace('Bearer ', '');
                
                if (!token) {
                    return next(new Error('Authentication required'));
                }
                
                const decoded = verify(token, process.env.JWT_SECRET!) as any;
                socket.userId = decoded.userId;
                socket.user = decoded;
                
                next();
            } catch (error) {
                next(new Error('Invalid token'));
            }
        });
        
        this.io.engine.on("connection_error", (err) => {
            console.log("Connection error:", err.message);
        });
    }
    
    private setupEventHandlers(): void {
        this.io.on('connection', (socket: AuthenticatedSocket) => {
            console.log(`User connected: ${socket.userId}`);
            
            // Join user's personal room
            const userRoom = `user:${socket.userId}`;
            socket.join(userRoom);
            
            this.trackUserSocket(socket.userId!, socket.id);
            
            // Handle joining topic rooms
            socket.on('join:room', (roomId: string) => {
                socket.join(`room:${roomId}`);
                
                if (!this.rooms.has(roomId)) {
                    this.rooms.set(roomId, new Set());
                }
                this.rooms.get(roomId)!.add(socket.userId!);
                
                socket.to(`room:${roomId}`).emit('user:joined', {
                    userId: socket.userId,
                    roomId,
                    timestamp: Date.now()
                });
            });
            
            // Handle leaving rooms
            socket.on('leave:room', (roomId: string) => {
                socket.leave(`room:${roomId}`);
                
                this.rooms.get(roomId)?.delete(socket.userId!);
                
                socket.to(`room:${roomId}`).emit('user:left', {
                    userId: socket.userId,
                    roomId,
                    timestamp: Date.now()
                });
            });
            
            // Handle private messages
            socket.on('message:private', (data: { to: string; content: string }) => {
                const message: WebSocketMessage = {
                    type: 'private',
                    payload: {
                        from: socket.userId,
                        to: data.to,
                        content: data.content
                    },
                    timestamp: Date.now()
                };
                
                // Send to recipient's personal room
                this.io.to(`user:${data.to}`).emit('message:received', message);
                
                // Confirm delivery to sender
                socket.emit('message:sent', message);
            });
            
            // Handle room messages
            socket.on('message:room', (data: { roomId: string; content: string }) => {
                const message: WebSocketMessage = {
                    type: 'room',
                    payload: {
                        from: socket.userId,
                        fromName: socket.user?.name,
                        roomId: data.roomId,
                        content: data.content
                    },
                    timestamp: Date.now()
                };
                
                socket.to(`room:${data.roomId}`).emit('message:room', message);
                socket.emit('message:sent', message);
            });
            
            // Handle typing indicators
            socket.on('typing:start', (roomId: string) => {
                socket.to(`room:${roomId}`).emit('user:typing', {
                    userId: socket.userId,
                    roomId
                });
            });
            
            socket.on('typing:stop', (roomId: string) => {
                socket.to(`room:${roomId}`).emit('user:stopped-typing', {
                    userId: socket.userId,
                    roomId
                });
            });
            
            // Handle presence updates
            socket.on('presence:update', (status: string) => {
                socket.to(`user:${socket.userId}`).broadcast.emit('presence:changed', {
                    userId: socket.userId,
                    status,
                    timestamp: Date.now()
                });
            });
            
            // Handle disconnection
            socket.on('disconnect', (reason) => {
                console.log(`User disconnected: ${socket.userId}, reason: ${reason}`);
                
                this.removeUserSocket(socket.userId!, socket.id);
                
                // Notify all rooms user was in
                this.rooms.forEach((users, roomId) => {
                    if (users.has(socket.userId!)) {
                        users.delete(socket.userId!);
                        socket.to(`room:${roomId}`).emit('user:left', {
                            userId: socket.userId,
                            roomId,
                            timestamp: Date.now()
                        });
                    }
                });
            });
        });
    }
    
    private trackUserSocket(userId: string, socketId: string): void {
        if (!this.userSockets.has(userId)) {
            this.userSockets.set(userId, new Set());
        }
        this.userSockets.get(userId)!.add(socketId);
    }
    
    private removeUserSocket(userId: string, socketId: string): void {
        const sockets = this.userSockets.get(userId);
        if (sockets) {
            sockets.delete(socketId);
            if (sockets.size === 0) {
                this.userSockets.delete(userId);
            }
        }
    }
    
    // Broadcast to all connected clients
    broadcast(event: string, data: any): void {
        this.io.emit(event, {
            ...data,
            timestamp: Date.now()
        });
    }
    
    // Send to specific user
    sendToUser(userId: string, event: string, data: any): void {
        this.io.to(`user:${userId}`).emit(event, {
            ...data,
            timestamp: Date.now()
        });
    }
    
    // Send to room
    sendToRoom(roomId: string, event: string, data: any, exclude?: string): void {
        if (exclude) {
            this.io.to(`room:${roomId}`).except(`user:${exclude}`).emit(event, {
                ...data,
                timestamp: Date.now()
            });
        } else {
            this.io.to(`room:${roomId}`).emit(event, {
                ...data,
                timestamp: Date.now()
            });
        }
    }
    
    // Get online users in room
    getRoomUsers(roomId: string): string[] {
        return Array.from(this.rooms.get(roomId) || []);
    }
    
    // Check if user is online
    isUserOnline(userId: string): boolean {
        return this.userSockets.has(userId);
    }
}

Best Practices

  • Use HTTPS everywhere; enforce TLS 1.2+ with secure cipher suites
  • Implement proper HTTP status codes and error responses
  • Use HTTP caching headers (Cache-Control, ETag) appropriately
  • Implement rate limiting to prevent abuse
  • Use HTTP/2 or HTTP/3 for improved performance
  • Validate and sanitize all input data
  • Implement proper authentication and authorization
  • Use content negotiation for API versioning
  • Implement proper request/response logging
  • Use compression (gzip, Brotli) for response bodies

Core Competencies

  • HTTP methods and status codes
  • Request/response headers
  • Body parsing and serialization
  • URL routing and parameter handling
  • TLS/HTTPS configuration
  • HTTP/2 multiplexing and server push
  • WebSocket implementation
  • RESTful API design
  • Authentication and authorization
  • Rate limiting and throttling
  • Caching strategies
  • CORS configuration
  • Compression
  • Content negotiation
  • API versioning
Install via CLI
npx skills add https://github.com/ffsshhttiikk/opencode-agents-skills --skill http-https
Repository Details
star Stars 2
call_split Forks 2
navigation Branch main
article Path SKILL.md
More from Creator
ffsshhttiikk
ffsshhttiikk Explore all skills →