2008-09-17 50 views
18

Tôi đã có một sở thích mới trong việc xây dựng một máy chủ web nhỏ, hiệu quả trong C và đã gặp một số sự cố khi phân tích cú pháp phương thức POST từ Tiêu đề HTTP. Có ai có lời khuyên nào về cách xử lý lấy các cặp tên/giá trị từ dữ liệu "đã đăng" không?Phân tích cú pháp tiêu đề HTTP

POST /test HTTP/1.1 
Host: test-domain.com:7017 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Referer: http://test-domain.com:7017/index.html 
Cookie: __utma=43166241.217413299.1220726314.1221171690.1221200181.16; __utmz=43166241.1220726314.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none) 
Cache-Control: max-age=0 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 25 

field1=asfd&field2=a3f3f3 
// ^-this 

Tôi thấy không có cách nào hữu hình để truy xuất dòng dưới cùng nói chung và đảm bảo rằng nó hoạt động mọi lúc. Tôi không phải là người hâm mộ mã hóa cứng trong bất cứ thứ gì.

Trả lời

19

Bạn có thể truy xuất cặp tên/giá trị bằng cách tìm kiếm dòng mới hoặc cụ thể hơn \ r \ n \ r \ n (sau này, nội dung thư sẽ bắt đầu).

Sau đó, bạn có thể chỉ cần chia danh sách theo & và sau đó chia từng chuỗi đã trả lại chuỗi giữa các cặp tên/giá trị.

Xem HTTP 1.1 RFC.

+0

Ah, cảm ơn. Tôi nhận thấy có thêm một khoảng trống ngay trước chuỗi các cặp tên/giá trị, nhưng không đặt hai và hai lại với nhau. –

+2

@rofly: không tính hai và hai, chỉ đọc tiêu chuẩn (RFC 2616). Đó là trong phần 4.1. – bortzmeyer

+2

Chỉ cần lưu ý rằng có các khách hàng không tuân thủ sử dụng tiêu đề "thú vị" của tiêu đề, chẳng hạn như '\ n \ n' hoặc '\ n \ r \ n'. – Wade

2

Bạn cần phải tiếp tục phân tích cú pháp luồng dưới dạng tiêu đề cho đến khi bạn thấy dòng trống. Phần còn lại là dữ liệu POST.

Bạn cần viết một trình phân tích cú pháp nhỏ cho dữ liệu bài đăng. Bạn có thể sử dụng các thói quen của thư viện C để làm điều gì đó nhanh chóng và dơ bẩn, như chỉ mục, strtok và sscanf. Nếu bạn có chỗ cho nó trong định nghĩa của bạn "nhỏ", bạn có thể làm một cái gì đó phức tạp hơn với một thư viện biểu thức chính quy, hoặc thậm chí với flex và bò rừng.

Ít nhất, tôi nghĩ loại câu trả lời này là câu hỏi của bạn.

4

Khi bạn có Độ dài nội dung trong tiêu đề, bạn biết số byte sẽ được đọc ngay sau dòng trống. Nếu, vì bất kỳ lý do gì (GET hoặc POST) Nội dung Độ dài không có trong tiêu đề, điều đó có nghĩa là không có gì để đọc sau dòng trống (crlf).

0

IETF RFC bất kể, đây là câu trả lời chính xác hơn. Giả sử bạn nhận ra rằng luôn có thêm /r/n sau dòng Content-Length trong tiêu đề, bạn có thể thực hiện công việc để tách nó thành biến char* có tên là data. Đây là nơi chúng ta bắt đầu.

char *data = "f1=asfd&f2=a3f3f3"; 
char f1[100], 
char f2[100]; 
sscanf(data, "%s&%s", &f1, &f2); // get the field tuples 

char f1_name[50]; 
char f1_data[50]; 
sscanf(f1, "%s=%s", f1_name, f1_data); 

char f2_name[50]; 
char f2_data[50]; 
sscanf(f2, "%s=%s", f2_name, f2_data); 
Các vấn đề liên quan