+
95
-

回答

golang代码

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
)

// 代理服务器地址
const proxyAddress = "0.0.0.0:8080"

// 文件下载目录
const downloadDir = "./downloads"

// 要下载的文件类型
var fileTypes = []string{"image/jpeg", "image/png", "application/pdf"}

func main() {
    http.HandleFunc("/", handleRequestAndRedirect)
    fmt.Printf("Starting proxy server on %s\n", proxyAddress)
    if err := http.ListenAndServe(proxyAddress, nil); err != nil {
        fmt.Printf("Failed to start server: %v\n", err)
    }
}

func handleRequestAndRedirect(w http.ResponseWriter, req *http.Request) {
    client := &http.Client{}

    // 创建新的请求
    newReq, err := http.NewRequest(req.Method, req.URL.String(), req.Body)
    if err != nil {
        http.Error(w, "Failed to create request", http.StatusInternalServerError)
        return
    }

    // 复制请求头
    for key, values := range req.Header {
        for _, value := range values {
            newReq.Header.Add(key, value)
        }
    }

    // 发送请求
    resp, err := client.Do(newReq)
    if err != nil {
        http.Error(w, "Failed to get response", http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    // 复制响应头
    for key, values := range resp.Header {
        for _, value := range values {
            w.Header().Add(key, value)
        }
    }

    // 检查响应内容类型
    contentType := resp.Header.Get("Content-Type")
    if shouldDownloadFile(contentType) {
        // 创建一个新的读取器来读取响应体
        bodyCopy := io.TeeReader(resp.Body, w)
        err := downloadFile(bodyCopy, contentType)
        if err != nil {
            fmt.Printf("Failed to download file: %v\n", err)
        }
    } else {
        // 将响应内容复制到客户端
        w.WriteHeader(resp.StatusCode)
        io.Copy(w, resp.Body)
    }
}

func shouldDownloadFile(contentType string) bool {
    for _, fileType := range fileTypes {
        if strings.Contains(contentType, fileType) {
            return true
        }
    }
    return false
}

func downloadFile(body io.Reader, contentType string) error {
    // 创建下载目录
    err := os.MkdirAll(downloadDir, os.ModePerm)
    if err != nil {
        return err
    }

    // 创建文件
    fileName := fmt.Sprintf("%s/%s", downloadDir, generateFileName(contentType))
    file, err := os.Create(fileName)
    if err != nil {
        return err
    }
    defer file.Close()

    // 将内容写入文件
    _, err = io.Copy(file, body)
    return err
}

func generateFileName(contentType string) string {
    ext := ""
    switch contentType {
    case "image/jpeg":
        ext = "jpg"
    case "image/png":
        ext = "png"
    case "application/pdf":
        ext = "pdf"
    default:
        ext = "bin"
    }
    return fmt.Sprintf("%d.%s", os.Getpid(), ext)
}

测试代码

<?php

// 要访问的URL
$url = "http://repo.bfw.wiki/bfwrepo/image/5d6539385ad28.png";

// 代理服务器地址和端口
$proxy = "http://golang的代理服务:8080";

// 代理服务器用户名和密码(如果需要)
$proxy_user = "username";
$proxy_password = "password";

// 初始化cURL会话
$ch = curl_init();

// 设置cURL选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// 设置代理
curl_setopt($ch, CURLOPT_PROXY, $proxy);

// 如果代理服务器需要身份验证,设置代理用户名和密码
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, "$proxy_user:$proxy_password");

// 发送请求并获取响应
$response = curl_exec($ch);

// 检查是否有错误发生
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
} else {
    // 输出响应
    echo $response;
}

// 关闭cURL会话
curl_close($ch);
?>

网友回复

我知道答案,我要回答