Skip to content

Commit 72c886e

Browse files
authored
Merge pull request #34 from Shibin-Ez/master
docs: update roadmap documentation and refine Parson library guide fo…
2 parents bb3cc3c + 42997b8 commit 72c886e

6 files changed

Lines changed: 40 additions & 38 deletions

File tree

docs/guides/references/parson.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ struct json_array_t {
6868
};
6969
```
7070

71-
In OOPS terms, `JSON_Value` is like a generic `Base Class` and `JSON_Object` and `JSON_Array` are like `Derived Class` objects.
71+
You can assume `JSON_Value` as a generic *Base Class* and `JSON_Object` and `JSON_Array` as it's *Derived Class* objects.
7272

7373
## JSON_Value Methods
7474

75-
### `json_parse_file`
75+
### `json_parse_file()`
7676
Reads a JSON file and returns (`JSON_Value*`) that contains the entire content.
7777

7878
```c
@@ -90,7 +90,7 @@ So after getting the `JSON_Value` struct object from `json_parse_file()`, method
9090
Since a JSON file can start with any valid data type (an object, an array, a string, or a number), the parser returns a generic `JSON_Value` struct object. We then must use the appropriate method to resolve it into the intended object or array.
9191
:::
9292
93-
### `json_value_get_object`
93+
### `json_value_get_object()`
9494
9595
Gets the main `JSON_Object` from a `JSON_Value`. Since our `xps_config.json` starts with `{}` we can use this function. If it had been starting with `[]` then that would imply the file starts as an array of object so we would have to use `json_value_get_array()` instead.
9696
@@ -105,7 +105,7 @@ JSON_Object *json_value_get_object(const JSON_Value *value);
105105

106106
Once you have a `JSON_Object`, you can get specific fields using the key name.
107107

108-
### `json_value_get_array`
108+
### `json_value_get_array()`
109109

110110

111111
Gets the `JSON_Array` from a `JSON_Value`. This is used if your JSON file starts with an array (`[...]`) instead of an object.
@@ -119,7 +119,7 @@ JSON_Array *json_value_get_array(const JSON_Value *value);
119119
- `value`: The `JSON_Value` to check.
120120
- **Returns**: A pointer to a `JSON_Array`.
121121
122-
### `json_value_free`
122+
### `json_value_free()`
123123
Frees the memory used by the parsed JSON.
124124
125125
```c
@@ -131,7 +131,7 @@ void json_value_free(JSON_Value *value);
131131

132132
## JSON_Object Methods
133133

134-
### `json_object_get_string`
134+
### `json_object_get_string()`
135135
Gets a string value for a specific key.
136136

137137

@@ -144,7 +144,7 @@ const char *json_object_get_string(const JSON_Object *object, const char *name);
144144
- `name`: The key string (like `"server_name"`).
145145
- **Returns**: The string, or `NULL` if the key doesn't exist.
146146
147-
### `json_object_get_number`
147+
### `json_object_get_number()`
148148
Gets a number value for a specific key.
149149
150150
@@ -154,7 +154,7 @@ double json_object_get_number(const JSON_Object *object, const char *name);
154154

155155
- **Returns**: A number (which we often treat as an `int` or `size_t` in eXpServer for things like `port` or `workers`). Returns `0` on fail.
156156

157-
### `json_object_get_boolean`
157+
### `json_object_get_boolean()`
158158
Gets a boolean (true/false) value for a specific key.
159159

160160

@@ -165,7 +165,7 @@ int json_object_get_boolean(const JSON_Object *object, const char *name);
165165
- **Returns**: `1` for true, `0` for false, or `-1` if it fails.
166166
<!-- - **Usage in eXpServer**: Used to check the `gzip_enable` setting. -->
167167
168-
### `json_object_get_array`
168+
### `json_object_get_array()`
169169
Gets a JSON array for a specific key.
170170
171171
@@ -180,7 +180,7 @@ JSON_Array *json_object_get_array(const JSON_Object *object, const char *name);
180180

181181
Once you have a `JSON_Array`, you can find out how big it is and loop through it.
182182

183-
### `json_array_get_count`
183+
### `json_array_get_count()`
184184
Gets the total number of items in an array.
185185

186186

@@ -191,7 +191,7 @@ size_t json_array_get_count(const JSON_Array *array);
191191
- **Returns**: The size of the array.
192192
<!-- - **Usage in eXpServer**: Used as the limit in `for` loops when going through routes or servers. -->
193193
194-
### `json_array_get_object`
194+
### `json_array_get_object()`
195195
Gets a `JSON_Object` at a specific position (index) in an array.
196196
197197
@@ -205,7 +205,7 @@ JSON_Object *json_array_get_object(const JSON_Array *array, size_t index);
205205
- **Returns**: The `JSON_Object` at that position.
206206
<!-- - **Usage in eXpServer**: Getting individual `"route"` items out of the main routes array. -->
207207

208-
### `json_array_get_string`
208+
### `json_array_get_string()`
209209
Gets a string at a specific position in an array.
210210

211211

docs/roadmap/phase-1/stage-10.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void xps_pipe_destroy(xps_pipe_t *pipe) {
300300
**`xps_pipe_is_writable`**
301301
302302
- Checks if the buffer list length is below the buffer threshold (see `xps.h`), allowing new data to be written.
303-
::: details **expserver/src/core/xps_pipe.c - `xps_pipe_is_readable()`, `xps_pipe_is_writable()`**
303+
::: details **expserver/src/core/xps_pipe.c - `xps_pipe_is_readable()`, `xps_pipe_is_writable()`**
304304
305305
```c
306306
bool xps_pipe_is_readable(xps_pipe_t *pipe) { return /*fill this*/ }

docs/roadmap/phase-2/stage-14.md

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,39 +88,39 @@ struct xps_http_req_s {
8888

8989
xps_http_method_t method_n;
9090

91-
char *request_line; // POST https://www.devdiary.live:3000/api/problems HTTP/1.1
91+
char *request_line; // eg: POST https://www.devdiary.live:3000/api/problems HTTP/1.1
9292
u_char *request_line_start;
9393
u_char *request_line_end;
9494

95-
char *method; // POST
95+
char *method; // eg: POST
9696
u_char *method_start;
9797
u_char *method_end;
9898

99-
char *uri; // https://www.devdiary.live:3000/api/problems?key=val
99+
char *uri; // eg: https://www.devdiary.live:3000/api/problems?key=val
100100
u_char *uri_start;
101101
u_char *uri_end;
102102

103-
char *schema; // https
103+
char *schema; // eg: https
104104
u_char *schema_start;
105105
u_char *schema_end;
106106

107-
char *host; // www.devdiary.live
107+
char *host; // eg: www.devdiary.live
108108
u_char *host_start;
109109
u_char *host_end;
110110

111-
int port; // 3000
111+
int port; // eg: 3000
112112
u_char *port_start;
113113
u_char *port_end;
114114

115-
char *path; // /api/problems?key=val
115+
char *path; // eg: /api/problems?key=val
116116
u_char *path_start;
117117
u_char *path_end;
118118

119-
char *pathname; // /api/problems
119+
char *pathname; // eg: /api/problems
120120
u_char *pathname_start;
121121
u_char *pathname_end;
122122

123-
char *http_version; // 1.1
123+
char *http_version; // eg: 1.1
124124
u_char *http_major;
125125
u_char *http_minor;
126126

@@ -422,12 +422,12 @@ int xps_http_parse_request_line(xps_http_req_t *http_req, xps_buffer_t *buff) {
422422

423423
case RL_PATH:
424424
/*on ' ' - path ends, assign end of path,pathname,uri next state is RL_VERSION_START*/
425-
/*on '?'or'&'or'='or'#' - assign end of pathname, next state is RL_PATHNAME*/
425+
/*on '?'or'&'or'='or'#' - assign end of path, next state is RL_PATHNAME*/
426426
/*on CR or LF, fails*/
427427
break;
428428

429429
case RL_PATHNAME:
430-
/*on ' ' - assign end of uri,path, next state is RL_VERSION_START*/
430+
/*on ' ' - assign end of uri,pathname, next state is RL_VERSION_START*/
431431
/*on CR or LF, fails*/
432432
break;
433433

@@ -454,7 +454,7 @@ int xps_http_parse_request_line(xps_http_req_t *http_req, xps_buffer_t *buff) {
454454
break;
455455

456456
case RL_VERSION_HTTP_SLASH:
457-
/*on '1' - assign major, next state is RL_MAJOR, fails on all other inputs*/
457+
/*on '1' - assign major, next state is RL_VERSION_MAJOR, fails on all other inputs*/
458458
break;
459459

460460
case RL_VERSION_MAJOR:
@@ -785,12 +785,13 @@ const char *xps_http_get_header(vec_void_t *headers, const char *key) {
785785
786786
::: tip TRY
787787
788-
- HTTP is case insensitive. Modify the code such that the comparison handles input key in a case insensitive way.
789-
:::
788+
- TTP header names are case insensitive. Modify the code such that the comparison handles the input key in a case insensitive way.
789+
790+
:::
790791
791792
- **`xps_http_serialize_headers()`**
792793
793-
Serialize a list of HTTP headers(key-value pairs) into a buffer. The serialized headers will be formatted as a string, where each header is in the format - key: value\n. The function `sprintf` is used to format and store a string into a character buffer.
794+
Serialize a list of HTTP headers(key-value pairs) into a buffer. The serialized headers will be formatted as a string, where each header is in the format - `key: value\n`. The function `sprintf` is used to format and store a string into a character buffer.
794795
For each key value pair (eg. given below), an additional size of +5 characters are added to account for the colon (`:`), space (` `), newline (`\r\n`), and null terminator (`\0`).
795796
796797
For example consider the HTTP Request

docs/roadmap/phase-2/stage-15.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ xps_http_set_header(&(http_res->headers), "Access-Control-Allow-Origin", "*");
148148

149149
`xps_http_res_serialize()` : used for serializing the whole response into a buffer. It is similiar to the serialize function used in http_request module.
150150

151-
- First the headers are serialized using `xps_http_res_serialize()` , provided in the `xps_http` module and are stored into a temporary buffer.
151+
- First the headers are serialized using `xps_http_serialize_headers()` , provided in the `xps_http` module and are stored into a temporary buffer.
152152
- Then create a buffer instance for storing the serialized HTTP response. The length of the buffer is calculated by adding the lengths of each field in the struct `xps_http_res_s`.
153153
- Copy the response_line, header and body to the newly created buffer. Don’t forget to include a newline between response_line, headers and body.
154154

docs/roadmap/phase-2/stage-16.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ This will create a parson directory inside `expserver/src/lib/` and download all
7070

7171
:::tip READ
7272

73-
Before proceeding further read about [Parson](/guides/references/parson)
73+
- Before proceeding further read about [Json](https://www.json.org/json-en.html) data exchange format
74+
- Read the specs of [Parson](/guides/references/parson) library
7475

7576
:::
7677

@@ -277,7 +278,7 @@ xps_config_t *xps_config_create(const char *config_path) {
277278
```
278279
279280
- `xps_config_destroy` : Cleans up and frees the memory allocated for the configuration object. Implement it by deallocating the servers and the corresponding listeners and routes. Also de-initialize the vectors.
280-
- `xps_config_lookup` : Performs a lookup to find the correct configuration based on an HTTP request (`xps_http_req_t`) and client details (`xps_connection_t`).
281+
- `xps_config_lookup` : Takes the parsed configuration, an incoming HTTP request, and the client connection as input. It determines the appropriate server and route for the request by first matching the client's listener and hostname against the configured servers, then selecting the best matching route using a longest prefix match on the request path. Based on the matched route type (`file_serve`, `reverse_proxy`, or `redirect`), it populates and returns an `xps_config_lookup_t` structure with the relevant fields. Sets `*error` to `E_FAIL` or `E_NOTFOUND` and returns `NULL` if no matching server or route is found.
281282
282283
```c
283284
xps_config_lookup_t *xps_config_lookup(xps_config_t *config, xps_http_req_t *http_req,
@@ -383,13 +384,13 @@ xps_config_lookup_t *xps_config_lookup(xps_config_t *config, xps_http_req_t *htt
383384

384385
### Core Module - Modifications
385386

386-
- To `xps_core_s` struct, add `config` field. `xps_core_create()` takes config as argument.
387-
- Remove creating listeners while starting the server as the listeners are created during the configuration set-up itself.
387+
- To `xps_core_s` struct, add `config` field. Pass `config` as an argument to `xps_core_create()`.
388+
- Remove creating listeners while starting the server as the listeners are created during the configuration set-up itself (this will be done below, on modification to the `main.c`).
388389

389390
### Session Module - Modifications
390391

391-
- Add the lookup field which is used to determine the type of the incoming request.
392-
- In the `session_process_request()` the lookup(to determine the type of request) is done and the request is processed with respect to its type.
392+
- Add a lookup field (`xps_config_lookup_t`) which is used to determine the type of the incoming request.
393+
- In the `session_process_request()` the lookup (to determine the type of request) is done and the request is processed with respect to its type.
393394

394395
```c
395396
/*config_lookup called*/
@@ -433,7 +434,7 @@ if (lookup->type == REQ_FILE_SERVE) {
433434

434435
### main.c
435436

436-
Processes the command-line arguments to retrieve the configuration file path. The configuration is created which is followed by core creation.
437+
Processes the command-line arguments to retrieve the configuration file path. The configuration object is created by invoking the method of `xps_config` module. Then `core_create` function is invoked which handles creation of listeners and attaching it with core in accordance with the `config` object. And then starts the core.
437438

438439
```c
439440
int main(int argc, char *argv[]) {
@@ -655,4 +656,4 @@ Now, navigate to `http://localhost:8001/` in your browser. You will notice that
655656

656657
## Conclusion
657658

658-
In this stage, we transitioned from a hardcoded server setup to a dynamic, configuration-driven architecture using JSON. By implementing the `config` module, eXpServer now supports multiple worker cores, reverse proxying, and URL redirects. While the server currently returns a 404 error when an index file is missing from a directory, we will resolve this in the next stage by implementing a dedicated directory module.
659+
In this stage, we transitioned from a hardcoded server setup to a dynamic, configuration-driven architecture using a JSON config file. By implementing the `config` module, eXpServer now supports reverse proxying and URL redirects. The server currently returns a 404 error when an index file is missing from a directory, we will resolve this in the next stage by implementing a dedicated directory module.

docs/roadmap/phase-2/stage-17.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Recap
44

5-
In the previous stages, we updated the server to handle HTTP messages. Stage 14 focused on implementing HTTP request parsing, while Stage 15 covered the construction of HTTP response messages. And in stage 16 we have implemented multiple cores, used a JSON file to set-up server configuration and implemented reverse proxy and URL redirecting in our webserver.
5+
In the previous stages, we updated the server to handle HTTP messages. Stage 14 focused on implementing HTTP request parsing, while Stage 15 covered the construction of HTTP response messages. And in stage 16 we have implemented config module, used a JSON file to set-up server configuration and implemented reverse proxy and URL redirecting in our webserver.
66

77
## Learning Objectives
88

0 commit comments

Comments
 (0)