Whats Content-Type value within a HTTP-Request when uploading content?

前端 未结 3 858
日久生厌
日久生厌 2020-11-28 12:09

I need to extract uploads from http-trafic. How could do that? First of all, the request-method will be POST. Secondly, there will be a Content-Type header-field. I do not w

相关标签:
3条回答
  • 2020-11-28 12:18

    The content type is per specification multipart/form-data.

    This is a special content type which can be visualized as multiple sub-requests in one big request. Each of those sub-requests (one form-data element) has their own set of headers. The content type of the actual data is in there.

    Here's an example how it look like with 1 normal field and 1 file field (in HTML terms, when using <input name="textfield"><input type="file" name="filefield">):

    Content-Type: multipart/form-data;boundary=SOME_BOUNDARY
    
    --SOME_BOUNDARY
    content-disposition: form-data;name="textfield"
    content-type: text/plain;charset=UTF-8
    
    value of textfield here
    --SOME_BOUNDARY
    content-disposition: form-data;name="filefield";filename="some.ext"
    content-type: application/octet-stream
    
    binary file content here
    
    --SOME_BOUNDARY--
    

    As to parsing and extracting this data, practically every programming language has builtin/3rd party APIs for this. As you didn't tell anything about which one you're using, it's impossible to give a targeted answer. In case of for example Java, that would be either the 3rd party library Apache Commons FileUpload or when you're using Servlet 3.0, the API-provided request.getPart() method.

    0 讨论(0)
  • 2020-11-28 12:23

    Based on @BalusC s solution I made a little extension method for .NET's build in WebClient class which does not support Multipart upload out of the box.

    Usage

    Just mix string values and files (enclosed in #)

        public void UploadMultipart()
        {
            var fileName = "/some/existing/file.ext";
            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                values.Add("id", Guid.NewGuid().ToString());
                values.Add("name", Path.GetFileNameWithoutExtension(fileName));
                values.Add("file", $"#{fileName}#");
    
                var result = client.UploadMultipart(address, method, values);
                var content = client.Encoding.GetString(result);
            }
        }
    

    Extension method

        public static byte[] UploadMultipart(this WebClient client,
            string address, string method, NameValueCollection values)
        {
    
            string boundary = DateTime.Now.Ticks.ToString("x");
    
            client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
    
            var sb = new StringBuilder()
                .AppendLine();
    
            foreach (var key in values.AllKeys)
            {
                var contentDispositon = $"form-data;name=\"{key}\"";
                var contentType = $"text/plain;charset={client.Encoding.WebName}";
    
                var value = values[key];
    
                if (value.StartsWith("#") && value.EndsWith("#"))
                {
                    // if a value is enclosed in hashes we expect this to be a path to a file
                    // file=#/path/to/file.ext#
                    var fileName = value.Trim('#');
                    var file = File.ReadAllBytes(fileName);
                    value = client.Encoding.GetString(file);
    
                    contentType = "application/octet-stream";
                    contentDispositon = $"form-data;name=\"{key}\"filename=\"{Path.GetFileName(fileName)}\"";
                }
    
                sb.AppendLine($"--{boundary}")
                  .AppendLine($"Content-Disposition: {contentDispositon}")
                  .AppendLine($"Content-Type: {contentType}")
                  .AppendLine()
                  .AppendLine(value);
            }
    
            sb.AppendLine($"--{boundary}--");
    
            var data = client.Encoding.GetBytes(sb.ToString());
    
            return client.UploadData(address, method, data);
    
        }
    
    0 讨论(0)
  • 2020-11-28 12:29

    If (and I by no means am saying this is the correct way) you just want to save data from a byte array, you should look at how to read the POST body at: Reading POST body with bottle.py Reading the data and then creating a new file should do the trick.

    0 讨论(0)
提交回复
热议问题