HttpWebRequest的发布PARAMATERS为AWS文件上传请求,导致400错误(Http

2019-11-04 16:26发布

我想从我的统一游戏文件上传到我的AWS账户。 这样做的表格可以在这里找到。 早些时候,我用FILEUPLOAD_BASE_URL是“ https://file.ac/xySSFOicMMk/ ”不需要一键(链接上传的文件在这里 )。 然而,AWS文件上传需要,其价值形态的关键PARAM可以是“/ $ {文件名}”。 我所指定的值作为sb.Append("key: AffectivaLogs/${filename}"); 如下面示出,但该请求被抛出400错误。 这是指定的键作为POST请求参数的正确方法是什么?

private string FILEUPLOAD_BASE_URL = "http://gameexperiencesurvey.s3.amazonaws.com/";
public void uploadToDrive()
{    
    string[] files = Directory.GetFiles(".", "*.txt");
    for (int i = 0; i < files.Length; i++)
    {
        string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
        ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
        HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(FILEUPLOAD_BASE_URL);
        webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
        webrequest.Method = "POST";
        // Build up the post message header  
        StringBuilder sb = new StringBuilder();
        sb.Append("--");
        sb.Append(boundary);
        sb.Append("\r\n");
        sb.Append("key: AffectivaLogs/${filename}"); // is this how it should be?
        sb.Append("\r\n");
        sb.Append("Content-Disposition: form-data; name=\"");
        sb.Append("file"); // file form name
        sb.Append("\"; filename=\"");
        sb.Append(Path.GetFileName(files[i]));
        sb.Append("\"");
        sb.Append("\r\n");
        sb.Append("Content-Type: ");
        sb.Append("text/plain");
        sb.Append("\r\n");
        sb.Append("\r\n");

        string postHeader = sb.ToString();
        byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

        // Build the trailing boundary string as a byte array  
        // ensuring the boundary appears on a line by itself  
        byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

        FileStream fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read);
        long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
        webrequest.ContentLength = length;

        Stream requestStream = webrequest.GetRequestStream();

        // Write out our post header  
        requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

        // Write out the file contents  
        byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            requestStream.Write(buffer, 0, bytesRead);

        // Write out the trailing boundary  
        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
        try
        {
            WebResponse response = webrequest.GetResponse();
            Stream s = response.GetResponseStream();
            StreamReader sr = new StreamReader(s);
        }
        catch (Exception e)
        {
            Debug.Log("Error occured .... " + e.Message);
        }        
    }
}

public bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    bool isOk = true;
    // If there are errors in the certificate chain, look at each error to determine the cause.
    if (sslPolicyErrors != SslPolicyErrors.None)
    {
        for (int i = 0; i < chain.ChainStatus.Length; i++)
        {
            if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
            {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                bool chainIsValid = chain.Build((X509Certificate2)certificate);
                if (!chainIsValid)
                {
                    isOk = false;
                }
            }
        }
    }
    return isOk;
}

错误如下:

Answer 1:

昨天,我试图用WWWForm和WWW上传文件,我有一个问题 ,其中添加二进制数据WWWform不能正常工作。 好像为了WWWForm工作,你需要在你的形式有两种二进制和非二进制数据。 因此,下面的解决方案工作。

public void uploadToAWS()
{
    fileNameList = "";
    string[] files = Directory.GetFiles(".", "*.txt");
    for (int i = 0; i < files.Length; i++)
    {
        WWWForm AWSform = new WWWForm();
        AWSform.AddField("key", "AffectivaLogs/${filename}");
        AWSform.AddBinaryData("file", File.ReadAllBytes(files[i]), files[i], "text/plain");
        StartCoroutine(Post(FILEUPLOAD_BASE_URL, AWSform));
        fileNameList += files[i].Replace(@".\", "") + "  ||  ";
    }
} 
IEnumerator Post(string url, WWWForm form)
{               
    WWW www = new WWW(url, form);
    float elapsedTime = 0.0f;
    while (!www.isDone)
    {
        elapsedTime += Time.deltaTime;
        //Matrix4x4 wait time is 20s
        if (elapsedTime >= 20f)
        {
            break;
        }
        yield return null;
    }
    if (!www.isDone || !string.IsNullOrEmpty(www.error))
    {
        Debug.LogError("Connection error while sending analytics... Error:" + www.error);
        // Error handling here.
        yield break;
    }

    if (www.isDone)
    {            
        Debug.Log("Data Sent successfully.");
        yield break;
    }        
}


文章来源: HttpWebRequest post paramaters for AWS file upload request, leading to 400 error