PHP file upload source code analysis (RFC1867) _ PHP Tutorial

Source: Internet
Author: User
Tags php file upload upload php
Php file upload source code analysis (RFC1867 ). For more information about php file upload source code analysis (RFC1867), refer to HTTP-based upload, which is easier to use and more secure than FTP. you can upload php files to the application for source code analysis (RFC1867). For more information, see

HTTP-based upload is easier to use and more secure than FTP. you can use PUT, WEBDAV, and RFC1867 Upload methods. This article will analyze how to implement file Upload based on RFC1867 in PHP.

RFC1867

RCF1867 is the Form-based File Upload in HTML standard protocol. RFC1867 makes two changes to HTML:


1 adds a file option for the type attribute of the input element.
2 The input mark can have the accept attribute, which can specify the file type or file format list that can be uploaded.


In addition, this standard defines a new mime type: multipart/form-data, and when processing a file with enctype = "multipart/form-data" and/or containsActions to be taken when marking the form.

For example, when HTML allows users to upload one or more files, they can write the following code:

The code is as follows:

This form must be familiar to everyone. for PHP, it also defines a default form element MAX_FILE_SIZE, you can use this hidden form element to recommend that PHP only allow the size of the file to be uploaded. for example, we hope that the size of the file uploaded by the user cannot exceed 5000 (5 k) bytes, you can write as follows:

The code is as follows:

Not to mention, how unreliable MAX_FILE_SIZE is (so browser-based control is unreliable). simply by implementation, I will slowly introduce how MAX_FILE_SIZE works.

When the user selects a file (laruence.txt) and fills in the file description ("laruence's personal introduction"), what happened after clicking Upload?

Form submission

After the user confirms the submission, the browser will send data packets in similar formats to the page specified by the action attribute in form (in this example, upload. php ):

The code is as follows:

// Request header
POST/upload. php HTTP/1.0rn
...
Host: www. laruence. comrn
...
Content-length: xxxxxrn
...
Content-type: multipart/form-data, boundary = -------------- 7d51863950254rn
... Rnrn
// Start POST data content
--------------- 7d51863950254
Content-disposition: form-data; name = "description"
Laruence profile
--------------- 7d51863950254
Content-disposition: form-data; name = "userfile"; filename = "laruence.txt"
Content-Type: text/plain
... Content of laruence.txt...
--------------- 7d51863950254

The next step is how the server processes the data.

Upload accepted

When the Web server is Apache (and PHP is installed on Apache in module mode) and user data is received, it first follows the HTTP request header, after determining that the mime type is php type and going through some processes (for this part, refer to my previous PHP Life Cycle ppt), the control will be handed over to the PHP module.

At this time, PHP will call sapi_activate to initialize a request. in this process, first determine the request type, which is POST, and then call sapi_read_post_data through Content-type, find the rfc1867 handler rfc1867_post_handler and call this handler to analyze the POST data.

For the source code of rfc1867_post_handler, you can find it in mian/rfc1867.c. For more information, see my previous in-depth understanding of PHP file upload, which also lists the source code.

Then, PHP uses boundary to check whether each segment is defined simultaneously:

Name and filename attributes (famous file upload)
Filename is not defined)
Filename (common data) is not defined for name ),

To perform different processing.

The code is as follows:

If (cd = php_mime_get_hdr_value (header, "Content-Disposition "))){
Char * pair = NULL;
Int end = 0;

While (isspace (* cd )){
++ Cd;
}

While (* cd & (pair = php_ap_getword (& cd ,';')))
{
Char * key = NULL, * word = pair;

While (isspace (* cd )){
++ Cd;
}

If (strchr (pair, '= ')){
Key = php_ap_getword (& pair, '= ');

If (! Strcasecmp (key, "name ")){
// Obtain the name field
If (param ){
Efree (param );
}
Param = php_ap_getword_conf (& pair TSRMLS_CC );
} Else if (! Strcasecmp (key, "filename ")){
// Obtain the filename field
If (filename ){
Efree (filename );
}
Filename = php_ap_getword_conf (& pair TSRMLS_CC );
}
}
If (key ){
Efree (key );
}
Efree (word );
}

In this process, PHP will check whether MAX_FILE_SIZE exists in common data.

The code is as follows:

/* Normal form variable, safe to read all data into memory */
If (! Filename & param ){
Unsigned int value_len;
Char * value = multipart_buffer_read_body (mbuff, & value_len TSRMLS_CC );
Unsigned int new_val_len;/* Dummy variable */
......

If (! Strcasecmp (param, "MAX_FILE_SIZE ")){
Max_file_size = atol (value );
}

Efree (param );
Efree (value );
Continue;
}

If yes, the system checks whether the file size exceeds the value.

The code is as follows:

If (PG (upload_max_filesize)> 0 & total_bytes> PG (upload_max_filesize )){
Cancel_upload = UPLOAD_ERROR_A;
} Else if (max_file_size & (total_bytes> max_file_size )){
# If DEBUG_FILE_UPLOAD
Sapi_module.sapi_error (E_NOTICE,
"MAX_FILE_SIZE of % ld bytes exceeded-file [% s = % s] not saved ",
Max_file_size, param, filename );
# Endif
Cancel_upload = UPLOAD_ERROR_ B;
}

Through the above code, we can also see that the judgment is divided into two parts, the first part is to check the default PHP Upload ceiling. the second part is to check the user-defined MAX_FILE_SIZE. Therefore, the MAX_FILE_SIZE defined in the form cannot exceed the maximum size set in PHP.

By judging the name and filename, if a file is uploaded, a temporary file with a random name will be created in the file upload directory based on php settings:

The code is as follows:

If (! Skip_upload ){
/* Handle file */
Fd = php_open_temporary_fd_ex (PG (upload_tmp_dir ),
"Php", & temp_filename, 1 TSRMLS_CC );
If (fd =-1 ){
Sapi_module.sapi_error (E_WARNING,
"File upload error-unable to create a temporary file ");
Cancel_upload = UPLOAD_ERROR_E;
}
}

Returns the file handle and temporary random file name.

There will also be some verification, such as the file name is legal, name is legal, and so on.

If these verifications are passed, read the content and write it to the temporary file.

.....

The code is as follows:

Else if (blen> 0 ){
Wlen = write (fd, buff, blen); // write a temporary file.
If (wlen =-1 ){
/* Write failed */
# If DEBUG_FILE_UPLOAD
Sapi_module.sapi_error (E_NOTICE, "write () failed-% s", strerror (errno ));
# Endif
Cancel_upload = UPLOAD_ERROR_F;
}
}
....

When the cyclic reading is complete, close the temporary file handle. record the temporary variable name:

The code is as follows:

Zend_hash_add (SG (rfc1867_uploaded_files), temp_filename,
Strlen (temp_filename) + 1, & temp_filename, sizeof (char *), NULL );

And generate the FILE variable. at this time, if it is a famous upload, it will be set:

The code is as follows:

$ _ FILES ['userfile'] // name = "userfile"

If it is an anonymous upload, tmp_name will be used for setting:

The code is as follows:

$ _ FILES ['tmp _ name'] // Upload without name

It is finally handed over to the user for upload. php processing.

In upload. php, you can use move_uploaded_file to operate the generated file.


For details about protocol (RFC1867), HTTP-based upload is much more convenient and secure than FTP...

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.