1% ----------------------------------------------------------------------
2% BEGIN LICENSE BLOCK
3% Version: CMPL 1.1
4%
5% The contents of this file are subject to the Cisco-style Mozilla Public
6% License Version 1.1 (the "License"); you may not use this file except
7% in compliance with the License.  You may obtain a copy of the License
8% at www.eclipse-clp.org/license.
9%
10% Software distributed under the License is distributed on an "AS IS"
11% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
12% the License for the specific language governing rights and limitations
13% under the License.
14%
15% The Original Code is  The ECLiPSe Constraint Logic Programming System.
16% The Initial Developer of the Original Code is  Cisco Systems, Inc.
17% Portions created by the Initial Developer are
18% Copyright (C) 1991-2006 Cisco Systems, Inc.  All Rights Reserved.
19%
20% Contributor(s): ECRC GmbH
21% Contributor(s): IC-Parc, Imperal College London
22%
23% END LICENSE BLOCK
24%
25% System:	ECLiPSe Constraint Logic Programming System
26% Version:	$Id: http_grammar.pl,v 1.1 2008/06/30 17:43:46 jschimpf Exp $
27% ----------------------------------------------------------------------
28
29/*
30$Id: http_grammar.pl,v 1.1 2008/06/30 17:43:46 jschimpf Exp $
31*/
32/*
33P is a string containing general_header or request_header
34or object_header.
35
36HttpParams is a list of terms representing _interesting_ params, e.g:
37bodyLength(BL).
38
39The DCG is defined according to the http document.
40
41The predicate token list performs the lexical analysis
42*/
43
44:- module(http_grammar).
45
46:- export
47        status/5,
48	header/3,
49	token_to_list/2,
50	list_to_token/2.
51
52
53% status line
54status(Version, ErrorCode, ErrorPhrase) -->
55        version(Version), errorCode(ErrorCode), errorPhrase(ErrorPhrase).
56
57version(Version) --> ["HTTP"], [/], [Version].
58errorCode(ErrorCode)--> [ErrorCode].
59errorPhrase(ErrorPhrase) --> error_list(ErrorWords),
60        {concat_string(ErrorWords, ErrorPhrase)}.
61
62error_list([X, " "|T]) --> [X], error_list(T).
63error_list([]) --> [].
64
65
66% header
67header(P) --> gene_head(P) ; requ_head(P) ; resp_head(P) ; obje_head(P).
68
69% general header fields
70gene_head(connection(L)) --> ["Connection"], [:], connect_option_list(L).
71gene_head(keepAlive(T)) --> ["Keep"], [-], ["Alive"], [:], [T], {number(T)}.
72gene_head(date(D)) --> ["Date"], [:], date(D).
73gene_head(forwarded) --> ["Forwarded"], [:], forwarded.
74gene_head(mandatory) --> ["Mandatory"], [:], mandatory.
75gene_head(messageId) --> ["Message"], [-], ["ID"], [:], address_spec.
76gene_head(messageId) --> ["Message"], [-], ["id"], [:], address_spec.
77gene_head(mimeVersion) --> ["MIME"], [-], ["Version"], [:], mimeVersion.
78gene_head(mimeVersion) --> ["MIME"], [-], [version], [:], mimeVersion.
79
80
81connect_option_list([C|T]) --> connect_option(C), sep, connect_option_list(T).
82connect_option_list([C]) --> connect_option(C).
83
84connect_option(C) --> [T], [=],[W],
85	{stratom(T), stratom(W), concat_string([T, =, W], C)}.
86connect_option(C) --> [C], {stratom(C)}.
87
88date(D) --> rest(D).
89forwarded --> rest.
90mandatory --> rest.
91address_spec --> rest.
92mimeVersion --> rest.
93
94% request header fields
95requ_head(userAgent) --> ["User"], [-], ["Agent"], [:], user_agent.
96requ_head(userAgent) --> ["User"], [-], [agent], [:], user_agent.
97requ_head(ifModifiedSince(D)) --> ["If"], [-], ["Modified"], [-], ["Since"],
98	[:], http_date(D).
99requ_head(pragma) --> ["Pragma"], [:], pragma.
100requ_head(authorization) --> ["Authorization"], [:], authorization.
101requ_head(proxyAuthorization) --> ["Proxy"], [-], ["Authorization"], [:],
102	proxy_authorization.
103requ_head(proxyAuthorization) --> ["Proxy"], [-], [authorization], [:],
104	proxy_authorization.
105requ_head(referer) --> ["Referer"], [:], uri.
106requ_head(from) --> ["From"], [:], from.
107% !!!!!!!!!!!!!
108requ_head(from) --> ["Host"], [:], from. % HACK netscape 2.0beta !!!
109% !!!!!!!!!!!!!!!!
110requ_head(acceptMediaType(MediaTypeList)) --> ["Accept"], [:],
111	media_type(MediaTypeList).
112requ_head(accept_encoding) --> ["Accept"], [-], ["Encoding"], [:],
113	encoding.
114requ_head(accept_encoding) --> ["Accept"], [-], [encoding], [:],
115	encoding.
116requ_head(accept_charset) --> ["Accept"], [-], ["Charset"], [:],
117	charset.
118requ_head(accept_charset) --> ["Accept"], [-], [charset], [:],
119	charset.
120requ_head(acceptLanguage) --> ["Accept"], [-], ["Language"], [:],
121	language.
122requ_head(acceptLanguage) --> ["Accept"], [-], [language], [:],
123	language.
124
125
126user_agent --> rest.
127http_date(D) --> rest(D).
128pragma --> rest.
129authorization --> rest.
130proxy_authorization --> rest.
131uri --> rest.
132from --> rest.
133media_type_list([MediaType|L]) --> media_type(MediaType), media_type_list(L).
134media_typelist([]) --> [].
135encoding --> rest.
136charset --> rest.
137language --> rest.
138
139media_type(mt(T, ST)) --> type_subtype(T, ST).
140%media_type(mt(T, ST)) --> type_subtype(T, ST), [;], rest.
141
142type_subtype(*, *) --> ['*/*'].
143type_subtype(T, *) --> ttype(T), ['/*'].
144type_subtype(*, ST) --> ['*/'], subtype(ST).
145type_subtype(T, ST) --> ttype(T), [/], subtype(ST).
146
147ttype(T) --> [T], {stratom(T)}; [T], [-], rest, {stratom(T)}.
148subtype(ST) --> [ST], {stratom(ST)}; [ST], [-], rest, {stratom(ST)}.
149
150% response header fields
151resp_head(server) --> ["Server"], [:], server.
152resp_head(wwwAuthenticate) --> ["WWW"], [-], ["Authenticate"], [:], www_authenticate.
153resp_head(wwwAuthenticate) --> ["WWW"], [-], [authenticate], [:], www_authenticate.
154resp_head(proxyAuthenticate) --> ["Proxy"], [-], ["Authenticate"], [:],
155	proxy_authenticate.
156resp_head(proxyAuthenticate) --> ["Proxy"], [-], [authenticate], [:],
157	proxy_authenticate.
158resp_head(retryAfter) --> ["Retry"], [-], ["After"], [:], retry_after.
159resp_head(retryAfter) --> ["Retry"], [-], [after], [:], retry_after.
160
161server --> rest.
162www_authenticate --> rest.
163proxy_authenticate --> rest.
164retry_after --> rest.
165
166% object header fields
167obje_head(acceptRanges) --> ["Accept"], [-], ["Ranges"], [:], rest.
168obje_head(acceptRanges) --> ["Accept"], [-], ["ranges"], [:], rest.
169obje_head(allow) --> ["Allow"], [:], allow.
170obje_head(contentLength(CL)) --> ["Content"], [-], ["Length"], [:], [CL].
171obje_head(contentLength(CL)) --> ["Content"], [-], [length], [:], [CL].
172obje_head(contentType(CT)) --> ["Content"], [-], ["Type"], [:], media_type(CT).
173obje_head(contentType(CT)) --> ["Content"], [-], [type], [:], media_type(CT).
174obje_head(contentEncoding) --> ["Content"], [-], ["Encoding"], [:], encoding.
175obje_head(contentEncoding) --> ["Content"], [-], [encoding], [:], encoding.
176obje_head(contentTransferEncoding) -->
177	["Content"], [-], ["Transfer"], [-], ["Encoding"],
178	[:], content_transfer_encoding.
179obje_head(contentTransferEncoding) -->
180	["Content"], [-], [transfer], [-], [encoding],
181	[:], content_transfer_encoding.
182obje_head(contentLanguage) --> ["Content"], [-], ["Language"], [:], language.
183obje_head(contentLanguage) --> ["Content"], [-], [language], [:], language.
184obje_head(etag) --> ["ETag"], [:], rest.
185obje_head(etag) --> ["Etag"], [:], rest.
186obje_head(expires(D)) --> ["Expires"], [:], http_date(D).
187obje_head(lastModified(D)) --> ["Last"], [-], ["Modified"], [:], http_date(D).
188obje_head(lastModified(D)) --> ["Last"], [-], [modified], [:], http_date(D).
189obje_head(uriHeader) --> ["URI"], [:], uri_header.
190obje_head(location) --> ["Location"], [:], uri.
191obje_head(version) --> ["Version"], [:], version.
192obje_head(derivedFrom) --> ["Derived"], [-], ["From"], [:], derived_from.
193obje_head(derivedFrom) --> ["Derived"], [-], [from], [:], derived_from.
194obje_head(title) --> ["Title"], [:], title.
195obje_head(link) --> ["Link"], [:], link.
196obje_head(link) --> ["X"], [-], ["Pad"], rest.
197
198allow --> rest.
199content_transfer_encoding --> rest.
200uri_header --> rest.
201version --> rest.
202derived_from --> rest.
203title --> rest.
204link --> rest.
205
206% common
207rest --> [], !.
208rest --> [_], rest.
209
210rest([]) --> [], !.
211rest([H|T]) --> [H],!, rest(T).
212rest(Val) --> [Val].
213
214sep --> [","], ssep.
215ssep --> [] ; [","].
216
217
218/*
219correspondance between a stream and a list of token.
220Used for lexical analysis (token_to_list).
221Used for pretty printing  (list_to_token).
222*/
223
224token_to_list(Stream, List):-
225	read_token(Stream, T, _),
226	( T == end_of_file
227          -> List = []
228        ;  List = [T|L],
229	 token_to_list(Stream, L)
230        ).
231
232list_to_token([X|_], _):-
233	var(X), !.
234list_to_token([X|L], S):-
235	write(S, X),
236	list_to_token(L, S).
237
238stratom(X) :- string(X).
239stratom(X) :- atom(X).
240