The main objective is to reduce loss in revenue due to delayed shelf-restocking (when product is in-stock in the store but not stocked on the shelf) and inaccurate forecasting (under-estimating future product sales) practices. The result is to demonstrate inventory automation using ECIS system by enabling the means to monitor and track store inventory in real-time, perform data analysis remotely in cloud, improve shopping experience for the consumers and increase revenue for the retailers in the retail industry. Machine Learning code can be found on my GitHub: https://github.com/priyankkalgaonkar

Dependencies:   mbed

ECE 53301: Wireless and Multimedia Computing Final Project Report – Group 1

Inventory Automation Using Electronically Connected Intelligent Shelves.

Code Developed by: Priyank Kalgaonkar.

Department of Electrical and Computer Engineering, Purdue School of Engineering and Technology at IUPUI.

Submitted as partial fulfillment for the requirement of Fall 2019 - ECE 53301-26877: Wireless and Multimedia Computing course.

Date of Submission: December 12, 2019.

Committer:
priyank12p
Date:
Thu Dec 12 01:04:52 2019 +0000
Revision:
0:b0c4c25d37ab
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
priyank12p 0:b0c4c25d37ab 1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
priyank12p 0:b0c4c25d37ab 2 *
priyank12p 0:b0c4c25d37ab 3 * Permission is hereby granted, free of charge, to any person obtaining a copy
priyank12p 0:b0c4c25d37ab 4 * of this software and associated documentation files (the "Software"), to
priyank12p 0:b0c4c25d37ab 5 * deal in the Software without restriction, including without limitation the
priyank12p 0:b0c4c25d37ab 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
priyank12p 0:b0c4c25d37ab 7 * sell copies of the Software, and to permit persons to whom the Software is
priyank12p 0:b0c4c25d37ab 8 * furnished to do so, subject to the following conditions:
priyank12p 0:b0c4c25d37ab 9 *
priyank12p 0:b0c4c25d37ab 10 * The above copyright notice and this permission notice shall be included in
priyank12p 0:b0c4c25d37ab 11 * all copies or substantial portions of the Software.
priyank12p 0:b0c4c25d37ab 12 *
priyank12p 0:b0c4c25d37ab 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
priyank12p 0:b0c4c25d37ab 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
priyank12p 0:b0c4c25d37ab 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
priyank12p 0:b0c4c25d37ab 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
priyank12p 0:b0c4c25d37ab 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
priyank12p 0:b0c4c25d37ab 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
priyank12p 0:b0c4c25d37ab 19 * IN THE SOFTWARE.
priyank12p 0:b0c4c25d37ab 20 */
priyank12p 0:b0c4c25d37ab 21 #ifndef http_parser_h
priyank12p 0:b0c4c25d37ab 22 #define http_parser_h
priyank12p 0:b0c4c25d37ab 23
priyank12p 0:b0c4c25d37ab 24 #ifdef __cplusplus
priyank12p 0:b0c4c25d37ab 25 extern "C" {
priyank12p 0:b0c4c25d37ab 26 #endif
priyank12p 0:b0c4c25d37ab 27
priyank12p 0:b0c4c25d37ab 28 /* Also update SONAME in the Makefile whenever you change these. */
priyank12p 0:b0c4c25d37ab 29 #define HTTP_PARSER_VERSION_MAJOR 2
priyank12p 0:b0c4c25d37ab 30 #define HTTP_PARSER_VERSION_MINOR 7
priyank12p 0:b0c4c25d37ab 31 #define HTTP_PARSER_VERSION_PATCH 1
priyank12p 0:b0c4c25d37ab 32
priyank12p 0:b0c4c25d37ab 33 #if defined(_WIN32) && !defined(__MINGW32__) && \
priyank12p 0:b0c4c25d37ab 34 (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
priyank12p 0:b0c4c25d37ab 35 #include <BaseTsd.h>
priyank12p 0:b0c4c25d37ab 36 #include <stddef.h>
priyank12p 0:b0c4c25d37ab 37 typedef __int8 int8_t;
priyank12p 0:b0c4c25d37ab 38 typedef unsigned __int8 uint8_t;
priyank12p 0:b0c4c25d37ab 39 typedef __int16 int16_t;
priyank12p 0:b0c4c25d37ab 40 typedef unsigned __int16 uint16_t;
priyank12p 0:b0c4c25d37ab 41 typedef __int32 int32_t;
priyank12p 0:b0c4c25d37ab 42 typedef unsigned __int32 uint32_t;
priyank12p 0:b0c4c25d37ab 43 typedef __int64 int64_t;
priyank12p 0:b0c4c25d37ab 44 typedef unsigned __int64 uint64_t;
priyank12p 0:b0c4c25d37ab 45 #else
priyank12p 0:b0c4c25d37ab 46 #include <stdint.h>
priyank12p 0:b0c4c25d37ab 47 #endif
priyank12p 0:b0c4c25d37ab 48
priyank12p 0:b0c4c25d37ab 49 /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
priyank12p 0:b0c4c25d37ab 50 * faster
priyank12p 0:b0c4c25d37ab 51 */
priyank12p 0:b0c4c25d37ab 52 #ifndef HTTP_PARSER_STRICT
priyank12p 0:b0c4c25d37ab 53 # define HTTP_PARSER_STRICT 1
priyank12p 0:b0c4c25d37ab 54 #endif
priyank12p 0:b0c4c25d37ab 55
priyank12p 0:b0c4c25d37ab 56 /* Maximium header size allowed. If the macro is not defined
priyank12p 0:b0c4c25d37ab 57 * before including this header then the default is used. To
priyank12p 0:b0c4c25d37ab 58 * change the maximum header size, define the macro in the build
priyank12p 0:b0c4c25d37ab 59 * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
priyank12p 0:b0c4c25d37ab 60 * the effective limit on the size of the header, define the macro
priyank12p 0:b0c4c25d37ab 61 * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
priyank12p 0:b0c4c25d37ab 62 */
priyank12p 0:b0c4c25d37ab 63 #ifndef HTTP_MAX_HEADER_SIZE
priyank12p 0:b0c4c25d37ab 64 # define HTTP_MAX_HEADER_SIZE (80*1024)
priyank12p 0:b0c4c25d37ab 65 #endif
priyank12p 0:b0c4c25d37ab 66
priyank12p 0:b0c4c25d37ab 67 typedef struct http_parser http_parser;
priyank12p 0:b0c4c25d37ab 68 typedef struct http_parser_settings http_parser_settings;
priyank12p 0:b0c4c25d37ab 69
priyank12p 0:b0c4c25d37ab 70
priyank12p 0:b0c4c25d37ab 71 /* Callbacks should return non-zero to indicate an error. The parser will
priyank12p 0:b0c4c25d37ab 72 * then halt execution.
priyank12p 0:b0c4c25d37ab 73 *
priyank12p 0:b0c4c25d37ab 74 * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
priyank12p 0:b0c4c25d37ab 75 * returning '1' from on_headers_complete will tell the parser that it
priyank12p 0:b0c4c25d37ab 76 * should not expect a body. This is used when receiving a response to a
priyank12p 0:b0c4c25d37ab 77 * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
priyank12p 0:b0c4c25d37ab 78 * chunked' headers that indicate the presence of a body.
priyank12p 0:b0c4c25d37ab 79 *
priyank12p 0:b0c4c25d37ab 80 * Returning `2` from on_headers_complete will tell parser that it should not
priyank12p 0:b0c4c25d37ab 81 * expect neither a body nor any futher responses on this connection. This is
priyank12p 0:b0c4c25d37ab 82 * useful for handling responses to a CONNECT request which may not contain
priyank12p 0:b0c4c25d37ab 83 * `Upgrade` or `Connection: upgrade` headers.
priyank12p 0:b0c4c25d37ab 84 *
priyank12p 0:b0c4c25d37ab 85 * http_data_cb does not return data chunks. It will be called arbitrarily
priyank12p 0:b0c4c25d37ab 86 * many times for each string. E.G. you might get 10 callbacks for "on_url"
priyank12p 0:b0c4c25d37ab 87 * each providing just a few characters more data.
priyank12p 0:b0c4c25d37ab 88 */
priyank12p 0:b0c4c25d37ab 89 typedef int (*http_data_cb) (http_parser*, const char *at, uint32_t length);
priyank12p 0:b0c4c25d37ab 90 typedef int (*http_cb) (http_parser*);
priyank12p 0:b0c4c25d37ab 91
priyank12p 0:b0c4c25d37ab 92
priyank12p 0:b0c4c25d37ab 93 /* Status Codes */
priyank12p 0:b0c4c25d37ab 94 #define HTTP_STATUS_MAP(XX) \
priyank12p 0:b0c4c25d37ab 95 XX(100, CONTINUE, Continue) \
priyank12p 0:b0c4c25d37ab 96 XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
priyank12p 0:b0c4c25d37ab 97 XX(102, PROCESSING, Processing) \
priyank12p 0:b0c4c25d37ab 98 XX(200, OK, OK) \
priyank12p 0:b0c4c25d37ab 99 XX(201, CREATED, Created) \
priyank12p 0:b0c4c25d37ab 100 XX(202, ACCEPTED, Accepted) \
priyank12p 0:b0c4c25d37ab 101 XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
priyank12p 0:b0c4c25d37ab 102 XX(204, NO_CONTENT, No Content) \
priyank12p 0:b0c4c25d37ab 103 XX(205, RESET_CONTENT, Reset Content) \
priyank12p 0:b0c4c25d37ab 104 XX(206, PARTIAL_CONTENT, Partial Content) \
priyank12p 0:b0c4c25d37ab 105 XX(207, MULTI_STATUS, Multi-Status) \
priyank12p 0:b0c4c25d37ab 106 XX(208, ALREADY_REPORTED, Already Reported) \
priyank12p 0:b0c4c25d37ab 107 XX(226, IM_USED, IM Used) \
priyank12p 0:b0c4c25d37ab 108 XX(300, MULTIPLE_CHOICES, Multiple Choices) \
priyank12p 0:b0c4c25d37ab 109 XX(301, MOVED_PERMANENTLY, Moved Permanently) \
priyank12p 0:b0c4c25d37ab 110 XX(302, FOUND, Found) \
priyank12p 0:b0c4c25d37ab 111 XX(303, SEE_OTHER, See Other) \
priyank12p 0:b0c4c25d37ab 112 XX(304, NOT_MODIFIED, Not Modified) \
priyank12p 0:b0c4c25d37ab 113 XX(305, USE_PROXY, Use Proxy) \
priyank12p 0:b0c4c25d37ab 114 XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
priyank12p 0:b0c4c25d37ab 115 XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
priyank12p 0:b0c4c25d37ab 116 XX(400, BAD_REQUEST, Bad Request) \
priyank12p 0:b0c4c25d37ab 117 XX(401, UNAUTHORIZED, Unauthorized) \
priyank12p 0:b0c4c25d37ab 118 XX(402, PAYMENT_REQUIRED, Payment Required) \
priyank12p 0:b0c4c25d37ab 119 XX(403, FORBIDDEN, Forbidden) \
priyank12p 0:b0c4c25d37ab 120 XX(404, NOT_FOUND, Not Found) \
priyank12p 0:b0c4c25d37ab 121 XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
priyank12p 0:b0c4c25d37ab 122 XX(406, NOT_ACCEPTABLE, Not Acceptable) \
priyank12p 0:b0c4c25d37ab 123 XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
priyank12p 0:b0c4c25d37ab 124 XX(408, REQUEST_TIMEOUT, Request Timeout) \
priyank12p 0:b0c4c25d37ab 125 XX(409, CONFLICT, Conflict) \
priyank12p 0:b0c4c25d37ab 126 XX(410, GONE, Gone) \
priyank12p 0:b0c4c25d37ab 127 XX(411, LENGTH_REQUIRED, Length Required) \
priyank12p 0:b0c4c25d37ab 128 XX(412, PRECONDITION_FAILED, Precondition Failed) \
priyank12p 0:b0c4c25d37ab 129 XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
priyank12p 0:b0c4c25d37ab 130 XX(414, URI_TOO_LONG, URI Too Long) \
priyank12p 0:b0c4c25d37ab 131 XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
priyank12p 0:b0c4c25d37ab 132 XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
priyank12p 0:b0c4c25d37ab 133 XX(417, EXPECTATION_FAILED, Expectation Failed) \
priyank12p 0:b0c4c25d37ab 134 XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
priyank12p 0:b0c4c25d37ab 135 XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
priyank12p 0:b0c4c25d37ab 136 XX(423, LOCKED, Locked) \
priyank12p 0:b0c4c25d37ab 137 XX(424, FAILED_DEPENDENCY, Failed Dependency) \
priyank12p 0:b0c4c25d37ab 138 XX(426, UPGRADE_REQUIRED, Upgrade Required) \
priyank12p 0:b0c4c25d37ab 139 XX(428, PRECONDITION_REQUIRED, Precondition Required) \
priyank12p 0:b0c4c25d37ab 140 XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
priyank12p 0:b0c4c25d37ab 141 XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
priyank12p 0:b0c4c25d37ab 142 XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
priyank12p 0:b0c4c25d37ab 143 XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
priyank12p 0:b0c4c25d37ab 144 XX(501, NOT_IMPLEMENTED, Not Implemented) \
priyank12p 0:b0c4c25d37ab 145 XX(502, BAD_GATEWAY, Bad Gateway) \
priyank12p 0:b0c4c25d37ab 146 XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
priyank12p 0:b0c4c25d37ab 147 XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
priyank12p 0:b0c4c25d37ab 148 XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
priyank12p 0:b0c4c25d37ab 149 XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
priyank12p 0:b0c4c25d37ab 150 XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
priyank12p 0:b0c4c25d37ab 151 XX(508, LOOP_DETECTED, Loop Detected) \
priyank12p 0:b0c4c25d37ab 152 XX(510, NOT_EXTENDED, Not Extended) \
priyank12p 0:b0c4c25d37ab 153 XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
priyank12p 0:b0c4c25d37ab 154
priyank12p 0:b0c4c25d37ab 155 enum http_status
priyank12p 0:b0c4c25d37ab 156 {
priyank12p 0:b0c4c25d37ab 157 #define XX(num, name, string) HTTP_STATUS_##name = num,
priyank12p 0:b0c4c25d37ab 158 HTTP_STATUS_MAP(XX)
priyank12p 0:b0c4c25d37ab 159 #undef XX
priyank12p 0:b0c4c25d37ab 160 };
priyank12p 0:b0c4c25d37ab 161
priyank12p 0:b0c4c25d37ab 162
priyank12p 0:b0c4c25d37ab 163 /* Request Methods */
priyank12p 0:b0c4c25d37ab 164 #define HTTP_METHOD_MAP(XX) \
priyank12p 0:b0c4c25d37ab 165 XX(0, DELETE, DELETE) \
priyank12p 0:b0c4c25d37ab 166 XX(1, GET, GET) \
priyank12p 0:b0c4c25d37ab 167 XX(2, HEAD, HEAD) \
priyank12p 0:b0c4c25d37ab 168 XX(3, POST, POST) \
priyank12p 0:b0c4c25d37ab 169 XX(4, PUT, PUT) \
priyank12p 0:b0c4c25d37ab 170 /* pathological */ \
priyank12p 0:b0c4c25d37ab 171 XX(5, CONNECT, CONNECT) \
priyank12p 0:b0c4c25d37ab 172 XX(6, OPTIONS, OPTIONS) \
priyank12p 0:b0c4c25d37ab 173 XX(7, TRACE, TRACE) \
priyank12p 0:b0c4c25d37ab 174 /* WebDAV */ \
priyank12p 0:b0c4c25d37ab 175 XX(8, COPY, COPY) \
priyank12p 0:b0c4c25d37ab 176 XX(9, LOCK, LOCK) \
priyank12p 0:b0c4c25d37ab 177 XX(10, MKCOL, MKCOL) \
priyank12p 0:b0c4c25d37ab 178 XX(11, MOVE, MOVE) \
priyank12p 0:b0c4c25d37ab 179 XX(12, PROPFIND, PROPFIND) \
priyank12p 0:b0c4c25d37ab 180 XX(13, PROPPATCH, PROPPATCH) \
priyank12p 0:b0c4c25d37ab 181 XX(14, SEARCH, SEARCH) \
priyank12p 0:b0c4c25d37ab 182 XX(15, UNLOCK, UNLOCK) \
priyank12p 0:b0c4c25d37ab 183 XX(16, BIND, BIND) \
priyank12p 0:b0c4c25d37ab 184 XX(17, REBIND, REBIND) \
priyank12p 0:b0c4c25d37ab 185 XX(18, UNBIND, UNBIND) \
priyank12p 0:b0c4c25d37ab 186 XX(19, ACL, ACL) \
priyank12p 0:b0c4c25d37ab 187 /* subversion */ \
priyank12p 0:b0c4c25d37ab 188 XX(20, REPORT, REPORT) \
priyank12p 0:b0c4c25d37ab 189 XX(21, MKACTIVITY, MKACTIVITY) \
priyank12p 0:b0c4c25d37ab 190 XX(22, CHECKOUT, CHECKOUT) \
priyank12p 0:b0c4c25d37ab 191 XX(23, MERGE, MERGE) \
priyank12p 0:b0c4c25d37ab 192 /* upnp */ \
priyank12p 0:b0c4c25d37ab 193 XX(24, MSEARCH, M-SEARCH) \
priyank12p 0:b0c4c25d37ab 194 XX(25, NOTIFY, NOTIFY) \
priyank12p 0:b0c4c25d37ab 195 XX(26, SUBSCRIBE, SUBSCRIBE) \
priyank12p 0:b0c4c25d37ab 196 XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
priyank12p 0:b0c4c25d37ab 197 /* RFC-5789 */ \
priyank12p 0:b0c4c25d37ab 198 XX(28, PATCH, PATCH) \
priyank12p 0:b0c4c25d37ab 199 XX(29, PURGE, PURGE) \
priyank12p 0:b0c4c25d37ab 200 /* CalDAV */ \
priyank12p 0:b0c4c25d37ab 201 XX(30, MKCALENDAR, MKCALENDAR) \
priyank12p 0:b0c4c25d37ab 202 /* RFC-2068, section 19.6.1.2 */ \
priyank12p 0:b0c4c25d37ab 203 XX(31, LINK, LINK) \
priyank12p 0:b0c4c25d37ab 204 XX(32, UNLINK, UNLINK) \
priyank12p 0:b0c4c25d37ab 205
priyank12p 0:b0c4c25d37ab 206 enum http_method
priyank12p 0:b0c4c25d37ab 207 {
priyank12p 0:b0c4c25d37ab 208 #define XX(num, name, string) HTTP_##name = num,
priyank12p 0:b0c4c25d37ab 209 HTTP_METHOD_MAP(XX)
priyank12p 0:b0c4c25d37ab 210 #undef XX
priyank12p 0:b0c4c25d37ab 211 };
priyank12p 0:b0c4c25d37ab 212
priyank12p 0:b0c4c25d37ab 213
priyank12p 0:b0c4c25d37ab 214 enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
priyank12p 0:b0c4c25d37ab 215
priyank12p 0:b0c4c25d37ab 216
priyank12p 0:b0c4c25d37ab 217 /* Flag values for http_parser.flags field */
priyank12p 0:b0c4c25d37ab 218 enum flags
priyank12p 0:b0c4c25d37ab 219 { F_CHUNKED = 1 << 0
priyank12p 0:b0c4c25d37ab 220 , F_CONNECTION_KEEP_ALIVE = 1 << 1
priyank12p 0:b0c4c25d37ab 221 , F_CONNECTION_CLOSE = 1 << 2
priyank12p 0:b0c4c25d37ab 222 , F_CONNECTION_UPGRADE = 1 << 3
priyank12p 0:b0c4c25d37ab 223 , F_TRAILING = 1 << 4
priyank12p 0:b0c4c25d37ab 224 , F_UPGRADE = 1 << 5
priyank12p 0:b0c4c25d37ab 225 , F_SKIPBODY = 1 << 6
priyank12p 0:b0c4c25d37ab 226 , F_CONTENTLENGTH = 1 << 7
priyank12p 0:b0c4c25d37ab 227 };
priyank12p 0:b0c4c25d37ab 228
priyank12p 0:b0c4c25d37ab 229
priyank12p 0:b0c4c25d37ab 230 /* Map for errno-related constants
priyank12p 0:b0c4c25d37ab 231 *
priyank12p 0:b0c4c25d37ab 232 * The provided argument should be a macro that takes 2 arguments.
priyank12p 0:b0c4c25d37ab 233 */
priyank12p 0:b0c4c25d37ab 234 #define HTTP_ERRNO_MAP(XX) \
priyank12p 0:b0c4c25d37ab 235 /* No error */ \
priyank12p 0:b0c4c25d37ab 236 XX(OK, "success") \
priyank12p 0:b0c4c25d37ab 237 \
priyank12p 0:b0c4c25d37ab 238 /* Callback-related errors */ \
priyank12p 0:b0c4c25d37ab 239 XX(CB_message_begin, "the on_message_begin callback failed") \
priyank12p 0:b0c4c25d37ab 240 XX(CB_url, "the on_url callback failed") \
priyank12p 0:b0c4c25d37ab 241 XX(CB_header_field, "the on_header_field callback failed") \
priyank12p 0:b0c4c25d37ab 242 XX(CB_header_value, "the on_header_value callback failed") \
priyank12p 0:b0c4c25d37ab 243 XX(CB_headers_complete, "the on_headers_complete callback failed") \
priyank12p 0:b0c4c25d37ab 244 XX(CB_body, "the on_body callback failed") \
priyank12p 0:b0c4c25d37ab 245 XX(CB_message_complete, "the on_message_complete callback failed") \
priyank12p 0:b0c4c25d37ab 246 XX(CB_status, "the on_status callback failed") \
priyank12p 0:b0c4c25d37ab 247 XX(CB_chunk_header, "the on_chunk_header callback failed") \
priyank12p 0:b0c4c25d37ab 248 XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
priyank12p 0:b0c4c25d37ab 249 \
priyank12p 0:b0c4c25d37ab 250 /* Parsing-related errors */ \
priyank12p 0:b0c4c25d37ab 251 XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
priyank12p 0:b0c4c25d37ab 252 XX(HEADER_OVERFLOW, \
priyank12p 0:b0c4c25d37ab 253 "too many header bytes seen; overflow detected") \
priyank12p 0:b0c4c25d37ab 254 XX(CLOSED_CONNECTION, \
priyank12p 0:b0c4c25d37ab 255 "data received after completed connection: close message") \
priyank12p 0:b0c4c25d37ab 256 XX(INVALID_VERSION, "invalid HTTP version") \
priyank12p 0:b0c4c25d37ab 257 XX(INVALID_STATUS, "invalid HTTP status code") \
priyank12p 0:b0c4c25d37ab 258 XX(INVALID_METHOD, "invalid HTTP method") \
priyank12p 0:b0c4c25d37ab 259 XX(INVALID_URL, "invalid URL") \
priyank12p 0:b0c4c25d37ab 260 XX(INVALID_HOST, "invalid host") \
priyank12p 0:b0c4c25d37ab 261 XX(INVALID_PORT, "invalid port") \
priyank12p 0:b0c4c25d37ab 262 XX(INVALID_PATH, "invalid path") \
priyank12p 0:b0c4c25d37ab 263 XX(INVALID_QUERY_STRING, "invalid query string") \
priyank12p 0:b0c4c25d37ab 264 XX(INVALID_FRAGMENT, "invalid fragment") \
priyank12p 0:b0c4c25d37ab 265 XX(LF_EXPECTED, "LF character expected") \
priyank12p 0:b0c4c25d37ab 266 XX(INVALID_HEADER_TOKEN, "invalid character in header") \
priyank12p 0:b0c4c25d37ab 267 XX(INVALID_CONTENT_LENGTH, \
priyank12p 0:b0c4c25d37ab 268 "invalid character in content-length header") \
priyank12p 0:b0c4c25d37ab 269 XX(UNEXPECTED_CONTENT_LENGTH, \
priyank12p 0:b0c4c25d37ab 270 "unexpected content-length header") \
priyank12p 0:b0c4c25d37ab 271 XX(INVALID_CHUNK_SIZE, \
priyank12p 0:b0c4c25d37ab 272 "invalid character in chunk size header") \
priyank12p 0:b0c4c25d37ab 273 XX(INVALID_CONSTANT, "invalid constant string") \
priyank12p 0:b0c4c25d37ab 274 XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
priyank12p 0:b0c4c25d37ab 275 XX(STRICT, "strict mode assertion failed") \
priyank12p 0:b0c4c25d37ab 276 XX(PAUSED, "parser is paused") \
priyank12p 0:b0c4c25d37ab 277 XX(UNKNOWN, "an unknown error occurred")
priyank12p 0:b0c4c25d37ab 278
priyank12p 0:b0c4c25d37ab 279
priyank12p 0:b0c4c25d37ab 280 /* Define HPE_* values for each errno value above */
priyank12p 0:b0c4c25d37ab 281 #define HTTP_ERRNO_GEN(n, s) HPE_##n,
priyank12p 0:b0c4c25d37ab 282 enum http_errno {
priyank12p 0:b0c4c25d37ab 283 HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
priyank12p 0:b0c4c25d37ab 284 };
priyank12p 0:b0c4c25d37ab 285 #undef HTTP_ERRNO_GEN
priyank12p 0:b0c4c25d37ab 286
priyank12p 0:b0c4c25d37ab 287
priyank12p 0:b0c4c25d37ab 288 /* Get an http_errno value from an http_parser */
priyank12p 0:b0c4c25d37ab 289 #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
priyank12p 0:b0c4c25d37ab 290
priyank12p 0:b0c4c25d37ab 291
priyank12p 0:b0c4c25d37ab 292 struct http_parser {
priyank12p 0:b0c4c25d37ab 293 /** PRIVATE **/
priyank12p 0:b0c4c25d37ab 294 unsigned int type : 2; /* enum http_parser_type */
priyank12p 0:b0c4c25d37ab 295 unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
priyank12p 0:b0c4c25d37ab 296 unsigned int state : 7; /* enum state from http_parser.c */
priyank12p 0:b0c4c25d37ab 297 unsigned int header_state : 7; /* enum header_state from http_parser.c */
priyank12p 0:b0c4c25d37ab 298 unsigned int index : 7; /* index into current matcher */
priyank12p 0:b0c4c25d37ab 299 unsigned int lenient_http_headers : 1;
priyank12p 0:b0c4c25d37ab 300
priyank12p 0:b0c4c25d37ab 301 uint32_t nread; /* # bytes read in various scenarios */
priyank12p 0:b0c4c25d37ab 302 uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
priyank12p 0:b0c4c25d37ab 303
priyank12p 0:b0c4c25d37ab 304 /** READ-ONLY **/
priyank12p 0:b0c4c25d37ab 305 unsigned short http_major;
priyank12p 0:b0c4c25d37ab 306 unsigned short http_minor;
priyank12p 0:b0c4c25d37ab 307 unsigned int status_code : 16; /* responses only */
priyank12p 0:b0c4c25d37ab 308 unsigned int method : 8; /* requests only */
priyank12p 0:b0c4c25d37ab 309 unsigned int http_errno : 7;
priyank12p 0:b0c4c25d37ab 310
priyank12p 0:b0c4c25d37ab 311 /* 1 = Upgrade header was present and the parser has exited because of that.
priyank12p 0:b0c4c25d37ab 312 * 0 = No upgrade header present.
priyank12p 0:b0c4c25d37ab 313 * Should be checked when http_parser_execute() returns in addition to
priyank12p 0:b0c4c25d37ab 314 * error checking.
priyank12p 0:b0c4c25d37ab 315 */
priyank12p 0:b0c4c25d37ab 316 unsigned int upgrade : 1;
priyank12p 0:b0c4c25d37ab 317
priyank12p 0:b0c4c25d37ab 318 /** PUBLIC **/
priyank12p 0:b0c4c25d37ab 319 void *data; /* A pointer to get hook to the "connection" or "socket" object */
priyank12p 0:b0c4c25d37ab 320 };
priyank12p 0:b0c4c25d37ab 321
priyank12p 0:b0c4c25d37ab 322
priyank12p 0:b0c4c25d37ab 323 struct http_parser_settings {
priyank12p 0:b0c4c25d37ab 324 http_cb on_message_begin;
priyank12p 0:b0c4c25d37ab 325 http_data_cb on_url;
priyank12p 0:b0c4c25d37ab 326 http_data_cb on_status;
priyank12p 0:b0c4c25d37ab 327 http_data_cb on_header_field;
priyank12p 0:b0c4c25d37ab 328 http_data_cb on_header_value;
priyank12p 0:b0c4c25d37ab 329 http_cb on_headers_complete;
priyank12p 0:b0c4c25d37ab 330 http_data_cb on_body;
priyank12p 0:b0c4c25d37ab 331 http_cb on_message_complete;
priyank12p 0:b0c4c25d37ab 332 /* When on_chunk_header is called, the current chunk length is stored
priyank12p 0:b0c4c25d37ab 333 * in parser->content_length.
priyank12p 0:b0c4c25d37ab 334 */
priyank12p 0:b0c4c25d37ab 335 http_cb on_chunk_header;
priyank12p 0:b0c4c25d37ab 336 http_cb on_chunk_complete;
priyank12p 0:b0c4c25d37ab 337 };
priyank12p 0:b0c4c25d37ab 338
priyank12p 0:b0c4c25d37ab 339
priyank12p 0:b0c4c25d37ab 340 enum http_parser_url_fields
priyank12p 0:b0c4c25d37ab 341 { UF_SCHEMA = 0
priyank12p 0:b0c4c25d37ab 342 , UF_HOST = 1
priyank12p 0:b0c4c25d37ab 343 , UF_PORT = 2
priyank12p 0:b0c4c25d37ab 344 , UF_PATH = 3
priyank12p 0:b0c4c25d37ab 345 , UF_QUERY = 4
priyank12p 0:b0c4c25d37ab 346 , UF_FRAGMENT = 5
priyank12p 0:b0c4c25d37ab 347 , UF_USERINFO = 6
priyank12p 0:b0c4c25d37ab 348 , UF_MAX = 7
priyank12p 0:b0c4c25d37ab 349 };
priyank12p 0:b0c4c25d37ab 350
priyank12p 0:b0c4c25d37ab 351
priyank12p 0:b0c4c25d37ab 352 /* Result structure for http_parser_parse_url().
priyank12p 0:b0c4c25d37ab 353 *
priyank12p 0:b0c4c25d37ab 354 * Callers should index into field_data[] with UF_* values iff field_set
priyank12p 0:b0c4c25d37ab 355 * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
priyank12p 0:b0c4c25d37ab 356 * because we probably have padding left over), we convert any port to
priyank12p 0:b0c4c25d37ab 357 * a uint16_t.
priyank12p 0:b0c4c25d37ab 358 */
priyank12p 0:b0c4c25d37ab 359 struct http_parser_url {
priyank12p 0:b0c4c25d37ab 360 uint16_t field_set; /* Bitmask of (1 << UF_*) values */
priyank12p 0:b0c4c25d37ab 361 uint16_t port; /* Converted UF_PORT string */
priyank12p 0:b0c4c25d37ab 362
priyank12p 0:b0c4c25d37ab 363 struct {
priyank12p 0:b0c4c25d37ab 364 uint16_t off; /* Offset into buffer in which field starts */
priyank12p 0:b0c4c25d37ab 365 uint16_t len; /* Length of run in buffer */
priyank12p 0:b0c4c25d37ab 366 } field_data[UF_MAX];
priyank12p 0:b0c4c25d37ab 367 };
priyank12p 0:b0c4c25d37ab 368
priyank12p 0:b0c4c25d37ab 369
priyank12p 0:b0c4c25d37ab 370 /* Returns the library version. Bits 16-23 contain the major version number,
priyank12p 0:b0c4c25d37ab 371 * bits 8-15 the minor version number and bits 0-7 the patch level.
priyank12p 0:b0c4c25d37ab 372 * Usage example:
priyank12p 0:b0c4c25d37ab 373 *
priyank12p 0:b0c4c25d37ab 374 * unsigned long version = http_parser_version();
priyank12p 0:b0c4c25d37ab 375 * unsigned major = (version >> 16) & 255;
priyank12p 0:b0c4c25d37ab 376 * unsigned minor = (version >> 8) & 255;
priyank12p 0:b0c4c25d37ab 377 * unsigned patch = version & 255;
priyank12p 0:b0c4c25d37ab 378 * printf("http_parser v%u.%u.%u\n", major, minor, patch);
priyank12p 0:b0c4c25d37ab 379 */
priyank12p 0:b0c4c25d37ab 380 unsigned long http_parser_version(void);
priyank12p 0:b0c4c25d37ab 381
priyank12p 0:b0c4c25d37ab 382 void http_parser_init(http_parser *parser, enum http_parser_type type);
priyank12p 0:b0c4c25d37ab 383
priyank12p 0:b0c4c25d37ab 384
priyank12p 0:b0c4c25d37ab 385 /* Initialize http_parser_settings members to 0
priyank12p 0:b0c4c25d37ab 386 */
priyank12p 0:b0c4c25d37ab 387 void http_parser_settings_init(http_parser_settings *settings);
priyank12p 0:b0c4c25d37ab 388
priyank12p 0:b0c4c25d37ab 389
priyank12p 0:b0c4c25d37ab 390 /* Executes the parser. Returns number of parsed bytes. Sets
priyank12p 0:b0c4c25d37ab 391 * `parser->http_errno` on error. */
priyank12p 0:b0c4c25d37ab 392 uint32_t http_parser_execute(http_parser *parser,
priyank12p 0:b0c4c25d37ab 393 const http_parser_settings *settings,
priyank12p 0:b0c4c25d37ab 394 const char *data,
priyank12p 0:b0c4c25d37ab 395 uint32_t len);
priyank12p 0:b0c4c25d37ab 396
priyank12p 0:b0c4c25d37ab 397
priyank12p 0:b0c4c25d37ab 398 /* If http_should_keep_alive() in the on_headers_complete or
priyank12p 0:b0c4c25d37ab 399 * on_message_complete callback returns 0, then this should be
priyank12p 0:b0c4c25d37ab 400 * the last message on the connection.
priyank12p 0:b0c4c25d37ab 401 * If you are the server, respond with the "Connection: close" header.
priyank12p 0:b0c4c25d37ab 402 * If you are the client, close the connection.
priyank12p 0:b0c4c25d37ab 403 */
priyank12p 0:b0c4c25d37ab 404 int http_should_keep_alive(const http_parser *parser);
priyank12p 0:b0c4c25d37ab 405
priyank12p 0:b0c4c25d37ab 406 /* Returns a string version of the HTTP method. */
priyank12p 0:b0c4c25d37ab 407 const char *http_method_str(enum http_method m);
priyank12p 0:b0c4c25d37ab 408
priyank12p 0:b0c4c25d37ab 409 /* Return a string name of the given error */
priyank12p 0:b0c4c25d37ab 410 const char *http_errno_name(enum http_errno err);
priyank12p 0:b0c4c25d37ab 411
priyank12p 0:b0c4c25d37ab 412 /* Return a string description of the given error */
priyank12p 0:b0c4c25d37ab 413 const char *http_errno_description(enum http_errno err);
priyank12p 0:b0c4c25d37ab 414
priyank12p 0:b0c4c25d37ab 415 /* Initialize all http_parser_url members to 0 */
priyank12p 0:b0c4c25d37ab 416 void http_parser_url_init(struct http_parser_url *u);
priyank12p 0:b0c4c25d37ab 417
priyank12p 0:b0c4c25d37ab 418 /* Parse a URL; return nonzero on failure */
priyank12p 0:b0c4c25d37ab 419 int http_parser_parse_url(const char *buf, uint32_t buflen,
priyank12p 0:b0c4c25d37ab 420 int is_connect,
priyank12p 0:b0c4c25d37ab 421 struct http_parser_url *u);
priyank12p 0:b0c4c25d37ab 422
priyank12p 0:b0c4c25d37ab 423 /* Pause or un-pause the parser; a nonzero value pauses */
priyank12p 0:b0c4c25d37ab 424 void http_parser_pause(http_parser *parser, int paused);
priyank12p 0:b0c4c25d37ab 425
priyank12p 0:b0c4c25d37ab 426 /* Checks if this is the final chunk of the body. */
priyank12p 0:b0c4c25d37ab 427 int http_body_is_final(const http_parser *parser);
priyank12p 0:b0c4c25d37ab 428
priyank12p 0:b0c4c25d37ab 429 #ifdef __cplusplus
priyank12p 0:b0c4c25d37ab 430 }
priyank12p 0:b0c4c25d37ab 431 #endif
priyank12p 0:b0c4c25d37ab 432 #endif