Merge branch 'master' of github.com:jocelyn/Eiffel-Web-Framework
This commit is contained in:
2
doc/wiki
2
doc/wiki
Submodule doc/wiki updated: 820bd7bd6f...a2a1f89299
@@ -21,6 +21,7 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
|
||||||
make
|
make
|
||||||
do
|
do
|
||||||
initialize_router
|
initialize_router
|
||||||
|
|||||||
25
examples/restbucks/restbucks-safe.ecf
Normal file
25
examples/restbucks/restbucks-safe.ecf
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?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">
|
||||||
|
<target name="restbucks">
|
||||||
|
<root class="RESTBUCKS_SERVER" 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="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="uri_template" location="..\..\library\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
||||||
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
1
examples/restbucks/restbucks.rc
Normal file
1
examples/restbucks/restbucks.rc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
21
examples/restbucks/src/database/database_api.e
Normal file
21
examples/restbucks/src/database/database_api.e
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {DATABASE_API}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
DATABASE_API
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature --Initialization
|
||||||
|
make
|
||||||
|
do
|
||||||
|
create orders.make (10)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
orders : HASH_TABLE[ORDER,STRING]
|
||||||
|
|
||||||
|
end
|
||||||
14
examples/restbucks/src/database/shared_database_api.e
Normal file
14
examples/restbucks/src/database/shared_database_api.e
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SHARED_DATABASE_API}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
SHARED_DATABASE_API
|
||||||
|
feature
|
||||||
|
db_access: DATABASE_API
|
||||||
|
once
|
||||||
|
create Result.make
|
||||||
|
end
|
||||||
|
end
|
||||||
87
examples/restbucks/src/domain/item.e
Normal file
87
examples/restbucks/src/domain/item.e
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {ITEM}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
ITEM
|
||||||
|
inherit
|
||||||
|
ITEM_CONSTANTS
|
||||||
|
create
|
||||||
|
make
|
||||||
|
feature -- Initialization
|
||||||
|
make ( a_name : STRING_32 ; a_size:STRING_32; a_option: STRING_32; a_quantity:INTEGER_8)
|
||||||
|
do
|
||||||
|
set_name (a_name)
|
||||||
|
set_size (a_size)
|
||||||
|
set_option (a_option)
|
||||||
|
set_quantity (a_quantity)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
name : STRING
|
||||||
|
-- product name type of Coffee(Late, Cappuccino, Expresso)
|
||||||
|
|
||||||
|
option : STRING
|
||||||
|
-- customization option Milk (skim, semi, whole)
|
||||||
|
|
||||||
|
size : STRING
|
||||||
|
-- small, mediumm large
|
||||||
|
|
||||||
|
quantity :INTEGER
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Element Change
|
||||||
|
set_name (a_name: STRING)
|
||||||
|
require
|
||||||
|
valid_name: is_valid_coffee_type (a_name)
|
||||||
|
do
|
||||||
|
name := a_name
|
||||||
|
ensure
|
||||||
|
name_assigned : name.same_string(a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_size (a_size: STRING)
|
||||||
|
require
|
||||||
|
valid_size : is_valid_size_option (a_size)
|
||||||
|
do
|
||||||
|
size := a_size
|
||||||
|
ensure
|
||||||
|
size_assigned : size.same_string(a_size)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_option (an_option: STRING)
|
||||||
|
require
|
||||||
|
valid_option : is_valid_milk_type (an_option)
|
||||||
|
do
|
||||||
|
option := an_option
|
||||||
|
ensure
|
||||||
|
option_assigned : option.same_string (an_option)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_quantity (a_quantity: INTEGER)
|
||||||
|
require
|
||||||
|
valid_quantity : a_quantity > 0
|
||||||
|
do
|
||||||
|
quantity := a_quantity
|
||||||
|
ensure
|
||||||
|
quantity_assigned : quantity = a_quantity
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Report
|
||||||
|
hash_code: INTEGER
|
||||||
|
--Hash code value
|
||||||
|
do
|
||||||
|
Result := option.hash_code + name.hash_code + size.hash_code + quantity.hash_code
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
invariant
|
||||||
|
valid_size : is_valid_size_option (size)
|
||||||
|
valid_coffe : is_valid_coffee_type (name)
|
||||||
|
valid_customization : is_valid_milk_type (option)
|
||||||
|
valid_quantity : quantity > 0
|
||||||
|
end
|
||||||
51
examples/restbucks/src/domain/item_constants.e
Normal file
51
examples/restbucks/src/domain/item_constants.e
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {ITEM_CONSTANTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
ITEM_CONSTANTS
|
||||||
|
feature -- Access
|
||||||
|
is_valid_coffee_type (a_type: STRING) : BOOLEAN
|
||||||
|
--is `a_type' a valid coffee type
|
||||||
|
do
|
||||||
|
a_type.to_lower
|
||||||
|
coffe_types.compare_objects
|
||||||
|
Result := coffe_types.has (a_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
Coffe_types : ARRAY[STRING]
|
||||||
|
-- List of valid Coffee types
|
||||||
|
once
|
||||||
|
Result := <<"late","cappuccino", "expresso">>
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_milk_type (a_type: STRING) : BOOLEAN
|
||||||
|
--is `a_type' a valid milk type
|
||||||
|
do
|
||||||
|
a_type.to_lower
|
||||||
|
milk_types.compare_objects
|
||||||
|
Result := milk_types.has (a_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
Milk_types : ARRAY[STRING]
|
||||||
|
-- List of valid Milk types
|
||||||
|
once
|
||||||
|
Result := <<"skim","semi", "whole">>
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_size_option (an_option: STRING) : BOOLEAN
|
||||||
|
--is `an_option' a valid size option
|
||||||
|
do
|
||||||
|
an_option.to_lower
|
||||||
|
size_options.compare_objects
|
||||||
|
Result := size_options.has (an_option)
|
||||||
|
end
|
||||||
|
|
||||||
|
Size_options : ARRAY[STRING]
|
||||||
|
-- List of valid Size_options
|
||||||
|
once
|
||||||
|
Result := <<"small","mediumn", "large">>
|
||||||
|
end
|
||||||
|
end
|
||||||
166
examples/restbucks/src/domain/json_order_converter.e
Normal file
166
examples/restbucks/src/domain/json_order_converter.e
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JSON_ORDER_CONVERTER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
JSON_ORDER_CONVERTER
|
||||||
|
inherit
|
||||||
|
JSON_CONVERTER
|
||||||
|
create
|
||||||
|
make
|
||||||
|
feature -- Initialization
|
||||||
|
make
|
||||||
|
do
|
||||||
|
create object.make ("","","")
|
||||||
|
end
|
||||||
|
feature -- Access
|
||||||
|
object : ORDER
|
||||||
|
|
||||||
|
|
||||||
|
value : detachable JSON_OBJECT
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
from_json (j: attached like value): detachable like object
|
||||||
|
-- Convert from JSON value. Returns Void if unable to convert
|
||||||
|
local
|
||||||
|
lstr1, lstr2, lstr3 : detachable STRING_32
|
||||||
|
q: detachable INTEGER_8
|
||||||
|
o: ORDER
|
||||||
|
i : ITEM
|
||||||
|
l_val : detachable JSON_ARRAY
|
||||||
|
l_array : detachable ARRAYED_LIST[JSON_VALUE]
|
||||||
|
jv : detachable JSON_OBJECT
|
||||||
|
is_valid_from_json : BOOLEAN
|
||||||
|
do
|
||||||
|
is_valid_from_json := True
|
||||||
|
lstr1 ?= json.object (j.item (id_key), Void)
|
||||||
|
lstr2 ?= json.object (j.item (location_key), Void)
|
||||||
|
lstr3 ?= json.object (j.item (status_key), Void)
|
||||||
|
l_val ?= j.item (items_key)
|
||||||
|
|
||||||
|
create o.make (lstr1, lstr2, lstr3)
|
||||||
|
|
||||||
|
if l_val /= void then
|
||||||
|
l_array := l_val.array_representation
|
||||||
|
from
|
||||||
|
l_array.start
|
||||||
|
until
|
||||||
|
l_array.after
|
||||||
|
loop
|
||||||
|
jv ?= l_array.item_for_iteration
|
||||||
|
if jv /= Void then
|
||||||
|
lstr1 ?= json.object (jv.item (name_key), Void)
|
||||||
|
lstr2 ?= json.object (jv.item (size_key), Void)
|
||||||
|
lstr3 ?= json.object (jv.item (option_key), Void)
|
||||||
|
q ?= json.object (jv.item (quantity_key),Void)
|
||||||
|
if lstr1/= Void and then lstr2 /= Void and then lstr3 /= Void then
|
||||||
|
if is_valid_item_customization(lstr1,lstr2,lstr3,q) then
|
||||||
|
create i.make (lstr1, lstr2,lstr3, q)
|
||||||
|
o.add_item (i)
|
||||||
|
else
|
||||||
|
is_valid_from_json := false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
is_valid_from_json := false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
l_array.forth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not is_valid_from_json or o.items.is_empty then
|
||||||
|
Result := Void
|
||||||
|
else
|
||||||
|
Result := o
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
to_json (o: like object): like value
|
||||||
|
-- Convert to JSON value
|
||||||
|
local
|
||||||
|
ja : JSON_ARRAY
|
||||||
|
i : ITEM
|
||||||
|
jv: JSON_OBJECT
|
||||||
|
do
|
||||||
|
create Result.make
|
||||||
|
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
|
||||||
|
create ja.make_array
|
||||||
|
o.items.start
|
||||||
|
until
|
||||||
|
o.items.after
|
||||||
|
loop
|
||||||
|
i := o.items.item_for_iteration
|
||||||
|
create jv.make
|
||||||
|
jv.put (json.value (i.name), name_key)
|
||||||
|
jv.put (json.value (i.size),size_key)
|
||||||
|
jv.put (json.value (i.quantity), quantity_key)
|
||||||
|
jv.put (json.value (i.option), option_key)
|
||||||
|
ja.add (jv)
|
||||||
|
o.items.forth
|
||||||
|
end
|
||||||
|
Result.put(ja,items_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
id_key: JSON_STRING
|
||||||
|
once
|
||||||
|
create Result.make_json ("id")
|
||||||
|
end
|
||||||
|
|
||||||
|
location_key: JSON_STRING
|
||||||
|
once
|
||||||
|
create Result.make_json ("location")
|
||||||
|
end
|
||||||
|
|
||||||
|
status_key: JSON_STRING
|
||||||
|
once
|
||||||
|
create Result.make_json ("status")
|
||||||
|
end
|
||||||
|
|
||||||
|
items_key : JSON_STRING
|
||||||
|
once
|
||||||
|
create Result.make_json ("items")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
name_key : JSON_STRING
|
||||||
|
|
||||||
|
once
|
||||||
|
create Result.make_json ("name")
|
||||||
|
end
|
||||||
|
|
||||||
|
size_key : JSON_STRING
|
||||||
|
|
||||||
|
once
|
||||||
|
create Result.make_json ("size")
|
||||||
|
end
|
||||||
|
|
||||||
|
quantity_key : JSON_STRING
|
||||||
|
|
||||||
|
once
|
||||||
|
create Result.make_json ("quantity")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
option_key : JSON_STRING
|
||||||
|
|
||||||
|
once
|
||||||
|
create Result.make_json ("option")
|
||||||
|
end
|
||||||
|
feature -- Validation
|
||||||
|
|
||||||
|
is_valid_item_customization ( name : STRING_32; size: STRING_32; option : STRING_32; quantity : INTEGER_8 ) : BOOLEAN
|
||||||
|
local
|
||||||
|
ic : ITEM_CONSTANTS
|
||||||
|
do
|
||||||
|
create ic
|
||||||
|
Result := ic.is_valid_coffee_type (name) and ic.is_valid_milk_type (option) and ic.is_valid_size_option (size) and quantity > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
109
examples/restbucks/src/domain/order.e
Normal file
109
examples/restbucks/src/domain/order.e
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {ORDER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
ORDER
|
||||||
|
create
|
||||||
|
make
|
||||||
|
feature -- Initialization
|
||||||
|
|
||||||
|
make ( an_id : detachable STRING_32; a_location: detachable STRING_32; a_status: detachable STRING_32)
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST[ITEM]}items.make (10)
|
||||||
|
if an_id /= Void then
|
||||||
|
set_id(an_id)
|
||||||
|
else
|
||||||
|
set_id ("")
|
||||||
|
end
|
||||||
|
if a_location /= Void then
|
||||||
|
set_location(a_location)
|
||||||
|
else
|
||||||
|
set_location ("")
|
||||||
|
end
|
||||||
|
if a_status /= Void then
|
||||||
|
set_status (a_status)
|
||||||
|
else
|
||||||
|
set_status ("")
|
||||||
|
end
|
||||||
|
revision := 0
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
id : STRING_32
|
||||||
|
location : STRING_32
|
||||||
|
items: LIST[ITEM]
|
||||||
|
status : STRING_32
|
||||||
|
revision : INTEGER
|
||||||
|
|
||||||
|
feature -- element change
|
||||||
|
set_id (an_id : STRING_32)
|
||||||
|
do
|
||||||
|
id := an_id
|
||||||
|
ensure
|
||||||
|
id_assigned : id.same_string (an_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_location (a_location : STRING_32)
|
||||||
|
do
|
||||||
|
location := a_location
|
||||||
|
ensure
|
||||||
|
location_assigned : location.same_string (a_location)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_status (a_status : STRING_32)
|
||||||
|
do
|
||||||
|
status := a_status
|
||||||
|
ensure
|
||||||
|
status_asigned : status.same_string (a_status)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
add_item (a_item : ITEM)
|
||||||
|
require
|
||||||
|
valid_item: a_item /= Void
|
||||||
|
do
|
||||||
|
items.force (a_item)
|
||||||
|
ensure
|
||||||
|
has_item : items.has (a_item)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
add_revision
|
||||||
|
do
|
||||||
|
revision := revision + 1
|
||||||
|
ensure
|
||||||
|
revision_incremented : old revision + 1 = revision
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Etag
|
||||||
|
|
||||||
|
etag : STRING_32
|
||||||
|
-- Etag generation for Order objects
|
||||||
|
do
|
||||||
|
Result := hash_code.out + revision.out
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Report
|
||||||
|
|
||||||
|
hash_code: INTEGER_32
|
||||||
|
-- Hash code value
|
||||||
|
do
|
||||||
|
from
|
||||||
|
items.start
|
||||||
|
Result := items.item.hash_code
|
||||||
|
until
|
||||||
|
items.off
|
||||||
|
loop
|
||||||
|
Result:= ((Result \\ 8388593) |<< 8) + items.item.hash_code
|
||||||
|
items.forth
|
||||||
|
end
|
||||||
|
if items.count > 1 then
|
||||||
|
Result := Result \\ items.count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
54
examples/restbucks/src/domain/order_validation.e
Normal file
54
examples/restbucks/src/domain/order_validation.e
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {ORDER_TRANSITIONS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
ORDER_VALIDATION
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
is_valid_status_state (a_status: STRING) : BOOLEAN
|
||||||
|
--is `a_status' a valid coffee order state
|
||||||
|
do
|
||||||
|
a_status.to_lower
|
||||||
|
Order_states.compare_objects
|
||||||
|
Result := Order_states.has (a_status)
|
||||||
|
end
|
||||||
|
|
||||||
|
Order_states : ARRAY[STRING]
|
||||||
|
-- List of valid status states
|
||||||
|
once
|
||||||
|
Result := <<"submitted","pay","payed", "cancel","canceled","prepare","prepared","deliver","completed">>
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
is_valid_transition (order:ORDER a_status : STRING) :BOOLEAN
|
||||||
|
-- Given the current order state, determine if the transition is valid
|
||||||
|
do
|
||||||
|
a_status.to_lower
|
||||||
|
if order.status.same_string ("submitted") then
|
||||||
|
Result := a_status.same_string ("pay") or a_status.same_string ("cancel") or order.status.same_string (a_status)
|
||||||
|
elseif order.status.same_string ("pay") then
|
||||||
|
Result := a_status.same_string ("payed") or order.status.same_string (a_status)
|
||||||
|
elseif order.status.same_string ("cancel") then
|
||||||
|
Result := a_status.same_string ("canceled") or order.status.same_string (a_status)
|
||||||
|
elseif order.status.same_string ("payed") then
|
||||||
|
Result := a_status.same_string ("prepared") or order.status.same_string (a_status)
|
||||||
|
elseif order.status.same_string ("prepared") then
|
||||||
|
Result := a_status.same_string ("deliver") or order.status.same_string (a_status)
|
||||||
|
elseif order.status.same_string ("deliver") then
|
||||||
|
Result := a_status.same_string ("completed") or order.status.same_string (a_status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_state_valid_to_update ( a_status : STRING) : BOOLEAN
|
||||||
|
-- Given the current state `a_status' of an order, is possible to update the order?
|
||||||
|
do
|
||||||
|
if a_status.same_string ("submitted") or else a_status.same_string ("pay") or else a_status.same_string ("payed") then
|
||||||
|
Result := true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
16
examples/restbucks/src/domain/shared_order_validation.e
Normal file
16
examples/restbucks/src/domain/shared_order_validation.e
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SHARED_ORDER_VALIDATION}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
SHARED_ORDER_VALIDATION
|
||||||
|
|
||||||
|
feature
|
||||||
|
order_validation : ORDER_VALIDATION
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
184
examples/restbucks/src/resource/order_handler.e
Normal file
184
examples/restbucks/src/resource/order_handler.e
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {ORDER_HANDLER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
ORDER_HANDLER[C -> REQUEST_HANDLER_CONTEXT]
|
||||||
|
inherit
|
||||||
|
REQUEST_HANDLER[C]
|
||||||
|
SHARED_DATABASE_API
|
||||||
|
SHARED_EJSON
|
||||||
|
REFACTORING_HELPER
|
||||||
|
SHARED_ORDER_VALIDATION
|
||||||
|
WGI_RESPONSE_STATUS_CODES
|
||||||
|
|
||||||
|
feature -- execute
|
||||||
|
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
-- Execute request handler
|
||||||
|
do
|
||||||
|
if req.request_method.same_string ("GET") then
|
||||||
|
-- pre_process_get (ctx, a_format, a_args)
|
||||||
|
elseif req.request_method.same_string ("PUT") then
|
||||||
|
-- pre_process_put (ctx, a_format, a_args)
|
||||||
|
elseif req.request_method.same_string ("DELETE") then
|
||||||
|
-- pre_process_delete (ctx, a_format, a_args)
|
||||||
|
elseif req.request_method.same_string ("POST") then
|
||||||
|
process_post (ctx,req,res)
|
||||||
|
else
|
||||||
|
-- TODO HANDLE METHOD NOT SUPPORTED
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- HTTP Methods
|
||||||
|
|
||||||
|
process_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
local
|
||||||
|
l_values: HASH_TABLE [STRING_32, STRING]
|
||||||
|
l_missings: LINKED_LIST [STRING]
|
||||||
|
l_full: BOOLEAN
|
||||||
|
l_post: STRING
|
||||||
|
l_location : STRING
|
||||||
|
l_msg : STRING
|
||||||
|
l_order : detachable ORDER
|
||||||
|
jv : detachable JSON_VALUE
|
||||||
|
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")
|
||||||
|
if req.content_length_value > 0 then
|
||||||
|
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 then
|
||||||
|
save_order( l_order)
|
||||||
|
create h.make
|
||||||
|
h.put_status (created)
|
||||||
|
h.put_content_type ("application/json")
|
||||||
|
jv ?= json.value (l_order)
|
||||||
|
if jv /= Void 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.add_header ("Location:"+ l_location)
|
||||||
|
end
|
||||||
|
res.set_status_code (created)
|
||||||
|
res.write_headers_string (h.string)
|
||||||
|
res.write_string (l_msg)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- handle_bad_request_response(l_post +"%N is not a valid ORDER",ctx.output)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- handle_bad_request_response("Bad request, content_lenght empty",ctx.output)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Implementation
|
||||||
|
|
||||||
|
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
|
||||||
|
joc : JSON_ORDER_CONVERTER
|
||||||
|
parser : JSON_PARSER
|
||||||
|
l_order : detachable ORDER
|
||||||
|
jv : detachable JSON_VALUE
|
||||||
|
do
|
||||||
|
create joc.make
|
||||||
|
json.add_converter(joc)
|
||||||
|
create parser.make_parser (l_post)
|
||||||
|
jv ?= parser.parse
|
||||||
|
if jv /= Void and parser.is_parsed then
|
||||||
|
l_order ?= json.object (jv, "ORDER")
|
||||||
|
Result := l_order
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- handle_bad_request_response (a_description:STRING; an_output: HTTPD_SERVER_OUTPUT )
|
||||||
|
-- local
|
||||||
|
-- rep: detachable REST_RESPONSE
|
||||||
|
-- do
|
||||||
|
-- create rep.make (path)
|
||||||
|
-- rep.headers.put_status (rep.headers.bad_request)
|
||||||
|
-- rep.headers.put_content_type_application_json
|
||||||
|
-- rep.set_message (a_description)
|
||||||
|
-- an_output.put_string (rep.string)
|
||||||
|
-- rep.recycle
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- handle_conflic_request_response (a_description:STRING; an_output: HTTPD_SERVER_OUTPUT )
|
||||||
|
-- local
|
||||||
|
-- rep: detachable REST_RESPONSE
|
||||||
|
-- do
|
||||||
|
-- create rep.make (path)
|
||||||
|
-- rep.headers.put_status (rep.headers.conflict)
|
||||||
|
-- rep.headers.put_content_type_application_json
|
||||||
|
-- rep.set_message (a_description)
|
||||||
|
-- an_output.put_string (rep.string)
|
||||||
|
-- rep.recycle
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
-- handle_resource_not_found_response (a_description:STRING; an_output: HTTPD_SERVER_OUTPUT )
|
||||||
|
-- local
|
||||||
|
-- rep: detachable REST_RESPONSE
|
||||||
|
-- do
|
||||||
|
-- create rep.make (path)
|
||||||
|
-- rep.headers.put_status (rep.headers.not_found)
|
||||||
|
-- rep.headers.put_content_type_application_json
|
||||||
|
-- rep.set_message (a_description)
|
||||||
|
-- an_output.put_string (rep.string)
|
||||||
|
-- rep.recycle
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
-- handle_method_not_supported_response (ctx :REST_REQUEST_CONTEXT)
|
||||||
|
-- local
|
||||||
|
-- rep: detachable REST_RESPONSE
|
||||||
|
-- do
|
||||||
|
-- create rep.make (path)
|
||||||
|
-- rep.headers.put_status (rep.headers.method_not_allowed)
|
||||||
|
-- rep.headers.put_content_type_application_json
|
||||||
|
-- ctx.output.put_string (rep.string)
|
||||||
|
-- rep.recycle
|
||||||
|
-- end
|
||||||
|
|
||||||
|
end
|
||||||
199
examples/restbucks/src/restbucks_server.e
Normal file
199
examples/restbucks/src/restbucks_server.e
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
note
|
||||||
|
description : "Objects that ..."
|
||||||
|
author : "$Author$"
|
||||||
|
date : "$Date$"
|
||||||
|
revision : "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
RESTBUCKS_SERVER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
|
||||||
|
URI_TEMPLATE_ROUTED_APPLICATION
|
||||||
|
|
||||||
|
ROUTED_APPLICATION_HELPER
|
||||||
|
|
||||||
|
DEFAULT_WGI_APPLICATION
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
|
||||||
|
make
|
||||||
|
do
|
||||||
|
initialize_router
|
||||||
|
make_and_launch
|
||||||
|
end
|
||||||
|
|
||||||
|
create_router
|
||||||
|
do
|
||||||
|
create router.make (5)
|
||||||
|
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: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
local
|
||||||
|
h: EWF_HEADER
|
||||||
|
l_url: STRING
|
||||||
|
e: EXECUTION_ENVIRONMENT
|
||||||
|
n: INTEGER
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
l_url := req.script_url ("/home")
|
||||||
|
n := 3
|
||||||
|
h.put_refresh (l_url, 5, 200)
|
||||||
|
res.set_status_code (200)
|
||||||
|
res.write_headers_string (h.string)
|
||||||
|
from
|
||||||
|
create e
|
||||||
|
until
|
||||||
|
n = 0
|
||||||
|
loop
|
||||||
|
if n > 1 then
|
||||||
|
res.write_string ("Redirected to " + l_url + " in " + n.out + " seconds :%N")
|
||||||
|
else
|
||||||
|
res.write_string ("Redirected to " + l_url + " in 1 second :%N")
|
||||||
|
end
|
||||||
|
res.flush
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
until
|
||||||
|
i = 1001
|
||||||
|
loop
|
||||||
|
res.write_string (".")
|
||||||
|
if i \\ 100 = 0 then
|
||||||
|
res.write_string ("%N")
|
||||||
|
end
|
||||||
|
res.flush
|
||||||
|
e.sleep (1_000_000)
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
res.write_string ("%N")
|
||||||
|
n := n - 1
|
||||||
|
end
|
||||||
|
res.write_string ("You are now being redirected...%N")
|
||||||
|
res.flush
|
||||||
|
end
|
||||||
|
|
||||||
|
execute_home (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
res.write_header (200, <<["Content-Type", "text/html"]>>)
|
||||||
|
res.write_string ("<html><body>Hello World ?!%N")
|
||||||
|
res.write_string ("<h3>Please try the following links</h3><ul>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/") + "%">default</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello") + "%">/hello</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello.html/Joce") + "%">/hello.html/Joce</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello.json/Joce") + "%">/hello.json/Joce</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello/Joce.html") + "%">/hello/Joce.html</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello/Joce.xml") + "%">/hello/Joce.xml</a></li>%N")
|
||||||
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello/Joce") + "%">/hello/Joce</a></li>%N")
|
||||||
|
res.write_string ("</ul>%N")
|
||||||
|
|
||||||
|
if attached req.item ("REQUEST_COUNT") as rqc then
|
||||||
|
res.write_string ("request #"+ rqc.as_string + "%N")
|
||||||
|
end
|
||||||
|
res.write_string ("</body></html>%N")
|
||||||
|
end
|
||||||
|
|
||||||
|
execute_hello (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT)
|
||||||
|
local
|
||||||
|
l_response_content_type: detachable STRING
|
||||||
|
msg: STRING
|
||||||
|
h: EWF_HEADER
|
||||||
|
content_type_supported: ARRAY [STRING]
|
||||||
|
do
|
||||||
|
if a_name /= Void then
|
||||||
|
msg := "Hello %"" + a_name + "%" !%N"
|
||||||
|
else
|
||||||
|
msg := "Hello anonymous visitor !%N"
|
||||||
|
end
|
||||||
|
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.html_text, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>>
|
||||||
|
inspect ctx.request_format_id ("format", content_type_supported)
|
||||||
|
when {HTTP_FORMAT_CONSTANTS}.json then
|
||||||
|
l_response_content_type := {HTTP_CONSTANTS}.json_app
|
||||||
|
msg := "{%N%"application%": %"/hello%",%N %"message%": %"" + msg + "%" %N}"
|
||||||
|
when {HTTP_FORMAT_CONSTANTS}.html then
|
||||||
|
l_response_content_type := {HTTP_CONSTANTS}.html_text
|
||||||
|
when {HTTP_FORMAT_CONSTANTS}.xml then
|
||||||
|
l_response_content_type := {HTTP_CONSTANTS}.xml_text
|
||||||
|
msg := "<response><application>/hello</application><message>" + msg + "</message></response>%N"
|
||||||
|
when {HTTP_FORMAT_CONSTANTS}.text then
|
||||||
|
l_response_content_type := {HTTP_CONSTANTS}.plain_text
|
||||||
|
else
|
||||||
|
execute_content_type_not_allowed (req, res, content_type_supported,
|
||||||
|
<<{HTTP_FORMAT_CONSTANTS}.json_name, {HTTP_FORMAT_CONSTANTS}.html_name, {HTTP_FORMAT_CONSTANTS}.xml_name, {HTTP_FORMAT_CONSTANTS}.text_name>>
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if l_response_content_type /= Void then
|
||||||
|
create h.make
|
||||||
|
h.put_status (200)
|
||||||
|
h.put_content_type (l_response_content_type)
|
||||||
|
h.put_content_length (msg.count)
|
||||||
|
res.set_status_code (200)
|
||||||
|
res.write_headers_string (h.string)
|
||||||
|
-- res.write_header (200, <<
|
||||||
|
-- ["Content-Type", l_response_content_type],
|
||||||
|
-- ["Content-Length", msg.count.out
|
||||||
|
-- >>)
|
||||||
|
res.write_string (msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, Void, ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_anonymous_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, ctx.string_parameter ("name"), ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_method_any (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, req.request_method, ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_method_get (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "GET", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
handle_method_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "POST", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_method_get_or_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "GET or POST", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-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
|
||||||
258
examples/restbucks/src/wgi_response_status_codes.e
Normal file
258
examples/restbucks/src/wgi_response_status_codes.e
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
note
|
||||||
|
description: "Based on http://en.wikipedia.org/wiki/List_of_HTTP_status_codes."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
WGI_RESPONSE_STATUS_CODES
|
||||||
|
|
||||||
|
feature -- 1xx Informational
|
||||||
|
|
||||||
|
Continue : INTEGER = 100
|
||||||
|
--This means that the server has received the request headers, and that the client should proceed to send the request body
|
||||||
|
--(in the case of a request for which a body needs to be sent; for example, a POST request).
|
||||||
|
--If the request body is large, sending it to a server when a request has already been rejected based upon inappropriate headers is inefficient.
|
||||||
|
--To have a server check if the request could be accepted based on the request's headers alone,
|
||||||
|
--a client must send Expect: 100-continue as a header in its initial request[2] and check if a 100 Continue status code is received in response
|
||||||
|
--before continuing (or receive 417 Expectation Failed and not continue).
|
||||||
|
|
||||||
|
Switching_Protocols : INTEGER = 101
|
||||||
|
--This means the requester has asked the server to switch protocols and the server is acknowledging that it will do so.
|
||||||
|
|
||||||
|
Processing : INTEGER = 102 -- (WebDAV) (RFC 2518)
|
||||||
|
--As a WebDAV request may contain many sub-requests involving file operations, it may take a long time to complete the request.
|
||||||
|
--This code indicates that the server has received and is processing the request, but no response is available yet.
|
||||||
|
--This prevents the client from timing out and assuming the request was lost.
|
||||||
|
|
||||||
|
Checkpoint : INTEGER = 103
|
||||||
|
--This code is used in the Resumable HTTP Requests Proposal to resume aborted PUT or POST requests.
|
||||||
|
|
||||||
|
Request_URI_too_long_ie7 : INTEGER = 122
|
||||||
|
--This is a non-standard IE7-only code which means the URI is longer than a maximum of 2083 characters
|
||||||
|
|
||||||
|
|
||||||
|
feature -- 2xx Success
|
||||||
|
|
||||||
|
OK : INTEGER = 200
|
||||||
|
--Standard response for successful HTTP requests. The actual response will depend on the request method used.
|
||||||
|
--In a GET request, the response will contain an entity corresponding to the requested resource.
|
||||||
|
--In a POST request the response will contain an entity describing or containing the result of the action.
|
||||||
|
|
||||||
|
Created : INTEGER = 201
|
||||||
|
--The request has been fulfilled and resulted in a new resource being created.
|
||||||
|
|
||||||
|
Accepted : INTEGER = 202
|
||||||
|
--The request has been accepted for processing, but the processing has not been completed.
|
||||||
|
--The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
|
||||||
|
|
||||||
|
Non_Authoritative_Information : INTEGER = 203 --(since HTTP/1.1)
|
||||||
|
--The server successfully processed the request, but is returning information that may be from another source.
|
||||||
|
|
||||||
|
No_Content : INTEGER = 204
|
||||||
|
--The server successfully processed the request, but is not returning any content.
|
||||||
|
|
||||||
|
Reset_Content : INTEGER = 205
|
||||||
|
--The server successfully processed the request, but is not returning any content.
|
||||||
|
--Unlike a 204 response, this response requires that the requester reset the document view.
|
||||||
|
|
||||||
|
|
||||||
|
Partial_Content : INTEGER = 206
|
||||||
|
--The server is delivering only part of the resource due to a range header sent by the client.
|
||||||
|
--The range header is used by tools like wget to enable resuming of interrupted downloads,
|
||||||
|
--or split a download into multiple simultaneous streams.
|
||||||
|
|
||||||
|
Multi_Status : INTEGER = 207 --(WebDAV) (RFC 4918)
|
||||||
|
--The message body that follows is an XML message and can contain a number of separate response codes,
|
||||||
|
-- depending on how many sub-requests were made.
|
||||||
|
|
||||||
|
IM_Used : INTEGER = 226 -- (RFC 3229)
|
||||||
|
--The server has fulfilled a GET request for the resource, and the response is a representation of the result of one
|
||||||
|
--or more instance-manipulations applied to the current instance.
|
||||||
|
|
||||||
|
feature -- 3xx Redirection
|
||||||
|
|
||||||
|
|
||||||
|
Multiple_Choices : INTEGER = 300
|
||||||
|
--Indicates multiple options for the resource that the client may follow.
|
||||||
|
--It, for instance, could be used to present different format options for video, list files with different extensions, or word sense disambiguation.
|
||||||
|
|
||||||
|
Moved_Permanently : INTEGER = 301
|
||||||
|
--This and all future requests should be directed to the given URI.
|
||||||
|
|
||||||
|
Found : INTEGER = 302
|
||||||
|
--This is an example of industrial practice contradicting the standard.
|
||||||
|
--HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"),
|
||||||
|
--but popular browsers implemented 302 with the functionality of a 303 See Other.
|
||||||
|
--Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours.
|
||||||
|
--However, some Web applications and frameworks use the 302 status code as if it were the 303.
|
||||||
|
|
||||||
|
See_Other : INTEGER = 303 -- (since HTTP/1.1)
|
||||||
|
--The response to the request can be found under another URI using a GET method.
|
||||||
|
--When received in response to a POST (or PUT/DELETE), it should be assumed that the server
|
||||||
|
--has received the data and the redirect should be issued with a separate GET message.
|
||||||
|
|
||||||
|
Not_Modified : INTEGER = 304
|
||||||
|
--Indicates the resource has not been modified since last requested.
|
||||||
|
--Typically, the HTTP client provides a header like the If-Modified-Since header to provide a time against which to compare.
|
||||||
|
--Using this saves bandwidth and reprocessing on both the server and client,
|
||||||
|
--as only the header data must be sent and received in comparison to the entirety of the page being re-processed by the server,
|
||||||
|
--then sent again using more bandwidth of the server and client.
|
||||||
|
|
||||||
|
Use_Proxy : INTEGER = 305 --(since HTTP/1.1)
|
||||||
|
--Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
|
||||||
|
|
||||||
|
Switch_Proxy : INTEGER = 306
|
||||||
|
--No longer used. Originally meant "Subsequent requests should use the specified proxy."
|
||||||
|
|
||||||
|
Temporary_Redirect : INTEGER = 307 --(since HTTP/1.1)
|
||||||
|
--In this occasion, the request should be repeated with another URI, but future requests can still use the original URI.
|
||||||
|
--In contrast to 303, the request method should not be changed when reissuing the original request.
|
||||||
|
--For instance, a POST request must be repeated using another POST request.
|
||||||
|
|
||||||
|
Resume_Incomplete : INTEGER = 308
|
||||||
|
--This code is used in the Resumable HTTP Requests Proposal to resume aborted PUT or POST requests.
|
||||||
|
|
||||||
|
feature -- 4xx Client Error
|
||||||
|
|
||||||
|
Bad_Request : INTEGER = 400
|
||||||
|
--The request cannot be fulfilled due to bad syntax.
|
||||||
|
|
||||||
|
Unauthorized : INTEGER = 401
|
||||||
|
--Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided.
|
||||||
|
--The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
|
||||||
|
--See Basic access authentication and Digest access authentication.
|
||||||
|
|
||||||
|
Payment_Required : INTEGER = 402
|
||||||
|
--Reserved for future use.The original intention was that this code might be used as part of some form of digital cash or micropayment scheme,
|
||||||
|
--but that has not happened, and this code is not usually used.
|
||||||
|
--As an example of its use, however, Apple's MobileMe service generates a 402 error ("httpStatusCode:402" in the Mac OS X Console log) if the MobileMe account is delinquent.
|
||||||
|
|
||||||
|
Forbidden : INTEGER = 403
|
||||||
|
--The request was a legal request, but the server is refusing to respond to it.
|
||||||
|
--Unlike a 401 Unauthorized response, authenticating will make no difference.
|
||||||
|
|
||||||
|
Not_Found : INTEGER = 404
|
||||||
|
--The requested resource could not be found but may be available again in the future.
|
||||||
|
--Subsequent requests by the client are permissible.
|
||||||
|
|
||||||
|
Method_Not_Allowed : INTEGER = 405
|
||||||
|
--A request was made of a resource using a request method not supported by that resource;
|
||||||
|
--for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.
|
||||||
|
|
||||||
|
Not_Acceptable : INTEGER = 406
|
||||||
|
--The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.
|
||||||
|
|
||||||
|
Proxy_Authentication_Required : INTEGER = 407
|
||||||
|
--The client must first authenticate itself with the proxy.
|
||||||
|
|
||||||
|
Request_Timeout : INTEGER = 408
|
||||||
|
--The server timed out waiting for the request. According to W3 HTTP specifications:
|
||||||
|
--"The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
|
||||||
|
|
||||||
|
Conflict : INTEGER = 409
|
||||||
|
--Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.
|
||||||
|
|
||||||
|
Gone : INTEGER = 410
|
||||||
|
--Indicates that the resource requested is no longer available and will not be available again.
|
||||||
|
--This should be used when a resource has been intentionally removed and the resource should be purged.
|
||||||
|
-- Upon receiving a 410 status code, the client should not request the resource again in the future.
|
||||||
|
-- Clients such as search engines should remove the resource from their indices.
|
||||||
|
--Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
|
||||||
|
|
||||||
|
Length_Required : INTEGER = 411
|
||||||
|
--The request did not specify the length of its content, which is required by the requested resource.
|
||||||
|
|
||||||
|
Precondition_Failed : INTEGER = 412
|
||||||
|
--The server does no t meet one of the preconditions that the requester put on the request.
|
||||||
|
|
||||||
|
Request_Entity_Too_Large : INTEGER = 413
|
||||||
|
--The request is larger than the server is willing or able to process.
|
||||||
|
|
||||||
|
Request_URI_Too_Long : INTEGER = 414
|
||||||
|
--The URI provided was too long for the server to process.
|
||||||
|
|
||||||
|
Unsupported_Media_Type : INTEGER = 415
|
||||||
|
--The request entity has a media type which the server or resource does not support.
|
||||||
|
--For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
|
||||||
|
|
||||||
|
Requested_Range_Not_Satisfiable : INTEGER = 416
|
||||||
|
--The client has asked for a portion of the file, but the server cannot supply that portion.
|
||||||
|
--For example, if the client asked for a part of the file that lies beyond the end of the file.
|
||||||
|
|
||||||
|
Expectation_Failed : INTEGER = 417
|
||||||
|
--The server cannot meet the requirements of the Expect request-header field.
|
||||||
|
|
||||||
|
Im_a_teapot : INTEGER = 418 --(RFC 2324)
|
||||||
|
--This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324,
|
||||||
|
--Hyper Text Coffee Pot Control Protocol, and is not expected to be implemented by actual HTTP servers.
|
||||||
|
|
||||||
|
Unprocessable_Entity : INTEGER = 422 --(WebDAV) (RFC 4918)
|
||||||
|
--The request was well-formed but was unable to be followed due to semantic errors.
|
||||||
|
|
||||||
|
Locked : INTEGER = 423 --(WebDAV) (RFC 4918)
|
||||||
|
--The resource that is being accessed is locked.
|
||||||
|
|
||||||
|
Failed_Dependency : INTEGER = 424 --(WebDAV) (RFC 4918)
|
||||||
|
--The request failed due to failure of a previous request (e.g. a PROPPATCH).
|
||||||
|
|
||||||
|
Unordered_Collection : INTEGER = 425 --(RFC 3648)
|
||||||
|
--Defined in drafts of "WebDAV Advanced Collections Protocol",
|
||||||
|
--but not present in "Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol".
|
||||||
|
|
||||||
|
Upgrade_Required : INTEGER = 426 -- (RFC 2817)
|
||||||
|
--The client should switch to a different protocol such as TLS/1.0.
|
||||||
|
|
||||||
|
No_Response : INTEGER = 444
|
||||||
|
--A Nginx HTTP server extension. The server returns no information to the client and closes the connection (useful as a deterrent for malware).
|
||||||
|
|
||||||
|
Retry_With : INTEGER = 449
|
||||||
|
--A Microsoft extension. The request should be retried after performing the appropriate action.
|
||||||
|
|
||||||
|
Blocked_by_Windows_Parental_Controls : INTEGER = 450
|
||||||
|
--A Microsoft extension. This error is given when Windows Parental Controls are turned on and are blocking access to the given webpage.
|
||||||
|
|
||||||
|
Client_Closed_Request : INTEGER = 499
|
||||||
|
--An Nginx HTTP server extension.
|
||||||
|
--This code is introduced to log the case when the connection is closed by client while HTTP server is processing its request,
|
||||||
|
-- making server unable to send the HTTP header back.
|
||||||
|
|
||||||
|
feature -- 5xx Server Error
|
||||||
|
Internal_Server_Error : INTEGER = 500
|
||||||
|
--A generic error message, given when no more specific message is suitable.
|
||||||
|
|
||||||
|
Not_Implemented : INTEGER = 501
|
||||||
|
--The server either does not recognise the request method, or it lacks the ability to fulfill the request.
|
||||||
|
|
||||||
|
Bad_Gateway : INTEGER = 502
|
||||||
|
--The server was acting as a gateway or proxy and received an invalid response from the upstream server.
|
||||||
|
|
||||||
|
Service_Unavailable : INTEGER = 503
|
||||||
|
--The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.
|
||||||
|
|
||||||
|
Gateway_Timeout : INTEGER = 504
|
||||||
|
--The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
|
||||||
|
|
||||||
|
HTTP_Version_Not_Supported : INTEGER = 505
|
||||||
|
--The server does not support the HTTP protocol version used in the request.
|
||||||
|
|
||||||
|
Variant_Also_Negotiates : INTEGER = 506 --(RFC 2295)
|
||||||
|
--Transparent content negotiation for the request results in a circular reference.
|
||||||
|
|
||||||
|
Insufficient_Storage : INTEGER = 507 -- (WebDAV)(RFC 4918)
|
||||||
|
--The server is unable to store the representation needed to complete the request.
|
||||||
|
|
||||||
|
Bandwidth_Limit_Exceeded : INTEGER = 509 -- (Apache bw/limited extension)
|
||||||
|
--This status code, while used by many servers, is not specified in any RFCs.
|
||||||
|
|
||||||
|
Not_Extended : INTEGER = 510 -- (RFC 2774)
|
||||||
|
--Further extensions to the request are required for the server to fulfill it.[20]
|
||||||
|
|
||||||
|
network_read_timeout_error : INTEGER = 598 --598 (Informal convention)
|
||||||
|
--This status code is not specified in any RFCs, but is used by some HTTP proxies to signal a network read
|
||||||
|
--timeout behind the proxy to a client in front of the proxy.
|
||||||
|
|
||||||
|
network_connect_timeout_error : INTEGER = 599
|
||||||
|
--This status code is not specified in any RFCs, but is used by some HTTP proxies to signal a
|
||||||
|
--network connect timeout behind the proxy to a client in front of the proxy.
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user