1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2005-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21-module(httpd_esi). 22 23-export([parse_headers/1, handle_headers/1]). 24 25-include_lib("inets/src/inets_app/inets_internal.hrl"). 26 27 28%%%========================================================================= 29%%% Internal application API 30%%%========================================================================= 31 32%%-------------------------------------------------------------------------- 33%% parse_headers(Data) -> {Headers, Body} 34%% 35%% Data = string() | io_list() 36%% Headers = string() 37%% Body = io_list() 38%% 39%% Description: Parses <Data> and divides it to a header part and a 40%% body part. Note that it is presumed that <Data> starts with a 41%% string including "\r\n\r\n" if there is any header information 42%% present. The returned headers will not contain the HTTP header body 43%% delimiter \r\n. (All header, header delimiters are kept.) 44%% Ex: ["Content-Type : text/html\r\n Connection : closing \r\n\r\n" | 45%% io_list()] --> {"Content-Type : text/html\r\n Connection : closing \r\n", 46%% io_list()} 47%%-------------------------------------------------------------------------- 48parse_headers(Data) -> 49 parse_headers(Data, []). 50 51%%-------------------------------------------------------------------------- 52%% handle_headers(Headers) -> {ok, HTTPHeaders, StatusCode} | 53%% {proceed, AbsPath} 54%% Headers = string() 55%% HTTPHeaders = [{HeaderField, HeaderValue}] 56%% HeaderField = string() 57%% HeaderValue = string() 58%% StatusCode = integer() 59%% 60%% Description: Transforms the plain HTTP header string data received 61%% from the ESI program into a list of header values and an 62%% appropriate HTTP status code. Note if a location header is present 63%% the return value will be {proceed, AbsPath} 64%%-------------------------------------------------------------------------- 65handle_headers("") -> 66 {ok, [], 200}; 67handle_headers(Headers) -> 68 NewHeaders = string:tokens(Headers, ?CRLF), 69 handle_headers(NewHeaders, [], 200, true). 70 71%%%======================================================================== 72%%% Internal functions 73%%%======================================================================== 74parse_headers([], Acc) -> 75 {[], lists:reverse(Acc)}; 76parse_headers([?CR, ?LF, ?CR, ?LF], Acc) -> 77 {lists:reverse(Acc) ++ [?CR, ?LF], []}; 78parse_headers([?CR, ?LF, ?CR, ?LF | Rest], Acc) -> 79 {lists:reverse(Acc) ++ [?CR, ?LF], Rest}; 80parse_headers([Char | Rest], Acc) -> 81 parse_headers(Rest, [Char | Acc]). 82 83handle_headers([], NewHeaders, StatusCode, _) -> 84 {ok, NewHeaders, StatusCode}; 85 86handle_headers([Header | Headers], NewHeaders, StatusCode, NoESIStatus) -> 87 {FieldName, FieldValue} = httpd_response:split_header(Header, []), 88 case FieldName of 89 "location" when NoESIStatus == true -> 90 handle_headers(Headers, 91 [{FieldName, FieldValue} | NewHeaders], 92 302, NoESIStatus); 93 94 "status" -> 95 NewStatusCode = 96 case httpd_util:split(FieldValue," ",2) of 97 {ok,[Code,_]} -> 98 list_to_integer(Code); 99 _ -> 100 200 101 end, 102 handle_headers(Headers, NewHeaders, NewStatusCode, false); 103 _ -> 104 handle_headers(Headers, 105 [{FieldName, FieldValue}| NewHeaders], StatusCode, 106 NoESIStatus) 107 end. 108