解析Content-Type: multipart/form-data格式数据

经常要处理php端发过来的Content-Type: multipart/form-data数据,写两个函数处理下这个数据好。

2014-1-24

发现有个Bug(错误)!!!!


Content-Type: multipart/form-data; boundary=----------------------------aa14712544ce
 
------------------------------aa14712544ce
Content-Disposition: form-data; name="subject"
 
【186期】邂逅青岛,还未离开就想再见
------------------------------aa14712544ce
Content-Disposition: form-data; name="html"
 
Html/78/186soFksp7820130730_f7dJVlDX.html
------------------------------aa14712544ce
Content-Disposition: form-data; name="email"
 
12477511147@qq.com
------------------------------aa14712544ce
Content-Disposition: form-data; name="magid"
 
78
------------------------------aa14712544ce
Content-Disposition: form-data; name="number"
 
186
------------------------------aa14712544ce
Content-Disposition: form-data; name="nick"
 
MyTrip
------------------------------aa14712544ce--


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char *get_boundary(char *mfd)
{
	char *p, *end;
	char *boundary = NULL;
	int boundary_size;
	
	if ((p = strstr(mfd, "boundary=")) == NULL) {
		return NULL;
	}

	p += 9;
	if ((end = strstr(p, "\r\n")) == NULL) {
		return NULL;
	}
	
	boundary_size = end - p + 1;
	boundary = malloc(boundary_size);

	strncpy(boundary, p, boundary_size);
	boundary[boundary_size - 1] = 0;
	
	return boundary;
}


char* mutipart_form_data(char *mfd, char *boundary, char **name, char **content)
{
	char *p, *end;
	int size;
	int boundary_size;

	*content = *name = NULL;
	if ( (p = strstr(mfd, "name=")) == NULL) {
		return -1;
	}
	p += 6;
	if ((end = strchr(p, '\"')) == NULL) {
		return -1;
	}

	// 获取name
	size = end - p + 1;
	*name = malloc(size);
	strncpy(*name, p, size);
	(*name)[size - 1] = 0;
	
	// 获取内容
	p = end + 1;
	if ((end = strstr(p, boundary)) == NULL) {
		free(*name);
		*name = NULL;
		return -1;
	}

	boundary_size = strlen(boundary);
	mfd = end + boundary_size;

	while(*p == '\r' || *p == '\n') {
		p++;
	}
	
	end -= 3;
	while(*end == '\r' || *end == '\n') {
		end--;
	}

	if (p > end) {
		free(*name);
		*name = NULL;
		return -1;
	}

	size = end - p + 2;
	*content = malloc(size);
	strncpy(*content, p, size);
	(*content)[size - 1] = 0;
	
	if (*(mfd + 1) == '-') {
		// 说明到了最后了
		return NULL;
	}

	return mfd;
}


int main(int argc, char *argv[])
{
	FILE *fp;
	char *f_buf;
	char *boundary;
	size_t f_size;
	fp = fopen(argv[1], "r");

	struct stat f_stat;
	stat(argv[1], &f_stat);
	f_size = f_stat.st_size;
	if (f_size <= 0) {
		printf("fail!!!!!!!\n");
		return 0;
	}
	
	f_buf = malloc(f_stat.st_size + 1);

	fread(f_buf, f_size, 1, fp);
	char *mfd = f_buf;

	
	boundary = get_boundary(f_buf);
	printf("boundary=%s\n", boundary);
	
	while (1) {
		char *name, *content;
		mfd = mutipart_form_data(mfd, boundary, &name, &content);
		if (mfd == -1) {
			break;
		}
                // show 
		printf("name=\"%s\" content=\"%s\"\n", name, content);
		free(name);
		free(content);
		if (mfd == NULL) {
			break;
		}
	}
	
	return 0;
}



  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: content-type: multipart/form-data 是一种 HTTP 请求头部的格式,用于在 HTTP 请求中传输二进制数据,例如上传文件。它允许将多个不同类型数据一起发送到服务器,每个数据块都有自己的 MIME 类型和边界分隔符。这种格式通常用于表单提交和文件上传。 ### 回答2: content-type: multipart/form-data是HTTP协议中的一个请求头字段,用于指定请求体的数据格式为多部分表单数据。该数据格式常用于上传文件等需要传递二进制数据的场景。 multipart/form-data数据格式的特点是将请求体数据划分为多个部分,每个部分都是一个独立的数据块,块之间用分隔符进行分隔。每个数据块都包含一个头部和一个内容部分。 头部是一个描述数据块的字符串,包含了元数据信息,如Content-Disposition和Content-Type等。其中Content-Disposition常用于指定数据块的名称、文件名和传输方式。Content-Type常用于指定数据块的媒体类型。 内容部分是实际的数据内容,可以是文本、二进制等形式。对于文件上传,内容部分通常是二进制的文件数据。 通过使用multipart/form-data格式,客户端可以将多个不同类型数据(例如文本表单字段和文件等)一同提交给服务器端。服务器端可以通过解析请求体数据,逐个读取和处理各个数据块,从而实现文件上传等功能。 总之,content-type: multipart/form-data是一种用于上传文件等二进制数据的HTTP请求数据格式,具有分块、包含元数据的特点,可以在客户端和服务器端传输多部分表单数据。 ### 回答3: content-type: multipart/form-data是HTTP协议中的一种数据传输格式,主要用于在客户端和服务器之间传递带有文件上传的表单数据。 在HTTP请求中,表单数据通常使用键值对的形式进行传输,例如key1=value1&key2=value2。然而,当表单中包含文件上传时,使用这种形式无法传递文件数据。这时就需要使用multipart/form-data格式。 使用multipart/form-data格式时,请求体被划分为多个部分(part),每个部分包含一个表单字段或一个文件。每个部分使用boundary作为分隔符,用于区分不同的字段或文件。 对于每个表单字段,请求体的一部分将包含字段的键名和值。对于文件,请求体的一部分将包含字段的键名、文件名以及文件的二进制数据。值得注意的是,multipart/form-data格式不对文件进行任何编码或压缩,直接发送原始的二进制数据。 使用multipart/form-data格式时,请求头中的Content-Type字段即为content-type: multipart/form-data,同时指定boundary参数来标识分隔符的字符串。 服务器端在接收到这样的请求后,可以解析请求体,提取其中的表单字段和文件数据,并进行相应的处理。常用的服务器端框架和编程语言都提供了处理这种格式的工具和库。 总之,content-type: multipart/form-data是一种用于在HTTP请求中传递带文件上传的表单数据格式,在客户端和服务器之间进行数据传输时使用,以便实现文件上传功能。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值