| 1939 | #define BRPC_CRLF "\r\n" |
| 1940 | |
| 1941 | void MakeHttpRequestHeaders(butil::IOBuf* out, |
| 1942 | brpc::HttpHeader* h, |
| 1943 | const butil::EndPoint& remote_side) { |
| 1944 | butil::IOBufBuilder os; |
| 1945 | os << HttpMethod2Str(h->method()) << ' '; |
| 1946 | const brpc::URI& uri = h->uri(); |
| 1947 | uri.PrintWithoutHost(os); // host is sent by "Host" header. |
| 1948 | os << " HTTP/" << h->major_version() << '.' |
| 1949 | << h->minor_version() << BRPC_CRLF; |
| 1950 | //rfc 7230#section-5.4: |
| 1951 | //A client MUST send a Host header field in all HTTP/1.1 request |
| 1952 | //messages. If the authority component is missing or undefined for |
| 1953 | //the target URI, then a client MUST send a Host header field with an |
| 1954 | //empty field-value. |
| 1955 | //rfc 7231#sec4.3: |
| 1956 | //the request-target consists of only the host name and port number of |
| 1957 | //the tunnel destination, seperated by a colon. For example, |
| 1958 | //Host: server.example.com:80 |
| 1959 | if (h->GetHeader("host") == NULL) { |
| 1960 | os << "Host: "; |
| 1961 | if (!uri.host().empty()) { |
| 1962 | os << uri.host(); |
| 1963 | if (uri.port() >= 0) { |
| 1964 | os << ':' << uri.port(); |
| 1965 | } |
| 1966 | } else if (remote_side.port != 0) { |
| 1967 | os << remote_side; |
| 1968 | } |
| 1969 | os << BRPC_CRLF; |
| 1970 | } |
| 1971 | if (!h->content_type().empty()) { |
| 1972 | os << "Content-Type: " << h->content_type() |
| 1973 | << BRPC_CRLF; |
| 1974 | } |
| 1975 | for (brpc::HttpHeader::HeaderIterator it = h->HeaderBegin(); |
| 1976 | it != h->HeaderEnd(); ++it) { |
| 1977 | os << it->first << ": " << it->second << BRPC_CRLF; |
| 1978 | } |
| 1979 | if (h->GetHeader("Accept") == NULL) { |
| 1980 | os << "Accept: */*" BRPC_CRLF; |
| 1981 | } |
| 1982 | // The fake "curl" user-agent may let servers return plain-text results. |
| 1983 | if (h->GetHeader("User-Agent") == NULL) { |
| 1984 | os << "User-Agent: brpc/1.0 curl/7.0" BRPC_CRLF; |
| 1985 | } |
| 1986 | const std::string& user_info = h->uri().user_info(); |
| 1987 | if (!user_info.empty() && h->GetHeader("Authorization") == NULL) { |
| 1988 | // NOTE: just assume user_info is well formatted, namely |
| 1989 | // "<user_name>:<password>". Users are very unlikely to add extra |
| 1990 | // characters in this part and even if users did, most of them are |
| 1991 | // invalid and rejected by http_parser_parse_url(). |
| 1992 | std::string encoded_user_info; |
| 1993 | butil::Base64Encode(user_info, &encoded_user_info); |
| 1994 | os << "Authorization: Basic " << encoded_user_info << BRPC_CRLF; |
| 1995 | } |
| 1996 | os << BRPC_CRLF; // CRLF before content |
| 1997 | os.move_to(*out); |
| 1998 | } |
no test coverage detected