কিভাবে HTTP ফাইল আপলোড কাজ করে?




file-upload (4)

একটি HTTP বার্তা শিরোনাম লাইন পরে প্রেরিত তথ্য একটি শরীর হতে পারে। একটি প্রতিক্রিয়াতে, অনুরোধকৃত সংস্থানটি ক্লায়েন্ট (বার্তা শব্দের সবচেয়ে সাধারণ ব্যবহার) -এ ফেরত পাঠানো হয়, অথবা যদি কোন ত্রুটি ঘটে তবে সম্ভবত ব্যাখ্যামূলক পাঠ্যটি পাঠানো হয়। একটি অনুরোধে, এই যেখানে ব্যবহারকারী প্রবেশ করানো তথ্য বা আপলোড করা ফাইল সার্ভারে পাঠানো হয়।

http://www.tutorialspoint.com/http/http_messages.htm

যখন আমি সংযুক্ত একটি ফাইল সহ এই মত একটি সহজ ফর্ম জমা:

<form enctype="multipart/form-data" action="http://localhost:3000/upload?upload_progress_id=12344" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: <input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>

কিভাবে অভ্যন্তরীণভাবে ফাইল পাঠাতে হয়? ফাইলটি HTTP দেহের অংশ হিসাবে ডেটা হিসাবে পাঠানো হয়? এই অনুরোধের শিরোনামগুলিতে, আমি ফাইলটির নামের সাথে সম্পর্কিত কিছু দেখতে পাচ্ছি না।

ফাইলটি পাঠানোর সময় আমি কেবল HTTP এর অভ্যন্তরীণ কাজগুলি জানতে চাই।


কিভাবে অভ্যন্তরীণভাবে ফাইল পাঠাতে হয়?

বিন্যাসটি multipart/form-data বলা হয় , যেমনঃ এন্টিটাইপ = 'মাল্টিপার্ট / ফর্ম-ডেটা' মানে কী?

আমি যাচ্ছি:

  • আরো কিছু HTML5 রেফারেন্স যোগ করুন
  • তিনি একটি ফর্ম সঙ্গে সঠিক কেন ব্যাখ্যা ব্যাখ্যা

HTML5 রেফারেন্স

enctype জন্য তিন সম্ভাবনা আছে:

  • x-www-urlencoded
  • multipart/form-data ( RFC2388 স্পেস পয়েন্ট)
  • text-plain । এটি "কম্পিউটার দ্বারা নির্ভরযোগ্যভাবে ব্যাখ্যাযোগ্য নয়", তাই এটি কখনই উত্পাদনতে ব্যবহার করা উচিত নয়, এবং আমরা এতে আরও দেখব না।

কিভাবে উদাহরণ জেনারেট করুন

একবার আপনি প্রতিটি পদ্ধতির একটি উদাহরণ দেখতে একবার, তারা কিভাবে কাজ করে তা স্পষ্ট হয়ে ওঠে, এবং যখন আপনি প্রতিটি ব্যবহার করা উচিত।

আপনি ব্যবহার করে উদাহরণ উত্পাদন করতে পারেন:

একটি সংক্ষিপ্ত। .html ফাইল ফর্ম সংরক্ষণ করুন:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
  <form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>

আমরা ডিফল্ট পাঠ্য মানটি a&#x03C9;b , যার অর্থ aωb কারণ ω হল U+03C9 , যা UTF-8 এ বাইটগুলি 61 CF 89 62

আপলোড করার জন্য ফাইল তৈরি করুন:

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary

আমাদের সামান্য ইকো সার্ভার চালান:

while true; do printf '' | nc -l 8000 localhost; done

আপনার ব্রাউজারে এইচটিএমএল খুলুন, ফাইল নির্বাচন করুন এবং জমা দিন এবং টার্মিনাল চেক করুন।

nc প্রিন্ট অনুরোধ প্রাপ্ত।

পরীক্ষিত: উবুন্টু 14.04.3, nc বিএসডি 1.105, ফায়ারফক্স 40।

একাধিক / ফর্ম-ডেটা

ফায়ারফক্স পাঠানো হয়েছে:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--

বাইনারি ফাইল এবং পাঠ্য ক্ষেত্রের জন্য বাইট 61 CF 89 62 (UTF-8 তে aωb ) আক্ষরিকভাবে পাঠানো হয়। আপনি nc -l localhost 8000 | hd সাথে যাচাই করতে পারেন nc -l localhost 8000 | hd , যা বলে যে বাইট:

61 CF 89 62

পাঠানো হয়েছে ( 61 == 'একটি' এবং 62 == 'বি')।

অতএব এটা স্পষ্ট যে:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 বিষয়বস্তুর ধরনটি multipart/form-data সেট করে এবং বলে যে ক্ষেত্রগুলিকে পৃথক করে দেওয়া হয় boundary স্ট্রিং।

  • প্রতিটি ক্ষেত্র তার তথ্য আগে কিছু সাব হেডার পায়: Content-Disposition: form-data; , ক্ষেত্রের name , filename name , তথ্য অনুসরণ করে।

    সার্ভার পরবর্তী সীমানা স্ট্রিং পর্যন্ত তথ্য পড়তে। ব্রাউজারটি এমন একটি সীমানা নির্বাচন করতে হবে যা ক্ষেত্রের যে কোনও ক্ষেত্রে উপস্থিত হবে না, তাই এই কারণে অনুরোধের মধ্যে সীমানা পরিবর্তিত হতে পারে।

    আমাদের অনন্য সীমানা আছে, ডেটা কোন এনকোডিং প্রয়োজন নেই: বাইনারি তথ্য যেমন পাঠানো হয়।

    TODO: অনুকূল সীমানা আকার ( log(N) আমি bet) কি, এবং অ্যালগরিদম নাম / চলমান সময় যা এটি খুঁজে পায়? জিজ্ঞাসা করা হয়েছেঃ https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences ফলাফল-of-a-set- https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type স্বয়ংক্রিয়ভাবে ব্রাউজার দ্বারা নির্ধারিত হয়।

    ঠিক কিভাবে এটি নির্ধারিত হয়: ব্রাউজারের দ্বারা নির্ধারিত একটি আপলোডকৃত ফাইলের মাইম টাইপ কেমন?

আবেদন / এক্স-WWW-ফর্ম-urlencoded

এখন enctype application/x-www-form-urlencoded enctype application/x-www-form-urlencoded enctype পরিবর্তন করুন, ব্রাউজারটি পুনরায় লোড করুন এবং পুনরায় জমা দিন।

ফায়ারফক্স পাঠানো হয়েছে:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

পরিষ্কারভাবে ফাইল তথ্য পাঠানো হয় নি, শুধুমাত্র বেস নাম। তাই এই ফাইল জন্য ব্যবহার করা যাবে না।

পাঠ্য ক্ষেত্রের জন্য, আমরা দেখি যে a এবং b মত সাধারণ মুদ্রণযোগ্য অক্ষরগুলি এক বাইটে পাঠানো হয়েছিল, যদিও 0xCF এবং 0x89 মত নন মুদ্রণযোগ্যগুলি প্রতিটি 3 টি বাইট গ্রহণ করেছিল: %CF%89 !

তুলনা

ফাইল আপলোডগুলি প্রায়শই অ-মুদ্রণযোগ্য অক্ষরগুলি (উদাহরণস্বরূপ চিত্র) প্রচুর থাকে, যদিও পাঠ্য ফর্মগুলি প্রায় কখনো করে না।

উদাহরণ থেকে আমরা দেখেছি যে:

  • multipart/form-data : বার্তার কয়েকটি বাইট সীমানা ওভারহেড যোগ করে এবং এটি গণনা করার জন্য কিছু সময় ব্যয় করতে হবে, তবে প্রতিটি বাইটকে এক বাইটে পাঠায়।

  • application/x-www-form-urlencoded : প্রতি ফিল্ড ( & ) একটি একক বাইট সীমানা আছে, তবে প্রতিটি অ মুদ্রণযোগ্য চরিত্রের জন্য 3x এর একটি লিনিয়ার ওভারহেড ফ্যাক্টর যোগ করে।

অতএব, এমনকি যদি আমরা application/x-www-form-urlencoded ফাইলগুলি পাঠাতে পারি, আমরা চাই না, কারণ এটি খুবই কার্যকর।

কিন্তু পাঠ্য ক্ষেত্রগুলিতে পাওয়া মুদ্রণযোগ্য অক্ষরের জন্য, এটি কোনও ব্যাপার না এবং কম ওভারহেড তৈরি করে, তাই আমরা এটি ব্যবহার করি।


আমি এই নমুনা জাভা কোড আছে:

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
public class TestClass {
    public static void main(String[] args) throws IOException {
        final ServerSocket socket = new ServerSocket(8081);
        final Socket accept = socket.accept();
        final InputStream inputStream = accept.getInputStream();
        final InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
        char readChar;
        while ((readChar = (char) inputStreamReader.read()) != -1) {
            System.out.print(readChar);
        }
        inputStream.close();
        accept.close();
        System.exit(1);
    }
}

এবং আমার এই test.html ফাইল আছে:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>File Upload!</title>
</head>
<body>
<form method="post" action="http://localhost:8081" enctype="multipart/form-data">
    <input type="file" name="file" id="file">
    <input type="submit">
</form>
</body>
</html>

এবং অবশেষে ফাইলটি আমি পরীক্ষার উদ্দেশ্যে ব্যবহারের জন্য ব্যবহার করব, যার নাম a.dat এর মধ্যে রয়েছে:

0x39 0x69 0x65

যদি আপনি ASCII বা UTF-8 অক্ষরের উপরে বাইটগুলি ব্যাখ্যা করেন তবে তারা আসলে প্রতিনিধিত্ব করবে:

9ie

সুতরাং চলুন আমাদের জাভা কোডটি a.dat , আমাদের প্রিয় ব্রাউজারে test.html খুলুন, a.dat আপলোড a.dat এবং ফর্ম জমা দিন এবং আমাদের সার্ভার কী পায় তা দেখুন:

POST / HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Content-Length: 196
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: null
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary06f6g54NVbSieT6y
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: en,en-US;q=0.8,tr;q=0.6
Cookie: JSESSIONID=27D0A0637A0449CF65B3CB20F40048AF

------WebKitFormBoundary06f6g54NVbSieT6y
Content-Disposition: form-data; name="file"; filename="a.dat"
Content-Type: application/octet-stream

9ie
------WebKitFormBoundary06f6g54NVbSieT6y--

আচ্ছা আমি 9 ক্যারেক্টার দেখতে বিস্মিত নই কারণ আমরা জাভাকে তাদের UTF-8 অক্ষর হিসাবে চিকিত্সা করে মুদ্রণ করতে বলেছিলাম। আপনি ভাল কাঁচা বাইট হিসাবে তাদের পড়তে চয়ন করতে পারেন ..

Cookie: JSESSIONID=27D0A0637A0449CF65B3CB20F40048AF 

আসলে এখানে শেষ HTTP শিরোলেখ। তারপরে HTTP শরীরে আসে, যেখানে মেটা এবং আমরা আপলোড করা ফাইলের বিষয়বস্তু আসলে দেখা যেতে পারে।


যখন আপনি কোনও ফাইল নির্বাচন করেন এবং আপনার ফর্ম জমা দেন তখন কী ঘটবে তা দেখি (আমি শিরোনামের জন্য শিরোনামগুলি কঙ্কাল করেছি):

POST /upload?upload_progress_id=12344 HTTP/1.1
Host: localhost:3000
Content-Length: 1325
Origin: http://localhost:3000
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L

------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="MAX_FILE_SIZE"

100000
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="uploadedfile"; filename="hello.o"
Content-Type: application/x-object

... contents of file goes here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--

ফর্ম প্যারামিটারগুলি এনক্রিপ্ট করার পরিবর্তে, ফর্ম প্যারামিটারগুলি (ফাইলের তথ্য সহ) অনুরোধের অংশে একটি মাল্টিপার্ট ডকুমেন্টের বিভাগ হিসাবে পাঠানো হয়।

উপরের উদাহরণে, আপনি ফর্মের মান সেট সহ MAX_FILE_SIZE ইনপুট দেখতে পারেন, পাশাপাশি ফাইল ডেটা ধারণকারী একটি বিভাগ দেখতে পারেন। ফাইল নামটি Content-Disposition শিরোনামের অংশ।

সম্পূর্ণ বিবরণ here





file-upload