http - 在不进行大量分配的情况下在 io.ReadCloser 中查找字符串

标签 http go memory

我有一个很大的 io.ReadCloser,它是从我的 HTTP 处理函数中的 http.Request 获得的。我需要将请求代理到另一台服务器,但首先我想在正文中找到与 Title: (\w+) 之类的正则表达式匹配的字符串。这很难——将整个主体复制到一个新的缓冲区中进行操作会占用太多内存,我试过使用 regexp.FindReaderSubmatchIndex但它只给我结果的索引,而不是实际的字符串。

执行此操作的最佳方法是什么? Tokenizers 和 JSON 解码器等似乎在 io 流上工作,这是一个非常简单的用例。有人可以指出我正确的方向吗?

最佳答案

我会为此使用 io.TeeReader 并将特殊编写器传递给 TeeReader 构造函数。考虑将以下内容作为伪代码,因为有一些我们在这里不处理的边缘情况:

package main

import (
    "fmt"
    "io"
    "io/ioutil"
    "net/http"
    "regexp"
)

type Finder struct {
    Regexp *regexp.Regexp
    match  string
}

//Write implements io.Writer interface
func (f *Finder) Write(p []byte) (int, error) {
    if f.match == "" {
        f.match = string(f.Regexp.Find(p))
    }

    return len(p), nil
}

func Handler(w http.ResponseWriter, r *http.Request) {
    f := &Finder{
        Regexp: regexp.MustCompile("Title: ([a-zA-Z0-9]+)"),
    }

    r.Body = ioutil.NopCloser(io.TeeReader(r.Body, f))

    //pass request to another server

    fmt.Println(f.match)
}

关于http - 在不进行大量分配的情况下在 io.ReadCloser 中查找字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51290415/

相关文章:

具有给定概率的 slice/数组的 Golang 选择数

linux - alloc_pages Linux 内核返回的页面

node.js - 使用 Node 和 Express 4 进行基本 HTTP 身份验证

c++ - Mongoose 正在阻塞其他请求并一一处理

java - android HTTP 请求失败

go - Int 串进去?

bash - 简单的 bash 和 curl 检查 Web 服务器上是否存在文件?

go - 处理用户回答

c - 动态内存位置 C - 参数 int *

java - 如何使用 Eclipse 内存分析器工具 (MAT) 分析 HashMap