PageRenderTime 61ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/ngx_http_ajp_msg.c

https://github.com/yaoweibin/nginx_ajp_module
C | 482 lines | 330 code | 149 blank | 3 comment | 55 complexity | 622b1ef04fd34446fc600da827dc234a MD5 | raw file
  1. #include "ngx_http_ajp.h"
  2. extern volatile ngx_cycle_t *ngx_cycle;
  3. static ngx_int_t
  4. ajp_msg_check_header(ajp_msg_t *msg)
  5. {
  6. u_char *head = msg->buf->pos;
  7. if (!((head[0] == 0x41 && head[1] == 0x42) ||
  8. (head[0] == 0x12 && head[1] == 0x34)))
  9. {
  10. ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
  11. "ajp_check_msg_header() got bad signature %02Xd%02Xd",
  12. head[0], head[1]);
  13. return NGX_ERROR;
  14. }
  15. return NGX_OK;
  16. }
  17. ngx_int_t
  18. ajp_msg_is_zero_length(u_char *head)
  19. {
  20. if (head[0] == 0x41 && head[1] == 0x42 &&
  21. head[3] == 0x00 && head[4] == 0x00)
  22. {
  23. return 1;
  24. }
  25. return 0;
  26. }
  27. ngx_int_t
  28. ajp_msg_parse_begin(ajp_msg_t *msg)
  29. {
  30. ngx_buf_t *buf = msg->buf;
  31. if (buf->last <= buf->pos + AJP_HEADER_LEN) {
  32. return NGX_ERROR;
  33. }
  34. if (ajp_msg_check_header(msg) != NGX_OK) {
  35. return NGX_ERROR;
  36. }
  37. buf->pos += AJP_HEADER_LEN;
  38. return NGX_OK;
  39. }
  40. ngx_int_t
  41. ajp_msg_reset(ajp_msg_t *msg)
  42. {
  43. ngx_buf_t *buf = msg->buf;
  44. if (buf->end > buf->start + AJP_HEADER_LEN) {
  45. buf->pos = buf->last = buf->start + AJP_HEADER_LEN;
  46. } else {
  47. return NGX_ERROR;
  48. }
  49. return NGX_OK;
  50. }
  51. ajp_msg_t *
  52. ajp_msg_reuse(ajp_msg_t *msg)
  53. {
  54. memset(msg, 0, sizeof(ajp_msg_t));
  55. return msg;
  56. }
  57. ngx_int_t
  58. ajp_msg_end(ajp_msg_t *msg)
  59. {
  60. size_t len;
  61. ngx_buf_t *buf;
  62. buf = msg->buf;
  63. len = buf->last - buf->start - AJP_HEADER_LEN;
  64. if (msg->server_side) {
  65. buf->start[0] = 0x41;
  66. buf->start[1] = 0x42;
  67. } else {
  68. buf->start[0] = 0x12;
  69. buf->start[1] = 0x34;
  70. }
  71. buf->start[2] = (u_char)((len >> 8) & 0xFF);
  72. buf->start[3] = (u_char)(len & 0xFF);
  73. buf->pos = buf->start;
  74. return NGX_OK;
  75. }
  76. ngx_int_t
  77. ajp_log_overflow(ajp_msg_t *msg, const char *context)
  78. {
  79. ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0,
  80. "%s(): BufferOverflowException pos:%p, last:%p, end:%p",
  81. context, msg->buf->pos, msg->buf->last, msg->buf->end);
  82. return AJP_EOVERFLOW;
  83. }
  84. ngx_int_t
  85. ajp_msg_append_uint32(ajp_msg_t *msg, uint32_t value)
  86. {
  87. ngx_buf_t *buf;
  88. buf = msg->buf;
  89. if ((buf->last + 4) > buf->end) {
  90. return ajp_log_overflow(msg, "ajp_msg_append_uint32");
  91. }
  92. *buf->last++ = (u_char)((value >> 24) & 0xFF);
  93. *buf->last++ = (u_char)((value >> 16) & 0xFF);
  94. *buf->last++ = (u_char)((value >> 8) & 0xFF);
  95. *buf->last++ = (u_char)(value & 0xFF);
  96. return NGX_OK;
  97. }
  98. ngx_int_t
  99. ajp_msg_append_uint16(ajp_msg_t *msg, uint16_t value)
  100. {
  101. ngx_buf_t *buf;
  102. buf = msg->buf;
  103. if ((buf->last + 2) > buf->end) {
  104. return ajp_log_overflow(msg, "ajp_msg_append_uint16");
  105. }
  106. *buf->last++ = (u_char)((value >> 8) & 0xFF);
  107. *buf->last++ = (u_char)(value & 0xFF);
  108. return NGX_OK;
  109. }
  110. ngx_int_t
  111. ajp_msg_append_uint8(ajp_msg_t *msg, u_char value)
  112. {
  113. ngx_buf_t *buf;
  114. buf = msg->buf;
  115. if ((buf->last + 1) > buf->end) {
  116. return ajp_log_overflow(msg, "ajp_msg_append_uint8");
  117. }
  118. *buf->last++ = value;
  119. return NGX_OK;
  120. }
  121. ngx_int_t
  122. ajp_msg_append_string(ajp_msg_t *msg, ngx_str_t *value)
  123. {
  124. ngx_buf_t *buf;
  125. if (value == NULL) {
  126. return(ajp_msg_append_uint16(msg, 0xFFFF));
  127. }
  128. buf = msg->buf;
  129. if ((buf->last + 2 + value->len + 1) > buf->end) {
  130. return ajp_log_overflow(msg, "ajp_msg_append_cvt_string");
  131. }
  132. ajp_msg_append_uint16(msg, (uint16_t) value->len);
  133. ngx_memcpy(buf->last, value->data, value->len);
  134. buf->last += value->len;
  135. *buf->last++ = '\0';
  136. return NGX_OK;
  137. }
  138. ngx_int_t
  139. ajp_msg_get_uint32(ajp_msg_t *msg, uint32_t *rvalue)
  140. {
  141. uint32_t value;
  142. ngx_buf_t *buf;
  143. buf = msg->buf;
  144. if ((buf->pos + 4) > buf->last) {
  145. return ajp_log_overflow(msg, "ajp_msg_get_uint32");
  146. }
  147. value = ((*buf->pos++ & 0xFF) << 24);
  148. value |= ((*buf->pos++ & 0xFF) << 16);
  149. value |= ((*buf->pos++ & 0xFF) << 8);
  150. value |= ((*buf->pos++ & 0xFF));
  151. *rvalue = value;
  152. return NGX_OK;
  153. }
  154. ngx_int_t
  155. ajp_msg_get_uint16(ajp_msg_t *msg, uint16_t *rvalue)
  156. {
  157. uint16_t value;
  158. ngx_buf_t *buf;
  159. buf = msg->buf;
  160. if ((buf->pos + 2) > buf->last) {
  161. return ajp_log_overflow(msg, "ajp_msg_get_uint16");
  162. }
  163. value = ((*buf->pos++ & 0xFF) << 8);
  164. value += ((*buf->pos++) & 0xFF);
  165. *rvalue = value;
  166. return NGX_OK;
  167. }
  168. ngx_int_t
  169. ajp_msg_peek_uint16(ajp_msg_t *msg, uint16_t *rvalue)
  170. {
  171. uint16_t value;
  172. ngx_buf_t *buf;
  173. buf = msg->buf;
  174. if ((buf->pos + 2) > buf->last) {
  175. return ajp_log_overflow(msg, "ajp_msg_peek_uint16");
  176. }
  177. value = ((*buf->pos & 0xFF) << 8);
  178. value += ((*buf->pos + 1) & 0xFF);
  179. *rvalue = value;
  180. return NGX_OK;
  181. }
  182. ngx_int_t
  183. ajp_msg_peek_uint8(ajp_msg_t *msg, u_char *rvalue)
  184. {
  185. if ((msg->buf->pos + 1) > msg->buf->last) {
  186. return ajp_log_overflow(msg, "ajp_msg_peek_uint8");
  187. }
  188. *rvalue = *msg->buf->pos;
  189. return NGX_OK;
  190. }
  191. ngx_int_t
  192. ajp_msg_get_uint8(ajp_msg_t *msg, u_char *rvalue)
  193. {
  194. if ((msg->buf->pos + 1) > msg->buf->last) {
  195. return ajp_log_overflow(msg, "ajp_msg_get_uint8");
  196. }
  197. *rvalue = *msg->buf->pos++;
  198. return NGX_OK;
  199. }
  200. ngx_int_t
  201. ajp_msg_get_string(ajp_msg_t *msg, ngx_str_t *value)
  202. {
  203. u_char *start;
  204. uint16_t size;
  205. ngx_int_t status;
  206. ngx_buf_t *buf;
  207. buf = msg->buf;
  208. status = ajp_msg_get_uint16(msg, &size);
  209. start = buf->pos;
  210. if ((status != NGX_OK) || (start + size + 1 > buf->last)) {
  211. return ajp_log_overflow(msg, "ajp_msg_get_string");
  212. }
  213. buf->pos += (size_t)size;
  214. buf->pos++; /* a String in AJP is NULL terminated */
  215. value->data = start;
  216. value->len = size;
  217. return NGX_OK;
  218. }
  219. ngx_int_t
  220. ajp_msg_create(ngx_pool_t *pool, size_t size, ajp_msg_t **rmsg)
  221. {
  222. ajp_msg_t *msg;
  223. msg = (ajp_msg_t *)ngx_pcalloc(pool, sizeof(ajp_msg_t));
  224. if (msg == NULL) {
  225. return NGX_ERROR;
  226. }
  227. msg->server_side = 0;
  228. msg->buf = ngx_create_temp_buf(pool, size);
  229. if (msg->buf == NULL) {
  230. return NGX_ERROR;
  231. }
  232. *rmsg = msg;
  233. return NGX_OK;
  234. }
  235. ngx_int_t
  236. ajp_msg_create_buffer(ngx_pool_t *pool, size_t size, ajp_msg_t *msg)
  237. {
  238. msg->server_side = 0;
  239. msg->buf = ngx_create_temp_buf(pool, size);
  240. if (msg->buf == NULL) {
  241. return NGX_ERROR;
  242. }
  243. return NGX_OK;
  244. }
  245. ngx_int_t
  246. ajp_msg_create_without_buffer(ngx_pool_t *pool, ajp_msg_t **rmsg)
  247. {
  248. ajp_msg_t *msg;
  249. msg = (ajp_msg_t *)ngx_pcalloc(pool, sizeof(ajp_msg_t));
  250. if (msg == NULL) {
  251. return NGX_ERROR;
  252. }
  253. msg->server_side = 0;
  254. *rmsg = msg;
  255. return NGX_OK;
  256. }
  257. ngx_int_t
  258. ajp_alloc_data_msg(ngx_pool_t *pool, ajp_msg_t *msg)
  259. {
  260. ngx_int_t rc;
  261. if ((rc = ajp_msg_create_buffer(pool, AJP_HEADER_SZ + 1, msg)) != NGX_OK) {
  262. return rc;
  263. }
  264. ajp_msg_reset(msg);
  265. return NGX_OK;
  266. }
  267. ngx_int_t
  268. ajp_data_msg_end(ajp_msg_t *msg, size_t len)
  269. {
  270. ngx_buf_t *buf;
  271. buf = msg->buf;
  272. buf->last = buf->start + AJP_HEADER_SZ;
  273. ajp_msg_end(msg);
  274. buf->start[AJP_HEADER_SZ - 2] = (u_char)((len >> 8) & 0xFF);
  275. buf->start[AJP_HEADER_SZ - 1] = (u_char)(len & 0xFF);
  276. /* len include AJP_HEADER_SIZE_LEN */
  277. len += AJP_HEADER_SZ_LEN;
  278. buf->start[AJP_HEADER_LEN - 2] = (u_char)((len >> 8) & 0xFF);
  279. buf->start[AJP_HEADER_LEN - 1] = (u_char)(len & 0xFF);
  280. return NGX_OK;
  281. }
  282. u_char *
  283. ajp_msg_dump(ngx_pool_t *pool, ajp_msg_t *msg, char *err)
  284. {
  285. size_t i, len, dump;
  286. u_char *rv, *p, *last;
  287. ngx_buf_t *buf;
  288. buf = msg->buf;
  289. dump = DUMP_LENGTH;
  290. if (dump >(size_t)(buf->last - buf->pos)) {
  291. dump = buf->last - buf->pos;
  292. }
  293. len = dump + 256;
  294. p = rv = ngx_pcalloc(pool, len);
  295. if (rv == NULL) {
  296. return NULL;
  297. }
  298. last = rv + len;
  299. p = ngx_snprintf(p, len,
  300. "ajp_msg_dump(): \"%s\", start:%p, pos:%p, last:%p \n"
  301. "dump packet: \n",
  302. err, buf->start, buf->pos, buf->last);
  303. for (i = 0; i < dump; i ++) {
  304. p = ngx_snprintf(p, last - p, "%02xd ", buf->pos[i]);
  305. if ((i+1) % 16 == 0) {
  306. p = ngx_snprintf(p, last - p, "\n");
  307. }
  308. }
  309. p = ngx_snprintf(p, last - p, "\n");
  310. return rv;
  311. }
  312. /* TODO: health check */
  313. ngx_int_t
  314. ajp_msg_serialize_ping(ajp_msg_t *msg)
  315. {
  316. ngx_int_t rc;
  317. ajp_msg_reset(msg);
  318. if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_PING)) != NGX_OK) {
  319. return rc;
  320. }
  321. return NGX_OK;
  322. }
  323. /* TODO: health check */
  324. ngx_int_t
  325. ajp_msg_serialize_cping(ajp_msg_t *msg)
  326. {
  327. ngx_int_t rc;
  328. ajp_msg_reset(msg);
  329. if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_CPING)) != NGX_OK) {
  330. return rc;
  331. }
  332. return NGX_OK;
  333. }