Phương thức HTTP GET hoạt động như thế nào liên quan đến giao thức DNS?


17

Tôi đang cố gắng để hiểu các giao thức lớp ứng dụng trong ngăn xếp TCP / IP. Tôi biết rằng cả giao thức HTTP và DNS đều ở lớp trên cùng (Lớp ứng dụng). Vì vậy, khi trình duyệt muốn truy cập tài nguyên, nó phải gửi yêu cầu đến máy chủ HTTP, ví dụ:

GET www.pippo.it/hello.htm HTTP/1.1

Thực hiện yêu cầu này theo các quy tắc của giao thức HTTP, nó sử dụng URL trang chứ không phải địa chỉ IP.

Tôi biết rằng yêu cầu DNS là cần thiết để chuyển đổi URL thành IP. Vì vậy, câu hỏi của tôi là: HTTP có gọi giao thức DNS không? Tôi dường như không thể, vì cả hai đều là giao thức lớp trên cùng (vì vậy DNS không thể cung cấp dịch vụ cho HTTP). Theo cùng một cách, ngay cả TCP (vẫn ở mức thấp hơn) không thể yêu cầu dịch vụ ở giao thức cấp cao hơn như DNS.

Vậy khi nào thì yêu cầu DNS xảy ra? Và ai thực hiện một yêu cầu như vậy?


1
Bạn có thể chấp nhận một trong những câu trả lời để làm rõ câu trả lời nào trong số những câu trả lời này không?
030

Câu trả lời:


38

Yêu cầu HTTP trong câu hỏi thực sự không hợp lệ trừ khi trình duyệt đang nói chuyện với một trung gian (proxy).

Ví dụ của bạn sẽ trông giống một chút như sau nếu trình duyệt đang nói chuyện trực tiếp với máy chủ web:

GET /hello.htm HTTP/1.1
Host: www.pippo.it

Bây giờ, để đặt điều này trong phối cảnh, hãy xem xét mô hình OSI:

Mô hình OSI

Chúng tôi có 3 hệ thống đang hoạt động:

  • Một khách hàng đang chạy trình duyệt
  • Một máy chủ web phục vụ trang web
  • Một máy chủ DNS biết địa chỉ IP của trang web

Các giao thức liên quan là, từ dưới lên trên (tối thiểu được đặt thành OP):

  • IP
  • TCP, UDP
  • HTTP, DNS

Giao tiếp HTTP được thực hiện qua giao thức TCP (TCP nằm trên giao thức IP) trong khi giao tiếp DNS, trong trường hợp này, được thực hiện qua giao thức UDP (UDP cũng nằm trên giao thức IP).

Dưới đây là chuỗi liên lạc ngắn gọn:

  1. Máy khách , đang chạy trình duyệt, yêu cầu máy chủ DNS cung cấp Abản ghi cho www.pippo.it, sử dụng giao thức UDP.

    1.1. Trên máy khách, đó là hệ điều hành thực hiện phần giải quyết và nói chuyện lại với trình duyệt --- trình duyệt không bao giờ nói chuyện trực tiếp với máy chủ DNS, mà thông qua HĐH bằng cách gọi gethostbyname () hoặc getaddrinfo () mới hơn . Trên Windows, thứ tự mà HĐH phân giải địa chỉ có khả năng được xác định bởi một cái gì đó như thế này , trong khi trên Linux, quyền ưu tiên giải quyết được xác định bởi/etc/nsswitch.conf

  2. Máy chủ DNS , sử dụng giao thức UDP, trả lời máy khách bằng địa chỉ bản ghi / IP, nếu nó tồn tại

  3. Máy khách mở kết nối TCP trên cổng 80 của máy chủ web và viết văn bản sau:

    Yêu cầu HTTP:

    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    Bạn có thể bắt chước điều tương tự bằng cách làm một cái gì đó như thế này trong bảng điều khiển hoặc dấu nhắc lệnh của bạn:

    > telnet www.pippo.it 80
    Trying 195.128.235.49...
    Connected to www.pippo.it.
    Escape character is '^]'.
    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    theo sau là hai dòng trống. Nếu nội dung được yêu cầu tồn tại, máy chủ web sẽ in nó trên màn hình. Nếu có một trình duyệt ở phía bên kia, văn bản phản hồi sẽ được trình duyệt phân tích cú pháp và tất cả các thẻ, liên kết, tập lệnh và hình ảnh được hiển thị trong những gì chúng ta gọi là trang web.

Trong thực tế có một số chi tiết khác, ví dụ các trình duyệt có thể lưu trữ địa chỉ IP nếu bạn đã truy cập một số tên miền, do đó việc phân giải DNS trở nên không cần thiết. Ngoài ra, các trình duyệt hiện đại có thể cố gắng giải quyết trước khi bạn thực sự cần nó ( tìm nạp trước DNS ) để tăng tốc trình duyệt của bạn.

Ngoài ra, máy tính của bạn có thể có các bản ghi tĩnh trong một hoststệp. Nếu một bản ghi khớp với yêu cầu, mục nhập tĩnh cục bộ sẽ được sử dụng trước tiên và không có máy chủ DNS nào được liên hệ. Đây là cấu hình và không nhất thiết phải đúng, nhưng nó là mặc định trên các hệ điều hành mà tôi quen thuộc.


4
@trikly: đó là những gì tiêu đề 'Máy chủ' dành cho. Không có nó, bạn chỉ có thể có một trang web cho mỗi địa chỉ IP. Đây là điểm khác biệt chính giữa HTTP / 1.0 và HTTP / 1.1. Rất may, các trình duyệt HTTP / 1.0 hiện rất hiếm - nhưng nếu bạn muốn phục vụ cho chúng thì bạn cần một địa chỉ IP khác nhau cho mỗi trang web (chúng vẫn có thể được lưu trữ trên cùng một máy chủ).
AE

1
@AE Cảm ơn. Tôi nghĩ rằng tôi đã không rõ ràng trong câu hỏi của mình và đó là lý do tại sao Hrvoje không hiểu những gì tôi đang nói. (Tôi nên nói tên miền chứ không phải URL). Tôi rất vui vì bạn vẫn hiểu.
trlkly

1
Bạn nói " Đây không phải là yêu cầu HTTP đúng " và điều đó gần như đúng, nhưng nó gần hơn so với bạn ngụ ý: " Để cho phép chuyển đổi sang perfectURI trong tất cả các yêu cầu trong các phiên bản HTTP trong tương lai, tất cả các máy chủ HTTP / 1.1 PHẢI chấp nhận hình thức perfectURI trong yêu cầu ". (RFC 2616 §5.1.2) Vì vậy, GET http://www.pippo.it/hello.htm HTTP/1.1sẽ là một yêu cầu hợp lệ, nếu không bình thường. Nó cũng sẽ là một yêu cầu hợp lệ và thông thường đối với proxy HTTP.
wfaulk

1
gethostbyname()có phần lỗi thời. Một người sẽ sử dụng tốt hơn getaddrinfo()...
glglgl

1
@Utku rất tiếc là không vì SSH giả định đầu bên kia nói giao thức SSH trong khi telnet là giao thức văn bản thuần túy và có thể được sử dụng để nói chuyện với bất kỳ giao thức đơn giản nào khác như POP3, IMAP miễn là họ không sử dụng SSL / TLS trong trường hợp bạn sẽ cần phải kết thúc phiên telnet với người trợ giúp như sslwrap hoặc một cái gì đó tương tự.
Hrvoje Špoljar

12

HTTP được vận chuyển qua TCP, là giao thức IP. Để thực hiện một yêu cầu HTTP, trình duyệt phải mở kết nối TCP và để thực hiện điều đó, nó cần địa chỉ IP đích (tức là địa chỉ IP của máy chủ). Để giải quyết tên máy chủ của máy chủ, do đó, nó phải đưa ra một yêu cầu DNS (nói chung, chính yêu cầu DNS được gửi bởi hệ điều hành khi một chương trình gọi các chức năng phân giải tên của nó, tuy nhiên, không có gì ngăn chương trình gửi các yêu cầu DNS của chính nó đến DNS người phục vụ). Khi kết nối được thiết lập, nó có thể gửi yêu cầu HTTP của nó, chứa đường dẫn đến tài nguyên được yêu cầu và trường Máy chủ có tên máy chủ của máy chủ (ví dụ Host: www.pippo.it:). Tên máy chủ không đi trên dòng yêu cầu (thực tế nó sẽ làGET /hello.htm HTTP/1.1), ngoại trừ khi yêu cầu được gửi tới proxy HTTP (và trong trường hợp này, URL đầy đủ có mặt, bao gồm cả phần giao thức, ví dụ GET http://www.pippo.it/hello.htm HTTP/1.1),


Cảm ơn, bây giờ nó rõ ràng hơn, nhưng không hoàn toàn. Bạn viết rằng trình duyệt phải đưa ra yêu cầu DNS. Ok, nhưng sau khi nhận được IP từ máy chủ DNS, làm thế nào để sử dụng nó? Ý tôi là, IP như vậy không xuất hiện trong yêu cầu HTTP. Vì vậy, tôi cho rằng vẫn còn một bước nữa trước khi đưa ra yêu cầu HTTP và tôi nghĩ đó là việc mở kết nối. Điểm này không rõ ràng với tôi ... Cảm ơn một lần nữa!
Giancarlo Perlo

5
Thật vậy, IP là cần thiết để mở kết nối TCP, trong đó yêu cầu HTTP được vận chuyển. Trên thực tế, địa chỉ IP của cả máy khách và máy chủ được gửi cùng với TẤT CẢ các gói kết nối. Cách tốt nhất để tìm hiểu cách thức hoạt động của nó có lẽ là cài đặt công cụ chụp gói (Wireshark là một nền tảng đa nền tảng và nguồn mở tuyệt vời), nắm bắt một yêu cầu HTTP đơn giản, lọc nó khỏi phần còn lại của hoạt động mạng và xem cách tất cả các gói đã được gửi trên dây. Bạn thực sự cũng có thể thấy yêu cầu DNS trước khi kết nối TCP.
Ale

1
Yêu cầu được ủy quyền nên sử dụng tiêu đề Máy chủ, không đặt URL đầy đủ vào dòng GET.
Ngừng làm hại Monica

1
@OrangeDog: Không, ngược lại. RFC 7230 (phần 5.3.2) nói rõ rằng khách hàng đưa ra yêu cầu tới proxy PHẢI sử dụng URI tuyệt đối trong dòng yêu cầu. (Có phải vẫn là một tiêu đề chủ sao chép thông tin từ dòng yêu cầu; phần 5.4).
Henning Makholm

7

Thủ tục như sau:

  1. Người dùng (bạn) cung cấp cho trình duyệt một URL, như http://www.pippo.it/hello.htm
  2. Trình duyệt chia thành ba phần:

    • Giao thức http
    • Tên máy chủ www.pippo.it
    • Đường dẫn URL /hello.htm

    (một URL phức tạp hơn cũng có thể có các phần khác, tôi sẽ bỏ qua khả năng đó ngay bây giờ)

  3. Trình duyệt biết rằng để tạo kết nối IP, nó cần một địa chỉ IP. Để có được địa chỉ IP, nó cần sử dụng DNS (trừ khi nó có địa chỉ được lưu trong bộ nhớ cache).

    1. Trình duyệt yêu cầu hệ điều hành cho địa chỉ IP của máy chủ DNS; giả sử nó được 8.8.8.8.
    2. Trình duyệt xây dựng kết nối nhiều lớp sau:

      • Lớp IP: kết nối với 8.8.8.8
      • Lớp UDP: đặt gói cho cổng đích 53
      • Lớp DNS: tạo yêu cầu DNS cho Abản ghi cho tên máy chủwww.pippo.it

      Tất nhiên tôi đang bỏ qua rất nhiều chi tiết về ví dụ như định dạng chính xác của các gói liên quan.

    3. Trình duyệt nhận được phản hồi DNS (lớp trên cùng của UDP được xếp lớp trên đầu IP, v.v.) cung cấp địa chỉ IP cho www.pippo.it, giả sử nó10.11.12.13
  4. Trình duyệt biết rằng để tạo kết nối TCP, nó cần số cổng. Để có được số cổng, nó tìm kiếm giao thức httptrong bảng bên trong của nó và biết rằng nó nên sử dụng cổng 80.
  5. Trình duyệt xây dựng kết nối nhiều lớp sau:

    • Lớp IP: kết nối với 10.11.12.13
    • Lớp TCP: đặt gói đến cổng đích 80
    • Lớp HTTP: tạo một yêu cầu HTTP cho URL /hello.htmtrên máy chủ www.pippo.it(vì máy tính tại 10.11.12.13có thể đang lưu trữ một số tên miền, vì vậy nó cần biết cái nào là mong muốn)

      GET /hello.htm HTTP/1.1
      Host: www.pippo.it
      ...
      

    Tất nhiên tôi đang bỏ qua tất cả các chi tiết của cái bắt tay TCP và như vậy.

  6. Trình duyệt nhận được phản hồi HTTP (lớp trên đầu TCP được xếp lớp trên đầu IP, v.v.) có chứa nội dung của hello.htm

Và để đo lường tốt, tôi sẽ đề cập rằng trình duyệt hiện kiểm tra nội dung của phản hồi đó và xác định bất kỳ tài nguyên bổ sung nào cần thiết: hình ảnh, CSS, Javascript, v.v. Sau đó, nó lặp lại toàn bộ quá trình cho mỗi tài nguyên đó.


4
Bước 3 thực sự không phải là thứ mà ứng dụng tự làm. Ứng dụng chỉ sử dụng một cái gì đó giống như getaddrinfohoặc gethostbynameyêu cầu HĐH giải quyết địa chỉ cho nó. Ngoài ra, HĐH thường sử dụng nhiều cơ chế để cố gắng tra cứu tên, không chỉ DNS. (Thông thường ít nhất là tệp máy chủ ngoài DNS.)
Håkan Lindqvist

Cảm ơn! Đó là một câu trả lời thực sự ấn tượng và chi tiết và cũng rất hữu ích!
Giancarlo Perlo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.