Compare commits

..

238 Commits

Author SHA1 Message Date
Jocelyn Fiat
25218996e0 Fixed compilation of draft/library/server/request/rest/tests/..
Note the "rest" library will not be maintained since this is not REST.
2012-03-13 18:41:32 +01:00
Jocelyn Fiat
68dbbdea9f precise that library/server/request/router is now part of "wsf" library and not anymore independant library. 2012-03-13 18:09:16 +01:00
Jocelyn Fiat
5abc79b7c3 Nino connector:
- fixed issue related to `ready_for_reading'  now use the `try_...' variant
 - for now Nino does not support persistent connection, then we have to respond with "Connection: close"

REQUEST_FILE_SYSTEM_HANDLER:
 - added not_found_handler and access_denied_handler, so that the user can customize related response

WSF_REQUEST and WSF_VALUE:
 - modified how uploaded file are handled, fixed various issues, and added WSF_UPLOADED_FILE (it is a WSF_VALUE)

WSF_VALUE:
 - added change_name (a_name: like name)
 - added url_encoded_name to other WSF_values

WSF_REQUEST:
 - added `destroy' to perform end of request cleaning (such as deleting temp uploaded files)
 - renamed `raw_post_data_recorded' as `raw_input_data_recorded', and related feature
 - do not store the RAW_POST_DATA in meta variable anymore, but in WSF_REQUEST.raw_input_data is asked

Added WSF_HTML_PAGE_RESPONSE to help user

WSF_REPONSE.redirect_... now use "temp_redirect" as default
  instead of "moved_permanently" which is specific usage

Removed many obsolete features.
2012-03-13 18:07:28 +01:00
Jocelyn Fiat
c5fe539acb use https:// url for git submodules 2012-02-29 17:23:34 +01:00
Jocelyn Fiat
ac3e969b3c Added assertions to catch if route mapping does not already exists 2012-02-29 11:27:46 +01:00
Jocelyn Fiat
98f2efbd68 Merging changes from Javier
Updated restbucksCRUD example, and related class in wsf/router
2012-02-28 09:23:09 +01:00
Jocelyn Fiat
7314e92fe6 Synchronized with nino and json library 2012-02-28 09:20:08 +01:00
jvelilla
468b2851be Refactor REQUEST_RESOURCE_HANDLER_HELPER to figure out the
transfer encoding: Chunked.
Added a new method to retrieve_data independently if the
transfer is chunked or not.
Updated ORDER_HANLDER to use this new feature.
Sync with Jocelyn repo
2012-02-17 08:48:27 -03:00
jvelilla
f1fe5464c6 Merge branch 'master' of git://github.com/jocelyn/Eiffel-Web-Framework 2012-02-17 07:28:57 -03:00
Jocelyn Fiat
d621987020 Minor correction, to avoid returning 200 as status code, when the client can not connect 2012-02-16 10:32:24 +01:00
Jocelyn Fiat
e541fdcb0c fixed compilation 2012-02-15 12:36:57 +01:00
Jocelyn Fiat
5950d768c9 sync with cURL library 2012-02-15 11:58:32 +01:00
Jocelyn Fiat
413fdaf6cd Fixed error visitor due to recent signature changes 2012-02-15 11:33:39 +01:00
Jocelyn Fiat
9138ffedfb renamed (add|remove)_synchronized_handler as (add|remove)_synchronization 2012-02-15 11:07:12 +01:00
Jocelyn Fiat
72cc05532c Removed tests target from encoder(-safe).ecf
(now there is a tests-safe.ecf in folder tests)
2012-02-15 11:04:42 +01:00
Jocelyn Fiat
145b129b28 Fixed ERROR_HANDLER.destroy
Fixed and export ERROR_HANDLER.remove_synchronized_handler
Added comments
Added associated autotests
2012-02-15 11:03:30 +01:00
Jocelyn Fiat
fbec89f354 Better signature for encoders
Split library .ecf and the autotest .ecf
2012-02-14 18:03:42 +01:00
Jocelyn Fiat
f59d5cac32 added postcondition to ensure the body string set to the response, is the same reference
this is important, since sometime we just do
  rep.set_body (s)
  s.append_string ("..")
2012-02-14 18:02:14 +01:00
Jocelyn Fiat
4bb8a71c1b Added DEBUG_OUTPUT to ERROR, since this is convenient during debugging 2012-02-14 18:01:17 +01:00
Jocelyn Fiat
dd6b74326e Added notion of synchronization between error handler
this is convenient to integrate two components using their own ERROR_HANDLER (not sharing the same object)
2012-02-14 12:57:01 +01:00
Jocelyn Fiat
e52cd6b352 use WSF_PAGE_RESPONSE, instead of reimplementing it ourself 2012-02-14 10:20:15 +01:00
Jocelyn Fiat
537bd8241f added a JSON encoder test case 2012-02-13 14:38:13 +01:00
Jocelyn Fiat
040c1d1c10 Merge pull request #9 from oligot/fix-libfcgi-location
[FIX] libfcgi.so location
2012-02-13 03:21:29 -08:00
Olivier Ligot
f3c779cf6e [FIX] libfcgi.so location
On Ubuntu 10.04 LTS, libfcgi.so is in /usr/lib instead of /usr/local/lib
2012-02-10 14:01:04 +01:00
Jocelyn Fiat
6cf35e90c6 added a case in test_json_encoder 2012-02-08 21:36:49 +01:00
unknown
497fe03d38 libcurl: Applied a workaround to avoid issue on Win32 (see LIBCURL_HTTP_CLIENT_REQUEST.apply_workaround)
Separated the http_client-safe.ecf and test-safe.ecf
Added HTTP_CLIENT_SESSION.set_max_redirects
Fixed broken test due to formatting trouble.
2012-02-08 21:32:25 +01:00
Jocelyn Fiat
ca3a520bb9 fixed http_client tests 2012-02-08 16:36:54 +01:00
jvelilla
3c755019aa Updated content 2012-02-08 08:47:39 -03:00
Jocelyn Fiat
3a9b67c8ad Better code to test similar functions but with chunked input 2012-02-07 16:05:19 +01:00
Jocelyn Fiat
e21da4a591 Improved the WSF_PAGE_RESPONSE to be more flexible and allow to change some values as expected. 2012-02-07 15:49:02 +01:00
Jocelyn Fiat
69bc4d568c Added support for chunked input data (see Transfer-Encoding: chunked) 2012-02-07 15:47:55 +01:00
Jocelyn Fiat
cf8d25c4e5 Added HTTP_HEADER.append_header_object and append_array.
This is helpful to "merge" two HTTP_HEADER and provide user friendly features
2012-02-07 15:45:44 +01:00
Jocelyn Fiat
2b9ca86501 Added proxy, at least to make it is possible to use http://fiddler2.com/ to inspect the traffic. 2012-02-07 15:44:45 +01:00
Jocelyn Fiat
2f43660628 Merge branch 'master' of https://github.com/jvelilla/Eiffel-Web-Framework 2012-02-07 15:13:59 +01:00
Jocelyn Fiat
d8476edf36 Fixed wrong code for postcondition on HTTP_HEADER.string
Patch provided by Paul-G.Crismer
2012-02-01 16:53:24 +01:00
Jocelyn Fiat
67e6b460b3 removed unwanted set_status_code, since we already use put_header to set the status code. 2012-02-01 16:05:30 +01:00
Jocelyn Fiat
962154fc81 Eventually fixing trouble with c_strlen being over capacity
(added this for testing, and while waiting a fix from EiffelcURL)
2012-02-01 11:57:42 +01:00
Jocelyn Fiat
645b35590b Improved redirect_now_custom to allow custom status code, custom header, and custom content 2012-02-01 10:57:52 +01:00
Jocelyn Fiat
a1354136fa Fixed usage of lst[] in web form, now we are url-decoding the name because the [] could escaped...
Fixed bad code for assertion related to variable url-encoded name
2012-01-31 17:57:59 +01:00
Jocelyn Fiat
945ef79857 added REQUEST_HANDLER_CONTEXT.string_array_path_parameter (...) to help user handling list/array parameters
fixed postcondition WSF_REQUEST.set_meta_string_variable ...
2012-01-31 12:12:41 +01:00
Jocelyn Fiat
2c4df29877 Make sure to return a response
Added precondition to check URI_TEMPLATE is valid
2012-01-25 16:27:22 +01:00
Jocelyn Fiat
e6687c7791 Fixed wrong assertion, status_committed instead of status_set 2012-01-24 16:47:12 +01:00
Jocelyn Fiat
754d3f670c Fixed issue with WSF_FILE_RESPONSE not setting the status code
Added Last-Modified
2012-01-23 18:20:25 +01:00
Jocelyn Fiat
8e420de8ec Fixed wrong code for postcondition in unset_orig_path_info 2012-01-23 15:32:11 +01:00
Jocelyn Fiat
6dc1c0d2b0 Removed most of the "retry" in rescue clauses, since it was hidding critical issue.
This should be the choice of the application to "retry" on exception, otherwise let the framework handle this in the lower part.

Better handling of response termination (alias commit)
Added the notion of "status_committed"
2012-01-23 15:31:34 +01:00
Jocelyn Fiat
80d68699b1 added "conversion" to ease the use of HTTP_HEADER 2012-01-23 15:28:06 +01:00
Jocelyn Fiat
fcdf4e456e fixed compilation (was not up to date with tests.ecf) 2012-01-20 20:04:56 +01:00
Jocelyn Fiat
c92c2a91b4 Corrected remaining issue related to recent addition of REQUEST_ROUTER.make_with_base_url
And applied removal of format_name and format_id, and replaced by accepted_format_name, ...
2012-01-20 18:55:03 +01:00
Jocelyn Fiat
da9fa4ecc2 Do not add again ctx.headers, since it is already "imported" during the creation of Current request
(see HTTP_CLIENT_REQUEST.make)
2012-01-20 15:37:04 +01:00
Jocelyn Fiat
abdd68863d Removed any "format" related query from router lib, this is too application specific to be there.
Better handling of base_url for REQUEST_ROUTER
2012-01-20 15:35:03 +01:00
Jocelyn Fiat
83a8ad3879 separate library .ecf and tests .ecf
merged tests .ecf for draft 05 and current implementation
2012-01-19 14:34:04 +01:00
Jocelyn Fiat
1b55b09b64 Fixed WSF_REQUEST.script_url (..) for clean path
Added related autotests
2012-01-19 10:25:53 +01:00
Jocelyn Fiat
4cf3393a13 Don't forget to put Content-Length: 0 for redirect without any content 2012-01-17 17:37:26 +01:00
Jocelyn Fiat
4486df14cc export handler from REQUEST_ROUTER 2012-01-17 07:51:26 -08:00
Jocelyn Fiat
60574ee85f REQUEST_ROUTER now inherit from ITERABLE [..] 2012-01-17 16:35:52 +01:00
Jocelyn Fiat
7a6c51e47e Send the Status code, as an header line Status: code reason 2012-01-17 16:34:48 +01:00
Jocelyn Fiat
d8c420c4b7 use READABLE_STRING_8 instead of STRING_8 2012-01-17 16:33:40 +01:00
Jocelyn Fiat
790aa40591 According to http://www.fastcgi.com/docs/faq.html#httpstatus
send the Status code, as an header line  Status: code reason
2012-01-17 13:49:04 +01:00
Jocelyn Fiat
e506397406 Do not send any Status line back to the FastCGI client 2012-01-16 13:49:38 +01:00
Jocelyn Fiat
434f031680 Synchronized with ejson library
Cleaned JSON_ENCODER
2012-01-13 19:04:26 +01:00
Jocelyn Fiat
e36533bc99 Added JSON_ENCODER 2012-01-12 10:38:43 +01:00
Jocelyn Fiat
d90ecbd5fe removed obsolete call on WSF_RESPONSE.write_..' by using the up-to-date WSF_RESPONSE.put_..' 2012-01-09 10:21:35 +01:00
Jocelyn Fiat
20281bc922 HTTP_HEADER: - added put_last_modified
- added RFC1123 http date format helper
             - added put_cookie_with_expiration_date as DATE_TIME
REQUEST: added `execution_variable' to provide a way to keep object attached to the request
         and indexed by a string. A typical usage is a SESSION object
2012-01-06 18:27:52 +01:00
jvelilla
6b3a2d3b43 Update examples/restbucksCRUD/readme.md 2011-12-21 15:40:03 -02:00
Jocelyn Fiat
83346c92a7 added REQUEST.execution_variables ... to provide a solution to store data during request execution
could be used for SESSION, or any "shared" data inside the same Request
2011-12-18 12:57:24 +01:00
Jocelyn Fiat
6b50ab8c55 applied write_ as put_ renaming to examples 2011-12-18 12:55:42 +01:00
Jocelyn Fiat
c8efa04147 Use put_ instead of write_ 2011-12-15 23:52:53 +01:00
Jocelyn Fiat
37860f43b5 various minor changes 2011-12-15 23:38:34 +01:00
Jocelyn Fiat
65a998cec3 use /usr/lib/libfcgi.so instead of /usr/local/lib/libfcgi.so 2011-12-15 20:10:31 +01:00
Jocelyn Fiat
7207a021be Applied renaming from write_ to put_ 2011-12-15 19:34:20 +01:00
Jocelyn Fiat
32373addfa Renamed write_ feature as put_ 2011-12-15 19:04:26 +01:00
Jocelyn Fiat
e16f03b1c2 Fixed stupid mistake in {WGI_NINO_INPUT_SREEAM}.end_of_input 2011-12-15 15:36:47 +01:00
Jocelyn Fiat
1698a06ea0 Fixed typo and missing uri_template reference for draft rest library 2011-12-15 14:40:43 +01:00
Jocelyn Fiat
da3594db50 Now the 'router' library is part of 'wsf'
Move hello_routed_world under tests/dev since it was not really an example, but more a dev workspace/test
2011-12-15 14:10:52 +01:00
Jocelyn Fiat
bfa620eee3 Made DEFAULT_SERVICE_LAUNCHER more flexible for the user. 2011-12-15 13:30:19 +01:00
jvelilla
1423412f31 Update read_trailer feature. 2011-12-15 09:18:37 -03:00
jvelilla
0f51925ec1 Initial implementation of wgi_chunked_input_stream
as a wrapper of wgi_input_stream
2011-12-15 08:53:50 -03:00
Jocelyn Fiat
b6784ee35c Use port 9090 for restbuck server
mainly to avoid using 80 or 8080 which are often already used (by current webserver, or even skype, or jenkins, or ...)
2011-12-14 16:34:01 +01:00
Jocelyn Fiat
ab5b43d8ef Forgot to add make_and_launch_with_options to the creation procedures 2011-12-14 15:04:29 +01:00
Jocelyn Fiat
c7366615cf Added DEFAULT_SERVICE_LAUNCHER.make_and_launch_with_options
Added WSF_RESPONSE.redirect_now_with_content (...)
Updated hello_routed_world .. mainly example use to test/develop... not really a nice example
2011-12-14 14:44:06 +01:00
Jocelyn Fiat
b60c41ee1b Updated readme on how to get source code 2011-12-13 11:43:24 +01:00
Jocelyn Fiat
f9dfeb0034 added head and bottom value in WSF_FILE_RESPONSE, to enable the user to set a head and bottom part easily 2011-12-13 10:35:49 +01:00
Jocelyn Fiat
5e35bc59a9 avoid infinite rescue due to internal error or user code not dealing well with socket disconnection 2011-12-12 21:19:45 +01:00
Jocelyn Fiat
2ed6d92e53 Removed dotnet target for now 2011-12-12 21:18:35 +01:00
Jocelyn Fiat
33d3071cad Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework 2011-12-12 18:57:09 +01:00
Jocelyn Fiat
35dde23976 Fixed http_client autotest code 2011-12-12 18:50:40 +01:00
Jocelyn Fiat
390c05b056 Break inheritance from WGI_RESPONSE, since it is not flexible for future improvement. 2011-12-12 18:24:46 +01:00
Jocelyn Fiat
011f8746d6 Fixed HTTP client callers 2011-12-12 18:17:39 +01:00
Jocelyn Fiat
0335226e8b Renamed DEFAULT_SERVICE as DEFAULT_SERVICE_LAUNCHER 2011-12-12 18:17:27 +01:00
Jocelyn Fiat
68e4ac9a8f Fixed WSF_FILE_RESPONSE
and added WSF_FORCE_DOWNLOAD_RESPONSE
2011-12-12 16:20:06 +01:00
Jocelyn Fiat
f6b293d4ae Merge changes from Javier
- update on RESTbuck examples
- new example
- fixed bad typo in WSF_REQUEST

Reverted some changes such as
- http_client_response: keep the headers as a list to handle multiple message-value with same message-name

Fixed simple and simple_file example
Improved HTTP_HEADER

Changed libcurl implementation for http client
- now the header from the context really overwrite any of the session headers
- better design which is more strict, and remove any doubt about context's header usage
2011-12-12 16:03:38 +01:00
Jocelyn Fiat
89572b4f33 Removed any (put|write)_file_content from the WSF_ or WGI_ OUTPUT classes
Now DEFAULT_SERVICE has to be created instead of inherited.
   - This seems to be better for new user, and this avoid potential conflict and difference when inheriting between the various DEFAULT_SERVICE implementation.
   - remember that DEFAULT_SERVICE, is mainly to help the user to build its very first service.
Use READABLE_STRING_8 as argument whenever it is possible.
Added WSF_RESPONSE_MESSAGE, and WSF_RESPONSE.put_response (a_response_message)
Now WSF_RESPONSE inherit from WGI_RESPONSE
2011-12-12 11:16:15 +01:00
jvelilla
52e6944f37 Merge branch 'master' of github.com:jvelilla/Eiffel-Web-Framework 2011-12-10 18:06:39 -03:00
jvelilla
bf056154d8 Update restbuck client, create and read an order.
Update JSON converter, the id is not important, applied the DRY principle.
Update the ORDER_HANDLER to use the meta_string_variable instead of meta_variable from req.
Fix, the key in meta_variable_table, use c.key instead of c.item
2011-12-10 18:05:41 -03:00
jvelilla
a3c50956f1 Update examples/restbucksCRUD/readme.md 2011-12-10 11:02:20 -02:00
jvelilla
0d67533c83 Merge branch 'master' of github.com:jvelilla/Eiffel-Web-Framework 2011-12-09 21:14:18 -03:00
jvelilla
c0c206e9ae Update the restbuck_client, still work in progress.
Update restbuck_server, remove unused class in inherit.
Update libcurl_http_client_request, to parse context headers before the
execution.
Update wgi_input_stream, commented precondition.
2011-12-09 21:11:16 -03:00
jvelilla
36601fd3a4 Update examples/restbucksCRUD/readme.md 2011-12-09 19:16:07 -02:00
jvelilla
9a85c24c0d Update examples/restbucksCRUD/readme.md 2011-12-09 19:15:33 -02:00
jvelilla
5ef19021eb Update examples/restbucksCRUD/readme.md 2011-12-09 19:10:09 -02:00
jvelilla
7495d0e6a7 Update examples/restbucksCRUD/readme.md 2011-12-09 19:00:58 -02:00
jvelilla
f27c1f97a3 Update examples/restbucksCRUD/readme.md 2011-12-09 18:59:23 -02:00
jvelilla
b96029a750 Update examples/restbucksCRUD/readme.md 2011-12-09 18:56:49 -02:00
jvelilla
9ef10c749a Update examples/restbucksCRUD/readme.md 2011-12-09 18:45:50 -02:00
jvelilla
0aa3d81b22 Update examples/restbucksCRUD/readme.md 2011-12-09 18:44:21 -02:00
jvelilla
5d17b0dd29 Update examples/restbucksCRUD/readme.md 2011-12-09 17:24:01 -02:00
jvelilla
5e2c2af18a Update examples/restbucksCRUD/readme.md 2011-12-09 11:57:47 -02:00
jvelilla
de157be6f1 Update examples/restbucksCRUD/readme.md 2011-12-09 11:57:04 -02:00
jvelilla
f601ae1c8b Update examples/restbucksCRUD/readme.md 2011-12-09 11:52:18 -02:00
jvelilla
f6f94add80 Update examples/restbucksCRUD/readme.md 2011-12-09 11:43:58 -02:00
jvelilla
a70e75f729 Update examples/restbucksCRUD/readme.md 2011-12-09 11:41:58 -02:00
jvelilla
2dd43ad829 Update examples/restbucksCRUD/readme.md 2011-12-09 11:02:31 -02:00
jvelilla
108396bd91 Update examples/restbucksCRUD/readme.md 2011-12-09 10:56:58 -02:00
jvelilla
e9b7fc4c93 Update examples/restbucksCRUD/readme.md 2011-12-08 20:28:14 -02:00
jvelilla
0dd2812574 Updated documentation 2011-12-08 20:04:39 -02:00
jvelilla
d961544b8b Updated restbucksCRUD documentation 2011-12-08 18:48:50 -03:00
jvelilla
3313e9cf81 Added basic two basic examples, refactor rename restbucks
to restbucksCRUD
2011-12-08 18:43:29 -03:00
jvelilla
39b5a70979 Sync Jocelyn repo 2011-12-07 07:22:51 -03:00
Jocelyn Fiat
379e806166 Update README.md 2011-12-03 14:55:55 +01:00
Jocelyn Fiat
c1e08a1bdc Update README.md 2011-12-03 14:55:28 +01:00
Jocelyn Fiat
af21520e5d Update README.md 2011-12-03 14:42:09 +01:00
Jocelyn Fiat
effc6ba81d fixed markdown syntax 2011-12-03 14:40:54 +01:00
Jocelyn Fiat
019fb539ae Remove any useless library include from this .ecf
we just need default_"connector", router, wsf and http
2011-12-02 13:50:39 +01:00
Jocelyn Fiat
03938b43c3 Fixed compilation issue for CGI and libFCGI connector
due to recent changes in interface  (use READABLE_STRING_8)
2011-12-02 12:05:07 +01:00
Jocelyn Fiat
e70d67aed5 Integrated new system to handle form_parameter, input_data in relation with MIME handling
This is not yet clear how to let the user precise its own MIME handler
but it is in progress
2011-12-01 19:12:26 +01:00
Jocelyn Fiat
de38f46d1d fixed remaining issue or useless code to set http environment variable 2011-12-01 18:41:51 +01:00
Jocelyn Fiat
8c79a64f0c Fixed stupid error where we were concatenating ... value by error 2011-12-01 18:38:26 +01:00
Jocelyn Fiat
fff7a5c96d Added WSF_RESPONSE.write_chunk (s: ?READABLE_STRING_8)
to help user sending chunk with "Transfer-Encoding: chunked"
2011-12-01 18:22:47 +01:00
Jocelyn Fiat
1b92403045 Synchronized with Nino 2011-12-01 17:59:35 +01:00
Jocelyn Fiat
8ae4a30ee8 Fixed WSF_RESPONSE.redirect* features 2011-12-01 17:52:31 +01:00
Jocelyn Fiat
8ffe2a8f73 sync with Nino, call to put_readable_string_8 2011-12-01 17:52:00 +01:00
Jocelyn Fiat
769f2bb5a8 Synchronized with EiffelWebNino 2011-12-01 15:28:38 +01:00
Jocelyn Fiat
483f065ef1 relative path for README link 2011-12-01 15:13:15 +01:00
jvelilla
8ff055803d Update library/protocol/CONNEG/README.md 2011-12-01 09:38:13 -02:00
jvelilla
3b30f4b994 Update library/protocol/CONNEG/README.md 2011-12-01 09:34:11 -02:00
jvelilla
f71bbc07e8 Updated Conneg library, added test cases 2011-12-01 08:13:42 -03:00
jvelilla
9b9bc1f190 Fixed minor issue, added test cases to check language negotiation. 2011-11-30 08:56:13 -03:00
jvelilla
6feaf5757f Update conneg library and test cases 2011-11-30 07:15:17 -03:00
Jocelyn Fiat
6f4ec89404 Fixed example due to recent interface changes 2011-11-25 20:44:32 +01:00
Jocelyn Fiat
cdfc6851e7 - (WGI|WSF)_RESPONSE(*) renamed write_headers_string as write_header_text
- HTTP_HEADER.string does not have the ending CRLFCRLF .. but just CRLF
- WGI_RESPONSE.write_header_text has the responsibility to handle the last blank line CRLF (separating the header from the message)
- HTTP_HEADER.string does not set anymore a default content type as text/html
- added WGI_RESPONSE.write_header_lines (ITERABLE [TUPLE [name,value: READABLE_STRING_8]] mainly as an helper method,
   this way the WGI user does not have to know about the CRLF end of line
2011-11-25 20:43:04 +01:00
Jocelyn Fiat
e0ec84611e Applied recent renaming from WGI_RESPONSE_BUFFER as WGI_RESPONSE 2011-11-25 19:21:45 +01:00
Jocelyn Fiat
2234d3712b updated WGI specification 2011-11-25 18:25:50 +01:00
Jocelyn Fiat
c89ccfa768 Added missing wgi_connector 2011-11-25 16:27:46 +01:00
Jocelyn Fiat
1a88388ffe added "redirect" helper feature to WSF_RESPONSE 2011-11-25 16:24:55 +01:00
Jocelyn Fiat
5eab38778a Added `{WGI_REQUEST}.wgi_*' function to WSF_REQUEST 2011-11-25 16:24:26 +01:00
Jocelyn Fiat
9d457bb978 rename application' as service' 2011-11-25 16:22:44 +01:00
Jocelyn Fiat
42be0b2a4e Use HTTP_HEADER instead of WSF_HEADER
(WSF_HEADER is kept for convenience and existing code)
2011-11-25 15:53:15 +01:00
Jocelyn Fiat
48d4d26cda better script to check compilation and tests 2011-11-25 14:52:00 +01:00
Jocelyn Fiat
182749d010 Moved implementation of WSF_HEADER to HTTP_HEADER in the http library 2011-11-25 14:51:46 +01:00
Jocelyn Fiat
fd0912904c Simplified EWSGI interfaces
Renamed WGI_RESPONSE_BUFFER as WGI_RESPONSE to avoid confusion
Removed EWF_HEADER and removed related caller from WGI implementation,
   now this is only part of WSF library
Added wgi_version, wgi_implementation and wgi_connector to the WGI_REQUEST interface
   to give more information to the user
Added back WGI_CONNECTOR to WGI specification, mainly because of `{WGI_REQUEST}.wgi_connector'
   simplified WGI_CONNECTOR to contain for now only `name' and `version'
   if the implementation of connector inherit from WGI_CONNECTOR (recommended)
   this might gives more access to the user using a reverse assignment for specific needs
   (but this usage is not recommended due to portability issue on other connector)
Removed useless connector.ecf since now EWF/WGI library provides the helper classes
2011-11-25 14:39:48 +01:00
Jocelyn Fiat
3032b91ff7 Fixed sample example config file after recent location change for "rest" lib 2011-11-23 18:36:56 +01:00
Jocelyn Fiat
772b88f257 Improved run_CI_tests.py and include the compile_all call directly in the python script.
If compile_all tool supports  -keep ... let's use it. (recent addition)
2011-11-23 16:35:22 +01:00
Jocelyn Fiat
a1cc2d1d1a fixed rest(-safe).ecf due to recent location change 2011-11-23 15:37:01 +01:00
Jocelyn Fiat
9f90bf56a5 Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework 2011-11-23 15:31:47 +01:00
Jocelyn Fiat
dbea0e509b Updated README.md in relation with "rest" lib relocation 2011-11-23 15:27:51 +01:00
Jocelyn Fiat
a3f28e3945 Move "rest" library under "draft/..." since it is more an experiment rather than a real REST library 2011-11-23 15:18:35 +01:00
Jocelyn Fiat
379a6193e9 Update draft/README.md 2011-11-21 18:28:33 +01:00
Jocelyn Fiat
03d9c3785c updated Eiffel libfcgi README file 2011-11-21 17:43:02 +01:00
Jocelyn Fiat
612915c918 Merge branch 'master' of github.com:jocelyn/Eiffel-Web-Framework
Conflicts:
	library/server/libfcgi/Clib/README.md
2011-11-21 17:33:34 +01:00
Jocelyn Fiat
ff967d6332 Added scripts to help building the libfcgi.dll and .lib from modified source of libfcgi
Extracted into "libfcgi" only the files needed to compile the Windows .dll and .lib
2011-11-21 17:07:38 +01:00
Jocelyn Fiat
8d75a04068 Added scripts to help building the libfcgi.dll and .lib from modified source of libfcgi 2011-11-21 16:38:36 +01:00
Jocelyn Fiat
202ad2861b updated README to apply 'ext' renamed as 'contrib' 2011-11-21 14:30:03 +01:00
Jocelyn Fiat
44857d28ec fixed compilation for tests.ecf 2011-11-18 14:56:02 +01:00
Jocelyn Fiat
e3597c0f3b fixed typo 2011-11-18 14:18:30 +01:00
Jocelyn Fiat
0cce4d8244 Updated "draft" folder which contain potential future addition to EWF 2011-11-18 14:18:22 +01:00
Jocelyn Fiat
aab910ab64 Added "draft" folder to contain potential future addition to EWF 2011-11-18 13:56:07 +01:00
Jocelyn Fiat
257ede7586 restructured CONNEG library
fixed various issue in .ecf files
2011-11-18 11:14:30 +01:00
jvelilla
b58e4e19e1 Initial import CONNEG library, support server side
content negotiation.
2011-11-18 10:19:54 +01:00
Jocelyn Fiat
6ec37c90a2 Rename "ext" as "contrib" in compile_all.ini as well
no need to test the code coming from other projects.
2011-11-17 16:03:29 +01:00
Jocelyn Fiat
49c3e8e789 Renamed "ext" folder as "contrib" folder and reorganized a little bit
Renamed any *_APPLICATION as *_SERVICE
   mainly because those components
   such as WSF_APPLICATION, renamed as WSF_SERVICE
   are not always the main application entry, and "service" describe them better
Minor implementation change in WSF_REQUEST
Cosmetics
2011-11-17 15:50:30 +01:00
Jocelyn Fiat
cc11debf08 handle last run failure 2011-11-16 16:18:27 +01:00
Jocelyn Fiat
b71a22d040 Added request method PATCH even if not really used for now, it might in the future 2011-11-16 15:52:00 +01:00
Jocelyn Fiat
7022206a73 Do not print command during script execution 2011-11-16 13:10:35 +01:00
Jocelyn Fiat
b715d674ca fixed indentation in python script 2011-11-16 09:00:23 +01:00
Jocelyn Fiat
02f5bdd801 Added information output to run_CI_tests.py 2011-11-16 08:57:02 +01:00
Jocelyn Fiat
203d51a97e updated run_CI_tests.py 2011-11-16 08:48:24 +01:00
Jocelyn Fiat
733296e71e updated run_CI_tests.py 2011-11-16 08:42:08 +01:00
Jocelyn Fiat
0a497b9a4d updated run_CI_tests.py 2011-11-16 08:34:00 +01:00
Jocelyn Fiat
4ed91a91a2 updated run_CI_tests.py 2011-11-16 07:51:04 +01:00
Jocelyn Fiat
a76eb75267 removed unused local variables 2011-11-16 07:25:29 +01:00
Jocelyn Fiat
2c94a98730 added a python script to be use inside jenkins CI server
(experimental for now)
2011-11-16 07:25:15 +01:00
Jocelyn Fiat
cc960310e9 cosmetic 2011-11-14 19:06:31 +01:00
Jocelyn Fiat
d9daac67d9 cosmetics 2011-11-14 19:05:48 +01:00
Jocelyn Fiat
955f73dee9 Added various README.md (using the markdown syntax) 2011-11-14 19:00:00 +01:00
Jocelyn Fiat
137ed3888c updated README with links to sub READM.md 2011-11-14 18:46:37 +01:00
Jocelyn Fiat
8382e8f134 sync with Eiffel Web Nino 2011-11-14 16:39:26 +01:00
Jocelyn Fiat
0b7ea3c427 Added default WSF_APPLICATION for libfcgi connector 2011-11-14 16:27:55 +01:00
Jocelyn Fiat
1e7b370859 code removal 2011-11-14 16:26:31 +01:00
Jocelyn Fiat
8c02b0d546 Updated libfcgi source code for Windows AND Linux.
Cleaning some code and feature clauses.
2011-11-14 15:44:10 +01:00
Jocelyn Fiat
13b09adc8c Changed the WGI_INPUT_STREAM and WGI_OUTPUT_STREAM interfaces
main changes for existing code  `read_stream' is renamed `read_string'
2011-11-14 14:17:41 +01:00
Jocelyn Fiat
bc2e8b8ee2 Added is_request_method (STRING): BOOLEAN to help users 2011-11-09 18:07:03 +01:00
Jocelyn Fiat
36493b4324 updated readme with better way to get the source code recursively 2011-11-07 11:11:04 +01:00
Jocelyn Fiat
a09908c048 added script to build archive for download area 2011-11-07 01:22:14 -08:00
Jocelyn Fiat
d96ee66a32 sync with Eiffel Web Nino 2011-11-04 20:28:08 +01:00
Jocelyn Fiat
7669ccfc1d sync with nino and applied changes to connector 2011-11-04 20:21:35 +01:00
Jocelyn Fiat
3a6e3592ae Use recent changes from Nino, to get access to the launched and port information.
Quite useful when launching using port=0 to use a random free port.
This is great for testing, this way we can run many tests in the same time without any port blocking.
2011-11-04 12:15:40 +01:00
Jocelyn Fiat
07f9a8cec7 applied recent changes from Nino 2011-11-03 18:50:19 +01:00
Jocelyn Fiat
16cab53fb4 removed compliance on ewsgi, since now we target WSF
applied recent changes related to WSF_VALUE
2011-11-02 16:11:40 +01:00
Jocelyn Fiat
a2bf68e18a Safer interface for WSF_VALUE, when related to STRING value 2011-11-02 15:42:58 +01:00
Jocelyn Fiat
214255c4b9 sync with submodules 2011-11-02 13:30:35 +01:00
Jocelyn Fiat
082b8902ea Merge branch 'master' of git://github.com/Eiffel-World/Eiffel-Web-Framework 2011-11-02 13:11:09 +01:00
Jocelyn Fiat
ee9722fa18 renamed WSF_(.*)_VALUE as WSF_$1 2011-11-02 13:10:35 +01:00
Jocelyn Fiat
4a81d02d12 Fixed obsolete calls, and compilation error. 2011-10-31 18:42:44 +01:00
Jocelyn Fiat
0f5ae7e153 fixed path to cURL.ecf file, using the correct uppercase 2011-10-31 09:14:43 -07:00
Jocelyn Fiat
179dbceaba Fixed missing syntax="provisional" , this was preventing compiling with "across" statements 2011-10-31 16:06:10 +01:00
Jocelyn Fiat
45292e0248 Better implementation to get http header for http_client, and to get list of header entries by key,value 2011-10-31 16:05:34 +01:00
Jocelyn Fiat
a38fca267b Merge branch 'master' of https://github.com/jvelilla/Eiffel-Web-Framework 2011-10-31 12:33:20 +01:00
Jocelyn Fiat
d4266a83ec updated instructions related to submodules 2011-10-31 02:43:44 -07:00
Jocelyn Fiat
83a181ebf1 Fixed remaining 6.8 vs 7.0 compilation issue related to UTF8_(URL_)ENCODER 2011-10-31 09:02:19 +01:00
Jocelyn Fiat
54ecd2b1e8 Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework 2011-10-31 08:48:44 +01:00
Jocelyn Fiat
da8a216448 removed unused local variable 2011-10-31 08:48:19 +01:00
Jocelyn Fiat
085b520879 Added convenient features to BASE64
- decode_string_to_buffer (v: STRING; a_buffer: STRING)
   - decode_string_to_output_medium (v: STRING; a_output: IO_MEDIUM)
2011-10-31 08:45:50 +01:00
Jocelyn Fiat
c115a40922 removed unused local variable 2011-10-31 08:43:04 +01:00
Jocelyn Fiat
6f600362e3 Fixed code to be compilable with EiffelStudio 6.8 and 7.0 (due to recent change in UNICODE_CONVERSION) UNICODE_CONVERSION 2011-10-31 08:42:48 +01:00
jvelilla
bd36aa8b04 Added headers to response in HTTP_CLIENT_RESPONSE 2011-10-28 14:25:26 -03:00
Jocelyn Fiat
812f521c88 Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework 2011-10-27 16:24:40 +02:00
Jocelyn Fiat
beb1bd1599 use '%/123/' syntax, to make sure no editor replace the accentued characters 2011-10-27 16:24:19 +02:00
Jocelyn Fiat
9bbcdc9927 removed unwanted .rc 2011-10-27 16:03:10 +02:00
Jocelyn Fiat
0d637d478a Fixed a previously character changes in WSF_REQUEST (related to safe_filename), and modified the implementation to use inspect
Fixed the request_content_type computation
Cosmetic in REQUEST_RESOURCE_HANDLER_HELPER
2011-10-27 16:00:33 +02:00
Jocelyn Fiat
8e4e7a5084 Merge branch 'master' of https://github.com/jvelilla/Eiffel-Web-Framework
Conflicts:
	library/server/wsf/src/wsf_request.e
2011-10-27 15:49:12 +02:00
Jocelyn Fiat
95d44890d9 added script to update current git working copy and submodules recursively 2011-10-27 14:58:14 +02:00
Jocelyn Fiat
161a5c720b Merge branch 'master' of github.com:jocelyn/Eiffel-Web-Framework 2011-10-27 14:45:37 +02:00
Jocelyn Fiat
35a4cd7df9 cosmetic, or minor changes 2011-10-27 14:45:14 +02:00
Jocelyn Fiat
70ee7ff47a Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework 2011-10-27 14:43:32 +02:00
jvelilla
c9343688f3 Added eel and eapml in EWF libraries.
Removed them from gitmodule
2011-10-27 08:29:01 -03:00
jvelilla
f804a705d5 Updated request resource handler.
TODO: implement Content-Negotiation
2011-10-26 08:21:50 -03:00
Jocelyn Fiat
926c0a79b7 Start index for list[]=a&list[]=b ... from 1 instead of 0
Stick to Eiffel spirit
2011-10-24 17:44:13 +02:00
Jocelyn Fiat
fb7854fbcc Added visitor patterns to WSF_VALUE
Handling UTF-8 unencoding for WSF_VALUE ...
Added WSF_TABLE_VALUE to handle list[]=a&list[]=b ...

Library encoder: added UTF8 facilities
2011-10-24 17:23:36 +02:00
Jocelyn Fiat
663a39d2ec missing implementation (forgot to uncomment) 2011-10-24 09:07:26 +03:00
jvelilla
6fb36da9ac Merge remote-tracking branch 'jocelynEWF/master'
Conflicts:
	examples/restbucks/restbucks-safe.ecf
	examples/restbucks/src/resource/order_handler.e
	library/server/request/router/src/misc/request_resource_handler_helper.e
2011-10-23 20:58:28 -03:00
jvelilla
3fbd81aeb1 Added eel and eapml modules 2011-10-23 09:10:27 -03:00
jvelilla
6344f964fa Update delete method to hanlde method not allowed.
Added method not allowed to request resource handler helper class.
Update gitmodules
2011-10-23 09:05:12 -03:00
Jocelyn Fiat
14a2c01f41 Applied recent changes on WGI_ and WSF_
Moved classes away from ewsgi, restructured, cleaned
2011-10-21 16:58:23 +02:00
Jocelyn Fiat
79e12b8d04 Continued reducing WGI and move implementation to WSF (Web Server Framework)
Removed many usage of READABLE_STRING_GENERAL in favor to READABLE_STRING_8
   to avoid potential nasty issues in user's code
URI-template is working only with STRING_8, then changed any _GENERAL or _STRING_32 to _STRING_8
2011-10-21 16:58:18 +02:00
Jocelyn Fiat
aec0136739 First try to get a limited WGI_ and use WSF_ as default framework 2011-10-21 16:58:11 +02:00
jvelilla
9f53287226 Update Restbucks example: Conditional GET, PUT.
Added a response method to support resource not
modified.
Added a ETAG_UTILS class to calcule md5_digest.
Added ext libs eel and eapml.
2011-10-21 08:26:14 -03:00
jvelilla
8255dfd996 Added handle_resource_conflict_response feature to handle 409 reponse,
Cosmetic.
2011-10-13 09:07:37 -03:00
Jocelyn Fiat
fcdc164214 Added data and file for post and put request methods 2011-10-12 21:45:57 +02:00
564 changed files with 65501 additions and 4990 deletions

18
.gitmodules vendored
View File

@@ -1,12 +1,12 @@
[submodule "doc/wiki"]
path = doc/wiki
url = https://github.com/Eiffel-World/Eiffel-Web-Framework.wiki.git
[submodule "ext/server/nino"]
path = ext/server/nino
url = http://github.com/Eiffel-World/EiffelWebNino.git
[submodule "ext/text/json"]
path = ext/text/json
url = http://github.com/Eiffel-World/ejson-svn.git
[submodule "ext/ise_library/curl"]
path = ext/ise_library/curl
url = http://github.com/EiffelSoftware/mirror-Eiffel-cURL.git
[submodule "contrib/library/server/nino"]
path = contrib/library/server/nino
url = https://github.com/Eiffel-World/EiffelWebNino.git
[submodule "contrib/library/text/parser/json"]
path = contrib/library/text/parser/json
url = https://github.com/Eiffel-World/ejson-svn.git
[submodule "contrib/ise_library/cURL"]
path = contrib/ise_library/cURL
url = https://github.com/EiffelSoftware/mirror-Eiffel-cURL.git

1218
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

1
README
View File

@@ -1 +0,0 @@
README.md

View File

@@ -1,37 +1,80 @@
# Eiffel Web Framework
## Overview
Official project site for Eiffel Web Framework:
* http://eiffel-world.github.com/Eiffel-Web-Framework/
For more information please have a look at the related wiki:
* https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki
How to get the source code?
---------------------------
## Requirements
* Developped using EiffelStudio 7.0 (on Windows, Linux)
* Tested using EiffelStudio 7.0 with "jenkins" CI server (and v6.8 for time to time)
* The code have to allow __void-safe__ compilation and non void-safe system (see [more about void-safety](http://docs.eiffel.com/book/method/void-safe-programming-eiffel) )
## How to get the source code?
Using git version >= 1.6.5
* git clone --recursive https://github.com/Eiffel-World/Eiffel-Web-Framework.git
Otherwise, try
* git clone https://github.com/Eiffel-World/Eiffel-Web-Framework.git
* cd Eiffel-Web-Framework
* git submodule update --init
* git submodule foreach git pull origin master
* git submodule foreach git checkout master
* git submodule foreach --recursive git checkout master
An alternative to the last 2 instructions is to use the script from tools folder:
* cd tools
* update_git_working_copy
* And to build the required and related Clibs
** cd ext/ise_library/curl
** geant compile
* cd contrib/ise_library/cURL
* geant compile
Overview
--------
## Libraries under 'library'
* library/server/ewsgi: Eiffel Web Server Gateway Interface
* library/server/ewsgi/connectors: various web server connectors for EWSGI
* library/server/libfcgi: Wrapper for libfcgi SDK
### server
* __ewsgi__: Eiffel Web Server Gateway Interface [read more](library/server/ewsgi)
* connectors: various web server connectors for EWSGI
* libfcgi: Wrapper for libfcgi SDK
* __wsf__: Web Server Framework [read more](library/server/wsf)
* __router__: URL dispatching/routing based on uri, uri_template, or custom [read more](library/server/wsf/router)
* library/server/request/router: URL dispatching/routing based on uri, uri_template, or custom.
* library/server/request/rest: experimental: RESTful library to help building RESTful services
### protocol
* __http__: HTTP related classes, constants for status code, content types, ... [read more](library/protocol/http)
* __uri_template__: URI Template library (parsing and expander) [read more](library/protocol/uri_template)
* __CONNEG__: CONNEG library (Content-type Negociation) [read more](library/protocol/CONNEG)
* library/protocol/http: HTTP related classes, constants for status code, content types, ...
* library/protocol/uri_template: URI Template library (parsing and expander)
### client
* __http_client__: simple HTTP client based on cURL [read more](library/client/http_client)
### text
* __encoder__: Various simpler encoders: base64, url-encoder, xml entities, html entities [read more](library/text/encoder)
### crypto
* eel
* eapml
### Others
* error: very simple/basic library to handle error
## External libraries under 'contrib'
* [Eiffel Web Nino](contrib/library/server/nino)
* ..
## Draft folder = call for contribution ##
### library/server/request ###
* request
* rest: (experimental) "a" RESTful library to help building RESTful services
## Examples
..
* library/error: very simple/basic library to handle error
* library/text/encoder: Various simpler encoder: base64, url-encoder, xml entities, html entities
For more information please have a look at the related wiki:
* https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki

25
draft/README.md Normal file
View File

@@ -0,0 +1,25 @@
This "draft" folder contains potential addition to EWF
Anyone wanting to contribute is welcome to the listed libraries, or by suggesting/contributing with extra libraries
## Current suggestions ##
### protocol ###
* web syndication [__Atom__](library/protocol/syndication/atom)
* web syndication [__RSS__](library/protocol/syndication/rss)
* [__Twitter__](library/protocol/twitter)
* [__XMPP__](library/protocol/xmpp) (also known as Jabber)
### Security ###
* [__OAuth__](library/security/oauth)
* [__OpenID__](library/security/openid)
### Text ###
* [__Filters__](library/text/filter) : Wiki markup, Markdown, ...
* [__Templates__](library/text/template) : Web template engine ...
### ... ###
Any contribution is welcome, help us make Eiffel Web Framework bigger, richer and better.

View File

@@ -0,0 +1,9 @@
Web Syndication
http://en.wikipedia.org/wiki/Web_syndication
* [Atom Pub](atom)
* [RSS](rss)
* ...
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,10 @@
Atom protocol
http://en.wikipedia.org/wiki/Atom_(standard)
Atom standard
* [RFC 4287](http://tools.ietf.org/html/rfc4287) "The Atom Syndication Format"
* [RFC 5023](http://tools.ietf.org/html/rfc5023) "The Atom Publishing Protocol"
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="atom" uuid="076DEABB-20DA-43E9-A4C7-F3FAEDF5B1FC" library_target="atom">
<target name="atom">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="atom" uuid="076DEABB-20DA-43E9-A4C7-F3FAEDF5B1FC" library_target="atom">
<target name="atom">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,22 @@
note
description: "[
Main interface for ATOM interface
]"
date: "$Date$"
revision: "$Revision$"
class
ATOM
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object
do
check not_yet_implemented: False end
end
end

View File

@@ -0,0 +1,7 @@
RSS protocol
http://en.wikipedia.org/wiki/RSS
* [RSS specification](http://www.rssboard.org/rss-specification)
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="rss" uuid="8D8E3E5A-2685-40AF-9EF9-E3113B3C62AA" library_target="rss">
<target name="rss">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="rss" uuid="8D8E3E5A-2685-40AF-9EF9-E3113B3C62AA" library_target="rss">
<target name="rss">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,22 @@
note
description: "[
Main interface for RSS interface
]"
date: "$Date$"
revision: "$Revision$"
class
RSS
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object
do
check not_yet_implemented: False end
end
end

View File

@@ -0,0 +1,6 @@
Twitter protocol
http://en.wikipedia.org/wiki/Twitter
Eventually move http://bricabrac.origo.ethz.ch/wiki/Eiffel_Twitter here
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,6 @@
XMPP/Jabber protocol
http://en.wikipedia.org/wiki/Xmpp
Eventually move http://bricabrac.origo.ethz.ch/wiki/Eiffel_XMPP here
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,7 @@
OAuth
http://en.wikipedia.org/wiki/Oauth
* [RFC5849](http://tools.ietf.org/html/rfc5849)
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="oauth" uuid="F8B4DF74-C71B-45A3-9B9A-F6141C4D3C56" library_target="oauth">
<target name="oauth">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="oauth" uuid="F8B4DF74-C71B-45A3-9B9A-F6141C4D3C56" library_target="oauth">
<target name="oauth">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,22 @@
note
description: "[
Main interface for OAUTH interface
]"
date: "$Date$"
revision: "$Revision$"
class
OAUTH
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object
do
check not_yet_implemented: False end
end
end

View File

@@ -0,0 +1,5 @@
OpenID
http://en.wikipedia.org/wiki/Openid
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="openid" uuid="E6B80EAB-AC99-46F5-9896-4892D3477A9A" library_target="openid">
<target name="openid">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="openid" uuid="E6B80EAB-AC99-46F5-9896-4892D3477A9A" library_target="openid">
<target name="openid">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<cluster name="src" location="./src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,22 @@
note
description: "[
Main interface for OPENID interface
]"
date: "$Date$"
revision: "$Revision$"
class
OPENID
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object
do
check not_yet_implemented: False end
end
end

View File

@@ -7,12 +7,12 @@
<exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"/>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
<library name="router" location="..\..\request\router\router-safe.ecf" readonly="false"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf"/>
<library name="wsf" location="..\..\..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\..\library\protocol\http\http-safe.ecf"/>
<library name="uri_template" location="..\..\..\..\..\library\protocol\uri_template\uri_template-safe.ecf"/>
<cluster name="contrib" location=".\src\contrib\" recursive="true">
<file_rule>
<exclude>/html$</exclude>

View File

@@ -9,10 +9,9 @@
</file_rule>
<option warning="true" full_class_checking="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf"/>
<library name="http" location="..\..\..\protocol\http\http.ecf"/>
<library name="router" location="..\..\request\router\router.ecf" readonly="false"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/>
<library name="wsf" location="..\..\..\..\..\library\server\wsf\wsf.ecf"/>
<library name="http" location="..\..\..\..\..\library\protocol\http\http.ecf"/>
<library name="uri_template" location="..\..\..\..\..\library\protocol\uri_template\uri_template.ecf"/>
<cluster name="contrib" location=".\src\contrib\" recursive="true">
<file_rule>
<exclude>/html$</exclude>

View File

@@ -31,7 +31,7 @@ feature {NONE} -- Initialization
feature -- Access
headers: EWF_HEADER
headers: HTTP_HEADER
feature -- Recycle
@@ -155,11 +155,11 @@ feature -- Output
Result := o
end
send (buf: WGI_RESPONSE_BUFFER)
send (buf: WSF_RESPONSE)
do
buf.set_status_code (200)
buf.write_headers_string (header_string)
buf.write_string (message_string)
buf.put_header_text (header_string)
buf.put_string (message_string)
end
feature {NONE} -- Implementation: output

View File

@@ -30,13 +30,13 @@ feature {NONE} -- Access: Implementation
feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
end
feature -- Execution
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
rep: like new_html_page
s: STRING
@@ -50,7 +50,7 @@ feature -- Execution
create s.make_empty
if
attached {WGI_STRING_VALUE} ctx.path_parameter ("resource") as l_resource_value and then
attached {WSF_STRING} ctx.path_parameter ("resource") as l_resource_value and then
attached l_resource_value.string as l_resource
then
from
@@ -114,7 +114,7 @@ feature -- Execution
rep.recycle
end
process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_dft_format: detachable STRING)
process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; a_dft_format: detachable STRING)
local
l_dft_format_name: detachable STRING
s: STRING

View File

@@ -0,0 +1,56 @@
note
description: "Summary description for {REST_RESPONSE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
REST_RESPONSE
inherit
WSF_PAGE_RESPONSE
rename
header as headers,
body as message,
set_body as set_message,
put_string as append_message,
make as page_make,
send_to as send
end
create
make
feature {NONE} -- Initialization
make (a_api: like api)
do
api := a_api
page_make
end
feature -- Recycle
recycle
do
headers.recycle
message := Void
end
feature -- Access
api: STRING
-- Associated api query string.
invariant
note
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -23,7 +23,7 @@ create
feature -- status
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
Result := internal_authentication_required
end

View File

@@ -9,13 +9,10 @@ deferred class
inherit
REQUEST_HANDLER [C]
redefine
execute
end
feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
-- Is authentication required
-- might depend on the request environment
-- or the associated resources
@@ -35,53 +32,47 @@ feature -- Element change
feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
local
rescued: BOOLEAN
do
if not rescued then
if request_method_name_supported (req.request_method) then
if authentication_required (req) and then not authenticated (ctx) then
execute_unauthorized (ctx, req, res)
else
pre_execute (ctx, req, res)
execute_application (ctx, req, res)
post_execute (ctx, req, res)
end
if request_method_name_supported (req.request_method) then
if authentication_required (req) and then not authenticated (ctx) then
execute_unauthorized (ctx, req, res)
else
execute_request_method_not_allowed (req, res, supported_request_method_names)
pre_execute (ctx, req, res)
execute_application (ctx, req, res)
post_execute (ctx, req, res)
end
else
rescue_execute (ctx, req, res)
execute_request_method_not_allowed (req, res, supported_request_method_names)
end
rescue
rescued := True
retry
execute_rescue (ctx, req, res)
end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
deferred
end
pre_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
pre_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
end
post_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
post_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
end
rescue_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_rescue (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
post_execute (ctx, req, res)
rescue
--| Just in case, the rescue is raising other exceptions ...
end
execute_unauthorized (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.write_header ({HTTP_STATUS_CODE}.unauthorized, Void)
res.write_string ("Unauthorized")
res.put_header ({HTTP_STATUS_CODE}.unauthorized, Void)
res.put_string ("Unauthorized")
end
feature -- Auth
@@ -241,6 +232,9 @@ feature -- Status report
if method_put_supported then
Result.extend (request_method_constants.method_put)
end
if method_patch_supported then
Result.extend (request_method_constants.method_patch)
end
if method_delete_supported then
Result.extend (request_method_constants.method_delete)
end
@@ -264,6 +258,11 @@ feature -- Status report
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
end
method_patch_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.patch)
end
method_delete_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
@@ -296,6 +295,11 @@ feature -- Element change: request methods
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
end
enable_request_method_patch
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.patch)
end
enable_request_method_delete
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
@@ -314,7 +318,7 @@ feature -- Element change: request methods
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -0,0 +1,131 @@
note
description: "Summary description for {REST_REQUEST_HANDLER_CONTEXT}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REST_REQUEST_HANDLER_CONTEXT
inherit
REQUEST_HANDLER_CONTEXT
feature -- Accept: Content-Type
accepted_content_type: detachable READABLE_STRING_8
do
if internal_accepted_content_type = Void then
get_accepted_content_type (Void)
end
Result := internal_accepted_content_type
end
get_accepted_content_type (a_supported_content_types: detachable ARRAY [STRING_8])
do
if internal_accepted_content_type = Void then
internal_accepted_content_type := request_accepted_content_type (a_supported_content_types)
end
end
feature -- Format name
accepted_format_name: detachable READABLE_STRING_8
do
if internal_accepted_format_name = Void then
get_accepted_format_name (Void, Void)
end
Result := internal_accepted_format_name
end
get_accepted_format_name (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [STRING_8])
do
if internal_accepted_format_name = Void then
internal_accepted_format_name := request_accepted_format (a_format_variable_name, a_supported_content_types)
end
end
feature -- Format id
accepted_format_id: INTEGER
do
if internal_accepted_format_id = 0 then
get_accepted_format_id (Void, Void)
end
Result := internal_accepted_format_id
end
get_accepted_format_id (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [STRING_8])
do
if internal_accepted_format_id = 0 then
internal_accepted_format_id := request_accepted_format_id (a_format_variable_name, a_supported_content_types)
end
end
feature {NONE} -- Constants
Format_constants: HTTP_FORMAT_CONSTANTS
once
create Result
end
feature -- Format
request_accepted_format (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
do
if a_format_variable_name /= Void and then attached string_parameter (a_format_variable_name) as ctx_format then
Result := ctx_format.as_string_8
else
Result := request_format_from_content_type (request_accepted_content_type (a_supported_content_types))
end
end
request_accepted_format_id (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): INTEGER
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
do
if attached request_accepted_format (a_format_variable_name, a_supported_content_types) as l_format then
Result := Format_constants.format_id (l_format)
else
Result := 0
end
end
feature {NONE} -- Format/Content type implementation
request_format_from_content_type (a_content_type: detachable READABLE_STRING_8): detachable READABLE_STRING_8
-- `a_content_type' converted into a request format name
do
if a_content_type /= Void then
if a_content_type.same_string ({HTTP_MIME_TYPES}.text_json) then
Result := {HTTP_FORMAT_CONSTANTS}.json_name
elseif a_content_type.same_string ({HTTP_MIME_TYPES}.application_json) then
Result := {HTTP_FORMAT_CONSTANTS}.json_name
elseif a_content_type.same_string ({HTTP_MIME_TYPES}.text_xml) then
Result := {HTTP_FORMAT_CONSTANTS}.xml_name
elseif a_content_type.same_string ({HTTP_MIME_TYPES}.text_html) then
Result := {HTTP_FORMAT_CONSTANTS}.html_name
elseif a_content_type.same_string ({HTTP_MIME_TYPES}.text_plain) then
Result := {HTTP_FORMAT_CONSTANTS}.text_name
end
end
end
feature {NONE} -- Internal
internal_accepted_content_type: like accepted_content_type
internal_accepted_format_id: like accepted_format_id
internal_accepted_format_name: like accepted_format_name
;note
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {DEFAULT_REST_APPLICATION}."
description: "Summary description for {DEFAULT_REST_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REST_APPLICATION
REST_SERVICE
inherit
REST_APPLICATION_I [REST_REQUEST_HANDLER [REST_REQUEST_HANDLER_CONTEXT], REST_REQUEST_HANDLER_CONTEXT]
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_HANDLER_CONTEXT], REST_REQUEST_HANDLER_CONTEXT]
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {REST_APPLICATION}."
description: "Summary description for {REST_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REST_APPLICATION_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT]
REST_SERVICE_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT]
inherit
ROUTED_APPLICATION_I [H, C]
ROUTED_SERVICE_I [H, C]
redefine
router
end

View File

@@ -18,7 +18,7 @@ create
feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]];
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8])
local
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT]

View File

@@ -25,7 +25,7 @@ create
feature -- Status report
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
Result := internal_authentication_required
end
@@ -36,12 +36,12 @@ feature {NONE} -- Implementation
feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
Precursor {REQUEST_URI_ROUTING_HANDLER_I} (ctx, req, res)
end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
check should_not_occur: False end
end

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {DEFAULT_REST_URI_APPLICATION}."
description: "Summary description for {DEFAULT_REST_URI_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REST_URI_APPLICATION
REST_URI_SERVICE
inherit
REST_APPLICATION_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT]
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT]
redefine
router
end

View File

@@ -14,11 +14,12 @@ inherit
end
create
make
make,
make_with_base_url
feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]];
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8])
local
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
@@ -28,7 +29,7 @@ feature -- Mapping
end
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -13,10 +13,11 @@ inherit
REST_REQUEST_ROUTER [H, C]
create
make
make,
make_with_base_url
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -14,14 +14,15 @@ inherit
end
create
make
make,
make_with_base_url
feature {NONE} -- Routing
router: REST_REQUEST_URI_TEMPLATE_ROUTER
;note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -21,11 +21,12 @@ inherit
end
create
make
make,
make_with_base_url
feature -- Status report
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
Result := internal_authentication_required
end
@@ -36,14 +37,14 @@ feature {NONE} -- Implementation
feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
pre_execute (ctx, req, res)
Precursor {REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I} (ctx, req, res)
post_execute (ctx, req, res)
end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
check should_not_occur: False end
end
@@ -53,7 +54,7 @@ feature {NONE} -- Routing
router: REST_REQUEST_URI_TEMPLATE_ROUTER_I [H, C]
;note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {DEFAULT_URI_TEMPLATE_REST_APPLICATION}."
description: "Summary description for {DEFAULT_URI_TEMPLATE_REST_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REST_URI_TEMPLATE_APPLICATION
REST_URI_TEMPLATE_SERVICE
inherit
REST_APPLICATION_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
redefine
router
end

View File

@@ -12,13 +12,13 @@
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="rest" location="..\rest-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf" readonly="false"/>
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
</target>
<target name="sample_fcgi" extends="common">
<root class="APP_SERVER" feature="make"/>
<setting name="executable_name" value="sample"/>
<library name="ewsgi_fcgi" location="..\..\..\ewsgi/connectors\libfcgi\libfcgi-safe.ecf" readonly="false"/>
<library name="ewsgi_fcgi" location="..\..\..\..\..\..\library\server\ewsgi\connectors\libfcgi\libfcgi-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/gateway$</exclude>
@@ -29,7 +29,7 @@
<target name="sample_cgi" extends="common">
<root class="APP_SERVER" feature="make"/>
<setting name="executable_name" value="sample"/>
<library name="ewsgi_cgi" location="..\..\..\ewsgi/connectors\cgi\cgi-safe.ecf" readonly="false"/>
<library name="ewsgi_cgi" location="..\..\..\..\..\..\library\server\ewsgi\connectors\cgi\cgi-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/gateway$</exclude>
@@ -41,8 +41,8 @@
<target name="sample_nino" extends="common">
<root class="APP_SERVER" feature="make"/>
<setting name="executable_name" value="sample"/>
<library name="ewsgi_nino" location="..\..\..\ewsgi/connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="ewsgi_default_nino" location="..\..\..\ewsgi/default\ewsgi_nino-safe.ecf" readonly="false"/>
<library name="ewsgi_nino" location="..\..\..\..\..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true">

View File

@@ -35,34 +35,34 @@ feature {NONE} -- Initialization
feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
Result := True
end
feature -- Execution
execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local
s: STRING
lst: LIST [STRING]
do
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.write_header ({HTTP_STATUS_CODE}.unauthorized, <<["WWW-Authenticate", "Basic realm=%"My Silly demo auth, password must be the same as login such as foo:foo%""]>>)
res.write_string ("Unauthorized")
res.put_header ({HTTP_STATUS_CODE}.unauthorized, <<["WWW-Authenticate", "Basic realm=%"My Silly demo auth, password must be the same as login such as foo:foo%""]>>)
res.put_string ("Unauthorized")
end
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_full: BOOLEAN
h: EWF_HEADER
h: HTTP_HEADER
l_login: STRING_8
s: STRING
content_type_supported: ARRAY [STRING]
l_format_id: INTEGER
do
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>>
l_format_id := ctx.request_format_id ("format", content_type_supported)
content_type_supported := <<{HTTP_CONSTANTS}.application_json, {HTTP_CONSTANTS}.text_xml, {HTTP_CONSTANTS}.text_plain>>
l_format_id := ctx.request_accepted_format_id ("format", content_type_supported)
if authenticated (ctx) then
l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true")
if attached authenticated_identifier (ctx) as log then
@@ -88,8 +88,8 @@ feature -- Execution
end
if not s.is_empty then
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
res.write_string (s)
res.put_header_text (h.string)
res.put_string (s)
end
else
send_error (ctx.path, 0, "User/password unknown", Void, ctx, req, res)

View File

@@ -32,30 +32,30 @@ feature {NONE} -- Initialization
feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN
authentication_required (req: WSF_REQUEST): BOOLEAN
do
end
feature -- Execution
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
local
s: STRING
h: EWF_HEADER
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_plain
create s.make_empty
s.append_string ("test")
if attached req.meta_variable ("REQUEST_COUNT") as l_request_count_val then
s.append_string ("(request_count="+ l_request_count_val.as_string +")%N")
if attached {WSF_STRING} req.meta_variable ("REQUEST_COUNT") as l_request_count_val then
s.append_string ("(request_count="+ l_request_count_val.string +")%N")
end
-- ctx.request_format_id ("format", Void)
if attached ctx.request_format ("format", Void) as l_format then
if attached ctx.request_accepted_format ("format", Void) as l_format then
s.append_string (" format=" + l_format + "%N")
end
@@ -80,8 +80,8 @@ feature -- Execution
end
res.set_status_code (200)
res.write_headers_string (h.string)
res.write_string (s)
res.put_header_text (h.string)
res.put_string (s)
end
note

View File

@@ -8,12 +8,12 @@ class
APP_SERVER
inherit
APP_APPLICATION
APP_SERVICE
redefine
execute
end
REST_APPLICATION_GATEWAY
REST_SERVICE_GATEWAY
create
make
@@ -68,17 +68,17 @@ feature {NONE} -- Handlers
feature -- Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
request_count := request_count + 1
Precursor (req, res)
end
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
local
rqst_uri: detachable STRING
l_path_info: detachable STRING
h: EWF_HEADER
h: HTTP_HEADER
s: STRING
l_redir_url: STRING
do
@@ -92,10 +92,12 @@ feature -- Execution
s.append ("You are being redirected to <a href=%"" + l_redir_url + "%">/doc</a> in 2 seconds ...%N")
h.put_content_length (s.count)
res.set_status_code ({HTTP_STATUS_CODE}.temp_redirect)
res.write_headers_string (h.string)
res.write_string (s)
res.put_header_text (h.string)
res.put_string (s)
end
request_count: INTEGER
-- execute_rescue (ctx: like new_request_context)
-- -- Execute the default rescue behavior
-- do
@@ -106,7 +108,7 @@ feature -- Implementation
-- execute_exception_trace (ctx: like new_request_context)
-- local
-- h: EWF_HEADER
-- h: HTTP_HEADER
-- s: STRING
-- do
-- create h.make
@@ -121,17 +123,17 @@ feature -- Implementation
-- exit_with_code (-1)
-- end
execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local
s: STRING
do
res.set_status_code (200)
res.write_header (200, <<["Content-Type", "text/html"]>>)
res.put_header (200, <<["Content-Type", "text/html"]>>)
create s.make_empty
s.append_string ("Exited")
s.append_string (" <a href=%"" + ctx.script_url ("/") + "%">start again</a>%N")
res.write_string (s)
res.put_string (s)
exit_with_code (0)
end

View File

@@ -1,18 +1,18 @@
deferred class
REST_APPLICATION_GATEWAY
REST_SERVICE_GATEWAY
inherit
WGI_APPLICATION
WSF_SERVICE
feature -- Access
build_gateway_and_launch
local
cgi: EWF_CGI_CONNECTOR
cgi: WGI_CGI_CONNECTOR
do
create cgi.make (Current)
cgi.launch
end
end
gateway_name: STRING = "CGI"
@@ -20,5 +20,5 @@ feature -- Access
do
(create {EXCEPTIONS}).die (a_code)
end
end

View File

@@ -1,14 +1,14 @@
deferred class
REST_APPLICATION_GATEWAY
REST_SERVICE_GATEWAY
inherit
WGI_APPLICATION
WSF_SERVICE
feature -- Access
build_gateway_and_launch
local
libfcgi: EWF_LIBFCGI_CONNECTOR
libfcgi: WGI_LIBFCGI_CONNECTOR
do
create libfcgi.make (Current)
libfcgi.launch

View File

@@ -1,14 +1,14 @@
deferred class
REST_APPLICATION_GATEWAY
REST_SERVICE_GATEWAY
inherit
WGI_APPLICATION
WSF_SERVICE
feature -- Access
build_gateway_and_launch
local
app: NINO_APPLICATION
app: NINO_SERVICE
port_number: INTEGER
base_url: STRING
do
@@ -18,7 +18,7 @@ feature -- Access
print ("Example: start a Nino web server on port " + port_number.out +
", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N")
end
create app.make_custom (agent execute, base_url)
create app.make_custom (agent wgi_execute, base_url)
app.force_single_threaded
app.listen (port_number)

View File

@@ -23,7 +23,7 @@ feature {NONE} -- Initialization
feature {NONE} -- Implementation
wgi_value_iteration_to_string (v: ITERABLE [WGI_VALUE]; using_pre: BOOLEAN): STRING_8
wgi_value_iteration_to_string (v: ITERABLE [WSF_VALUE]; using_pre: BOOLEAN): STRING_8
do
create Result.make (100)
if using_pre then
@@ -32,7 +32,7 @@ feature {NONE} -- Implementation
across
v as cur
loop
Result.append_string (cur.item.name.as_string_8 + " = " + cur.item.as_string.as_string_8 + "%N")
Result.append_string (cur.item.name.as_string_8 + " = " + cur.item.string_representation.as_string_8 + "%N")
end
if using_pre then
Result.append ("</pre>")

View File

@@ -0,0 +1,26 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
APP_REQUEST_HANDLER_CONTEXT
inherit
REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
create
make
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -9,7 +9,7 @@ deferred class
feature -- Helpers
send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local
s: STRING
i,nb: INTEGER
@@ -20,7 +20,7 @@ feature -- Helpers
rep_data.headers.put_content_type_text_plain
create s.make_empty
inspect ctx.format_id
inspect ctx.accepted_format_id
when {HTTP_FORMAT_CONSTANTS}.json then
rep_data.headers.put_content_type_text_plain
s := "{%"application%": %"" + a_path + "%""

View File

@@ -11,7 +11,8 @@ inherit
REST_REQUEST_URI_TEMPLATE_ROUTER_I [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
create
make
make,
make_with_base_url
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {APP_APPLICATION}."
description: "Summary description for {APP_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
APP_APPLICATION
APP_SERVICE
inherit
REST_APPLICATION_I [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
REST_SERVICE_I [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
redefine
router
end

View File

@@ -0,0 +1,7 @@
Support for various text filters such as
* [wikitext](http://en.wikipedia.org/wiki/Wiki_markup)
* [Markdown](http://en.wikipedia.org/wiki/Markdown)
* ...
Anyone wanting to contribute is welcome

View File

@@ -0,0 +1,7 @@
We could add libraries for template engines such as
* [Velocity](http://en.wikipedia.org/wiki/Apache_Velocity)
* [Smarty](http://en.wikipedia.org/wiki/Smarty)
* ...
Anyone wanting to contribute is welcome

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="hello_routed_world" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
<target name="hello_routed_world">
<root class="HELLO_ROUTED_WORLD" feature="make"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\library\server\ewsgi\default\ewsgi_nino-safe.ecf" readonly="false"/>
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
<library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
<library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/>
<library name="uri_template" location="..\..\library\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -1,72 +0,0 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
RESTBUCK_CLIENT
create
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
local
h: LIBCURL_HTTP_CLIENT
sess: HTTP_CLIENT_SESSION
s: READABLE_STRING_8
j: JSON_PARSER
id: detachable STRING
do
create h.make
sess := h.new_session ("http://127.0.0.1")
s := "[
{
"location":"takeAway",
"items":[
{
"name":"Late",
"option":"skim",
"size":"Small",
"quantity":1
}
]
}
]"
if attached sess.post ("/order", Void, s) as r then
if attached r.body as m then
create j.make_parser (m)
if j.is_parsed and attached j.parse_object as j_o then
if attached {JSON_STRING} j_o.item ("id") as l_id then
id := l_id.item
end
print (m)
io.put_new_line
end
end
end
if id /= Void and then attached sess.get ("/order/" + id, Void) as r then
print (r.body)
io.put_new_line
end
end
feature -- Status
feature -- Access
feature -- Change
feature {NONE} -- Implementation
invariant
-- invariant_clause: True
end

View File

@@ -1,51 +0,0 @@
Restbuck Eiffel Implementation based on the book of REST in Practice
Verb URI or template Use
POST /order Create a new order, and upon success, receive a Locationheader specifying the new order<65>s URI.
GET /order/{orderId} Request the current state of the order specified by the URI.
PUT /order/{orderId} Update an order at the given URI with new information, providing the full representation.
DELETE /order/{orderId} Logically remove the order identified by the given URI.
How to Create an order
* Uri: http://localhost:8080/order
* Method: POST
* Note: you will get in the response the "location" of the new your order.
* HEADERS:
Content-Type: application/json
* Example CONTENT
{
"location":"takeAway",
"items":[
{
"name":"Late",
"option":"skim",
"size":"Small",
"quantity":1
}
]
}
How to Read an order
* Uri: http://localhost:8080/order/{order_id}
* Method: GET
How to Update an order
* Uri: http://localhost:8080/order/{order_id}
* Method: PUT
How to Delete an order
* Uri: http://localhost:8080/order/{order_id}
* Method: DELETE

View File

@@ -1,255 +0,0 @@
note
description: "Summary description for {ORDER_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
ORDER_HANDLER [C -> REQUEST_HANDLER_CONTEXT]
inherit
REQUEST_HANDLER [C]
REQUEST_RESOURCE_HANDLER_HELPER [C]
redefine
do_get,
do_post,
do_put,
do_delete
end
SHARED_DATABASE_API
SHARED_EJSON
REFACTORING_HELPER
SHARED_ORDER_VALIDATION
feature -- execute
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Execute request handler
do
execute_methods (ctx, req, res)
end
feature -- API DOC
api_doc : STRING = "URI:/order METHOD: POST%N URI:/order/{orderid} METHOD: GET, PUT, DELETE%N"
feature -- HTTP Methods
do_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Using GET to retrieve resource information.
-- If the GET request is SUCCESS, we response with
-- 200 OK, and a representation of the order
-- If the GET request is not SUCCESS, we response with
-- 404 Resource not found
local
id : STRING
do
if attached req.orig_path_info as orig_path then
id := get_order_id_from_path (orig_path)
if attached retrieve_order (id) as l_order then
compute_response_get (ctx, req, res, l_order)
else
handle_resource_not_found_response ("The following resource" + orig_path + " is not found ", ctx, req, res)
end
end
end
compute_response_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER)
local
h: EWF_HEADER
l_msg : STRING
do
create h.make
h.put_status ({HTTP_STATUS_CODE}.ok)
h.put_content_type_application_json
if attached {JSON_VALUE} json.value (l_order) as jv then
l_msg := jv.representation
h.put_content_length (l_msg.count)
if attached req.request_time as time then
h.add_header ("Date:" + time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT")
end
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
res.write_string (l_msg)
end
end
do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
local
l_post: STRING
l_location : STRING
l_order : detachable ORDER
h : EWF_HEADER
do
fixme ("TODO handle an Internal Server Error")
fixme ("Refactor the code, create new abstractions")
fixme ("Add Header Date to the response")
fixme ("Put implementation is wrong!!!!")
req.input.read_stream (req.content_length_value.as_integer_32)
l_post := req.input.last_string
l_order := extract_order_request(l_post)
fixme ("TODO move to a service method")
if l_order /= Void and then db_access.orders.has_key (l_order.id) then
update_order( l_order)
create h.make
h.put_status ({HTTP_STATUS_CODE}.ok)
h.put_content_type ("application/json")
if attached req.request_time as time then
h.add_header ("Date:" +time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT")
end
if attached req.http_host as host then
l_location := "http://"+host +req.request_uri+"/" + l_order.id
h.add_header ("Location:"+ l_location)
end
if attached {JSON_VALUE} json.value (l_order) as jv then
h.put_content_length (jv.representation.count)
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
res.write_string (jv.representation)
end
else
handle_bad_request_response (l_post +"%N is not a valid ORDER, maybe the order does not exist in the system", ctx, req, res)
end
end
do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
local
id: STRING
h : EWF_HEADER
do
fixme ("TODO handle an Internal Server Error")
fixme ("Refactor the code, create new abstractions")
if attached req.orig_path_info as orig_path then
id := get_order_id_from_path (orig_path)
if db_access.orders.has_key (id) then
delete_order( id)
create h.make
h.put_status ({HTTP_STATUS_CODE}.no_content)
h.put_content_type ("application/json")
if attached req.request_time as time then
h.put_utc_date (time)
end
res.set_status_code ({HTTP_STATUS_CODE}.no_content)
res.write_headers_string (h.string)
else
handle_resource_not_found_response (orig_path + " not found in this server", ctx, req, res)
end
end
end
do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Here the convention is the following.
-- POST is used for creation and the server determines the URI
-- of the created resource.
-- If the request post is SUCCESS, the server will create the order and will response with
-- HTTP_RESPONSE 201 CREATED, the Location header will contains the newly created order's URI
-- if the request post is not SUCCESS, the server will response with
-- HTTP_RESPONSE 400 BAD REQUEST, the client send a bad request
-- HTTP_RESPONSE 500 INTERNAL_SERVER_ERROR, when the server can deliver the request
local
l_post: STRING
do
req.input.read_stream (req.content_length_value.as_integer_32)
l_post := req.input.last_string
if attached extract_order_request (l_post) as l_order then
save_order (l_order)
compute_response_post (ctx, req, res, l_order)
else
handle_bad_request_response (l_post +"%N is not a valid ORDER", ctx, req, res)
end
end
compute_response_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER)
local
h: EWF_HEADER
l_msg : STRING
l_location : STRING
joc : JSON_ORDER_CONVERTER
do
create h.make
create joc.make
json.add_converter(joc)
h.put_status ({HTTP_STATUS_CODE}.created)
h.put_content_type_application_json
if attached {JSON_VALUE} json.value (l_order) as jv then
l_msg := jv.representation
h.put_content_length (l_msg.count)
if attached req.http_host as host then
l_location := "http://" + host + req.request_uri + "/" + l_order.id
h.put_location (l_location)
end
if attached req.request_time as time then
h.put_utc_date (time)
end
res.set_status_code ({HTTP_STATUS_CODE}.created)
res.write_headers_string (h.string)
res.write_string (l_msg)
end
end
feature {NONE} -- URI helper methods
get_order_id_from_path (a_path: READABLE_STRING_32) : STRING
do
Result := a_path.split ('/').at (3)
end
feature {NONE} -- Implementation Repository Layer
retrieve_order ( id : STRING) : detachable ORDER
-- get the order by id if it exist, in other case, Void
do
Result := db_access.orders.item (id)
end
save_order (an_order: ORDER)
-- save the order to the repository
local
i : INTEGER
do
from
i := 1
until
not db_access.orders.has_key ((db_access.orders.count + i).out)
loop
i := i + 1
end
an_order.set_id ((db_access.orders.count + i).out)
an_order.set_status ("submitted")
an_order.add_revision
db_access.orders.force (an_order, an_order.id)
end
update_order (an_order: ORDER)
-- update the order to the repository
do
an_order.add_revision
db_access.orders.force (an_order, an_order.id)
end
delete_order (an_order: STRING)
-- update the order to the repository
do
db_access.orders.remove (an_order)
end
extract_order_request (l_post : STRING) : detachable ORDER
-- extract an object Order from the request, or Void
-- if the request is invalid
local
parser : JSON_PARSER
joc : JSON_ORDER_CONVERTER
do
create joc.make
json.add_converter(joc)
create parser.make_parser (l_post)
if attached parser.parse as jv and parser.is_parsed then
Result ?= json.object (jv, "ORDER")
end
end
note
copyright: "2011-2011, Javier Velilla and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -0,0 +1,11 @@
Make sure to have the Clib generated in the related cURL library
- if you use EiffelStudio >= 7.0
check %ISE_LIBRARY%\library\cURL\spec\%ISE_C_COMPILER%\$ISE_PLATFORM
or $ISE_LIBRARY/library/cURL/spec/$ISE_PLATFORM
- otherwise if you use earlier version
check under ext/ise_library/curl/spec/...
And on Windows, be sure to get the libcurl.dll from %ISE_LIBRARY%\studio\spec\%ISE_PLATFORM%\bin\libcurl.dll

View File

@@ -12,7 +12,7 @@
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http_client" location="..\..\..\library\client\http_client\http_client-safe.ecf" readonly="false"/>
<library name="json" location="..\..\..\ext\text\json\library\json-safe.ecf" readonly="false"/>
<library name="json" location="..\..\..\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>

View File

@@ -11,7 +11,7 @@
</option>
<setting name="concurrency" value="thread"/>
<library name="http_client" location="..\..\..\library\client\http_client\http_client.ecf"/>
<library name="json" location="..\..\..\ext\text\json\library\json.ecf" readonly="false"/>
<library name="json" location="..\..\..\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<library name="thread" location="$ISE_LIBRARY/library/thread/thread.ecf"/>
<cluster name="src" location="./src" recursive="true"/>

View File

@@ -0,0 +1,152 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
RESTBUCK_CLIENT
create
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
local
h: LIBCURL_HTTP_CLIENT
sess: HTTP_CLIENT_SESSION
resp : HTTP_CLIENT_RESPONSE
l_location : detachable READABLE_STRING_8
body : STRING
do
create h.make
sess := h.new_session ("http://127.0.0.1:9090")
-- Create Order
print ("%N Create Order %N")
resp := create_order (sess)
-- Read the Order
print ("%N Read Order %N")
l_location := resp.header ("Location")
resp := read_order (sess, l_location)
-- Update the Order
if attached resp.body as l_body then
body := l_body.as_string_8
body.replace_substring_all ("takeAway", "in Shop")
print ("%N Update Order %N")
resp := update_order (sess, l_location, body)
end
end
update_order ( sess: HTTP_CLIENT_SESSION; uri : detachable READABLE_STRING_8; a_body : STRING) : HTTP_CLIENT_RESPONSE
local
context : HTTP_CLIENT_REQUEST_CONTEXT
do
create Result.make
if attached uri as l_uri then
sess.set_base_url (l_uri)
create context.make
context.headers.put ("application/json", "Content-Type")
Result := sess.put ("", context, a_body )
-- Show headers
across
Result.headers as l_headers
loop
print (l_headers.item.name)
print (":")
print (l_headers.item.value)
io.put_new_line
end
-- Show body
print (Result.body)
io.put_new_line
end
end
read_order ( sess: HTTP_CLIENT_SESSION; uri : detachable READABLE_STRING_8) : HTTP_CLIENT_RESPONSE
do
create Result.make
if attached uri as l_uri then
sess.set_base_url (l_uri)
Result := sess.get ("", Void)
-- Show headers
across
Result.headers as l_headers
loop
print (l_headers.item.name)
print (":")
print (l_headers.item.value)
io.put_new_line
end
-- Show body
print (Result.body)
io.put_new_line
end
end
create_order (sess: HTTP_CLIENT_SESSION) : HTTP_CLIENT_RESPONSE
local
s: READABLE_STRING_8
j: JSON_PARSER
id: detachable STRING
context : HTTP_CLIENT_REQUEST_CONTEXT
do
s := "[
{
"location":"takeAway",
"items":[
{
"name":"Late",
"option":"skim",
"size":"Small",
"quantity":1
}
]
}
]"
create context.make
context.headers.put ("application/json", "Content-Type")
Result := sess.post ("/order", context, s)
-- Show the Headers
across
Result.headers as l_headers
loop
print (l_headers.item.name)
print (":")
print (l_headers.item.value)
io.put_new_line
end
-- Show the Response body
if attached Result.body as m then
create j.make_parser (m)
if j.is_parsed and attached j.parse_object as j_o then
if attached {JSON_STRING} j_o.item ("id") as l_id then
id := l_id.item
end
print (m)
io.put_new_line
end
end
end
feature {NONE} -- Implementation
invariant
-- invariant_clause: True
end

View File

@@ -0,0 +1,293 @@
Restbuck Eiffel Implementation based on the book of REST in Practice
====================================================================
This is an implementation of CRUD pattern for manipulate resources, this is the first step to use
the HTTP protocol as an application protocol instead of a transport protocol.
Restbuck Protocol
-----------------
<table>
<TR><TH>Verb</TH> <TH>URI or template</TH> <TH>Use</TH></TR>
<TR><TD>POST</TD> <TD>/order</TD> <TD>Create a new order, and upon success, receive a Locationheader specifying the new order's URI.</TD></TR>
<TR><TD>GET</TD> <TD>/order/{orderId}</TD> <TD>Request the current state of the order specified by the URI.</TD></TR>
<TR><TD>PUT</TD> <TD>/order/{orderId}</TD> <TD>Update an order at the given URI with new information, providing the full representation.</TD></TR>
<TR><TD>DELETE</TD> <TD>/order/{orderId}</TD> <TD>Logically remove the order identified by the given URI.</TD></TR>
</table>
Resource Represenation
----------------------
The previous tables shows a contrat, the URI or URI template, allows us to indentify resources, now we will chose a
representacion, for this particular case we will use JSON.
Note: <br/>
1. *A resource can have multiple URIs*.<br/>
2. *A resource can have multiple Representations*.<br/>
RESTBUCKS_SERVER
----------------
This class implement the main entry of our REST CRUD service, we are using a default connector (Nino Connector,
using a WebServer written in Eiffel).
We are inheriting from URI_TEMPLATE_ROUTED_SERVICE, this allows us to map our service contrat, as is shown in the previous
table, the mapping is defined in the feature setup_router, this also show that the class ORDER_HANDLER will be encharge
of to handle different type of request to the ORDER resource.
class
RESTBUCKS_SERVER
inherit
ANY
URI_TEMPLATE_ROUTED_SERVICE
DEFAULT_SERVICE
-- Here we are using a default connector using the default Nino Connector,
-- but it's possible to use other connector (CGI or FCGI).
create
make
feature {NONE} -- Initialization
make
-- Initialize the router (this will have the request handler and
-- their context).
do
initialize_router
make_and_launch
end
create_router
do
create router.make (2)
end
setup_router
local
order_handler: ORDER_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
do
create order_handler
router.map_with_request_methods ("/order", order_handler, <<"POST">>)
router.map_with_request_methods ("/order/{orderid}", order_handler, <<"GET", "DELETE", "PUT">>)
end
feature -- Execution
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
-- I'm using this method to handle the method not allowed response
-- in the case that the given uri does not have a corresponding http method
-- to handle it.
local
h : HTTP_HEADER
l_description : STRING
l_api_doc : STRING
do
if req.content_length_value > 0 then
req.input.read_string (req.content_length_value.as_integer_32)
end
create h.make
h.put_status ({HTTP_STATUS_CODE}.method_not_allowed)
h.put_content_type_text_plain
l_api_doc := "%NPlease check the API%NURI:/order METHOD: POST%NURI:/order/{orderid} METHOD: GET, PUT, DELETE%N"
l_description := req.request_method + req.request_uri + " is not allowed" + "%N" + l_api_doc
h.put_content_length (l_description.count)
h.put_current_date
res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
res.write_header_text (h.string)
res.write_string (l_description)
end
end
How to Create an order with POST
--------------------------------
Here is the convention that we are using:
POST is used for creation and the server determines the URI of the created resource.
If the request POST is SUCCESS, the server will create the order and will response with
201 CREATED, the Location header will contains the newly created order's URI,
if the request POST is not SUCCESS, the server will response with
400 BAD REQUEST, the client send a bad request or
500 INTERNAL_SERVER_ERROR, when the server can deliver the request.
POST /order HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Content-Length: 196
Origin: chrome-extension://fhjcajmcbmldlhcimfajhfbgofnpcjmb
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: es-419,es;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
{
"location":"takeAway",
"items":[
{
"name":"Late",
"option":"skim",
"size":"Small",
"quantity":1
}
]
}
Response success
HTTP/1.1 201 Created
Status 201 Created
Content-Type application/json
Content-Length 123
Location http://localhost:8080/order/1
Date FRI,09 DEC 2011 20:34:20.00 GMT
{
"location" : "takeAway",
"status" : "submitted",
"items" : [ {
"name" : "late",
"size" : "small",
"quantity" : 1,
"option" : "skim"
} ]
}
How to Read an order with GET
-----------------------------
Using GET to retrieve resource information.
If the GET request is SUCCESS, we response with 200 OK, and a representation of the order
If the GET request is not SUCCESS, we response with 404 Resource not found
If is a Conditional GET and the resource does not change we send a 304, Resource not modifed
GET /order/1 HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: es-419,es;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
If-None-Match: 6542EF270D91D3EAF39CFB382E4CEBA7
Response
HTTP/1.1 200 OK
Status 200 OK
Content-Type application/json
Content-Length 123
Date FRI,09 DEC 2011 20:53:46.00 GMT
etag 2ED3A40954A95D766FC155682DC8BB52
{
"location" : "takeAway",
"status" : "submitted",
"items" : [ {
"name" : "late",
"size" : "small",
"quantity" : 1,
"option" : "skim"
} ]
}
How to Update an order with PUT
-------------------------------
A successful PUT request will not create a new resource, instead it will change the state of the resource identified by the current uri.
If success we response with 200 and the updated order.
404 if the order is not found
400 in case of a bad request
500 internal server error
If the request is a Conditional PUT, and it does not mat we response 415, precondition failed.
Suposse that we had created an Order with the values shown in the _How to create an order with POST_
But we change our decision and we want to stay in the shop.
PUT /order/1 HTTP/1.1
Content-Length: 122
Content-Type: application/json; charset=UTF-8
Host: localhost:8080
Connection: Keep-Alive
Expect: 100-Continue
{
"location" : "in shop",
"status" : "submitted",
"items" : [ {
"name" : "late",
"size" : "small",
"quantity" : 1,
"option" : "skim"
} ]
}
Response success
HTTP/1.1 200 OK
Status 200 OK
Content-Type application/json
Date FRI,09 DEC 2011 21:06:26.00 GMT
etag 8767F900674B843E1F3F70BCF3E62403
Content-Length 122
{
"location" : "in shop",
"status" : "submitted",
"items" : [ {
"name" : "late",
"size" : "small",
"quantity" : 1,
"option" : "skim"
} ]
}
How to Delete an order with DELETE
----------------------------------
Here we use DELETE to cancel an order, if that order is in state where it can still be canceled.
204 if is ok
404 Resource not found
405 if consumer and service's view of the resouce state is inconsisent
500 if we have an internal server error
DELETE /order/1 HTTP/1.1
Host: localhost:8080
Connection: Keep-Alive
Response success
HTTP/1.1 204 No Content
Status 204 No Content
Content-Type application/json
Date FRI,09 DEC 2011 21:10:51.00 GMT
If we want to check that the resource does not exist anymore we can try to retrieve a GET /order/1 and we will receive a
404 No Found
GET /order/1 HTTP/1.1
Host: localhost:8080
Connection: Keep-Alive
Response
HTTP/1.1 404 Not Found
Status 404 Not Found
Content-Type application/json
Content-Length 44
Date FRI,09 DEC 2011 21:14:17.79 GMT
The following resource/order/1 is not found
References
----------
1. [How to get a cup of coffe](http://www.infoq.com/articles/webber-rest-workflow)
2. [Rest in Practice] (http://restinpractice.com/default.aspx)

View File

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="restbucks" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="restbucks" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
<target name="restbucks">
<root class="RESTBUCKS_SERVER" feature="make"/>
<file_rule>
@@ -7,19 +7,24 @@
<exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<debug name="nino" enabled="true"/>
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\library\server\ewsgi\default\ewsgi_nino-safe.ecf" readonly="false"/>
<library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false">
<option debug="true">
<debug name="nino" enabled="true"/>
</option>
</library>
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
<library name="eel" location="..\..\library\crypto\eel\eel-safe.ecf" readonly="false"/>
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
<library name="json" location="..\..\ext\text\json\library\json-safe.ecf" readonly="false"/>
<library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
<library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/>
<library name="json" location="..\..\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="uri_template" location="..\..\library\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -38,7 +38,7 @@ feature -- Conversion
s_location ?= json.object (j.item (location_key), Void)
s_status ?= json.object (j.item (status_key), Void)
create o.make (s_id, s_location, s_status)
create o.make ("", s_location, s_status)
if attached {JSON_ARRAY} j.item (items_key) as l_val then
l_array := l_val.array_representation
@@ -87,7 +87,7 @@ feature -- Conversion
jv: JSON_OBJECT
do
create Result.make
Result.put (json.value (o.id), id_key)
-- Result.put (json.value (o.id), id_key)
Result.put (json.value (o.location), location_key)
Result.put (json.value (o.status), status_key)
from

Some files were not shown because too many files have changed in this diff Show More