comparison src/http/modules/ngx_http_uwsgi_module.c @ 3627:9061fdb2ed8c

use ngx_http_parse_status_line()
author Igor Sysoev <igor@sysoev.ru>
date Tue, 15 Jun 2010 15:15:06 +0000
parents 8a6b36db2398
children cf47471a9eda
comparison
equal deleted inserted replaced
3626:e4cabc48b862 3627:9061fdb2ed8c
50 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r, 50 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
51 ngx_http_uwsgi_loc_conf_t *uwcf); 51 ngx_http_uwsgi_loc_conf_t *uwcf);
52 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r); 52 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
53 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r); 53 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
54 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r); 54 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
55 static ngx_int_t ngx_http_uwsgi_parse_status_line(ngx_http_request_t *r,
56 ngx_http_uwsgi_ctx_t *ctx);
57 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); 55 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
58 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); 56 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
59 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r); 57 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
60 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, 58 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
61 ngx_int_t rc); 59 ngx_int_t rc);
864 return NGX_OK; 862 return NGX_OK;
865 } 863 }
866 864
867 865
868 static ngx_int_t 866 static ngx_int_t
869 ngx_http_uwsgi_parse_status_line(ngx_http_request_t *r,
870 ngx_http_uwsgi_ctx_t *ctx)
871 {
872 u_char ch;
873 u_char *p;
874 ngx_http_upstream_t *u;
875 enum {
876 sw_start = 0,
877 sw_H,
878 sw_HT,
879 sw_HTT,
880 sw_HTTP,
881 sw_first_major_digit,
882 sw_major_digit,
883 sw_first_minor_digit,
884 sw_minor_digit,
885 sw_status,
886 sw_space_after_status,
887 sw_status_text,
888 sw_almost_done
889 } state;
890
891 u = r->upstream;
892
893 state = r->state;
894
895 for (p = u->buffer.pos; p < u->buffer.last; p++) {
896 ch = *p;
897
898 switch (state) {
899
900 /* "HTTP/" */
901 case sw_start:
902 switch (ch) {
903 case 'H':
904 state = sw_H;
905 break;
906 default:
907 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
908 }
909 break;
910
911 case sw_H:
912 switch (ch) {
913 case 'T':
914 state = sw_HT;
915 break;
916 default:
917 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
918 }
919 break;
920
921 case sw_HT:
922 switch (ch) {
923 case 'T':
924 state = sw_HTT;
925 break;
926 default:
927 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
928 }
929 break;
930
931 case sw_HTT:
932 switch (ch) {
933 case 'P':
934 state = sw_HTTP;
935 break;
936 default:
937 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
938 }
939 break;
940
941 case sw_HTTP:
942 switch (ch) {
943 case '/':
944 state = sw_first_major_digit;
945 break;
946 default:
947 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
948 }
949 break;
950
951 /* the first digit of major HTTP version */
952 case sw_first_major_digit:
953 if (ch < '1' || ch > '9') {
954 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
955 }
956
957 state = sw_major_digit;
958 break;
959
960 /* the major HTTP version or dot */
961 case sw_major_digit:
962 if (ch == '.') {
963 state = sw_first_minor_digit;
964 break;
965 }
966
967 if (ch < '0' || ch > '9') {
968 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
969 }
970
971 break;
972
973 /* the first digit of minor HTTP version */
974 case sw_first_minor_digit:
975 if (ch < '0' || ch > '9') {
976 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
977 }
978
979 state = sw_minor_digit;
980 break;
981
982 /* the minor HTTP version or the end of the request line */
983 case sw_minor_digit:
984 if (ch == ' ') {
985 state = sw_status;
986 break;
987 }
988
989 if (ch < '0' || ch > '9') {
990 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
991 }
992
993 break;
994
995 /* HTTP status code */
996 case sw_status:
997 if (ch == ' ') {
998 break;
999 }
1000
1001 if (ch < '0' || ch > '9') {
1002 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
1003 }
1004
1005 ctx->status = ctx->status * 10 + ch - '0';
1006
1007 if (++ctx->status_count == 3) {
1008 state = sw_space_after_status;
1009 ctx->status_start = p - 2;
1010 }
1011
1012 break;
1013
1014 /* space or end of line */
1015 case sw_space_after_status:
1016 switch (ch) {
1017 case ' ':
1018 state = sw_status_text;
1019 break;
1020 case '.': /* IIS may send 403.1, 403.2, etc */
1021 state = sw_status_text;
1022 break;
1023 case CR:
1024 state = sw_almost_done;
1025 break;
1026 case LF:
1027 goto done;
1028 default:
1029 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
1030 }
1031 break;
1032
1033 /* any text until end of line */
1034 case sw_status_text:
1035 switch (ch) {
1036 case CR:
1037 state = sw_almost_done;
1038
1039 break;
1040 case LF:
1041 goto done;
1042 }
1043 break;
1044
1045 /* end of status line */
1046 case sw_almost_done:
1047 ctx->status_end = p - 1;
1048 switch (ch) {
1049 case LF:
1050 goto done;
1051 default:
1052 return NGX_HTTP_UWSGI_PARSE_NO_HEADER;
1053 }
1054 }
1055 }
1056
1057 u->buffer.pos = p;
1058 r->state = state;
1059
1060 return NGX_AGAIN;
1061
1062 done:
1063
1064 u->buffer.pos = p + 1;
1065
1066 if (ctx->status_end == NULL) {
1067 ctx->status_end = p;
1068 }
1069
1070 r->state = sw_start;
1071
1072 return NGX_OK;
1073 }
1074
1075
1076 static ngx_int_t
1077 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r) 867 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
1078 { 868 {
1079 ngx_int_t rc; 869 ngx_int_t rc;
1080 ngx_http_upstream_t *u; 870 ngx_http_upstream_t *u;
1081 ngx_http_uwsgi_ctx_t *ctx; 871 ngx_http_status_t *status;
1082 872
1083 ctx = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module); 873 status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
1084 874
1085 if (ctx == NULL) { 875 if (status == NULL) {
1086 return NGX_ERROR; 876 return NGX_ERROR;
1087 } 877 }
1088 878
1089 rc = ngx_http_uwsgi_parse_status_line(r, ctx); 879 u = r->upstream;
880
881 rc = ngx_http_parse_status_line(r, &u->buffer, status);
1090 882
1091 if (rc == NGX_AGAIN) { 883 if (rc == NGX_AGAIN) {
1092 return rc; 884 return rc;
1093 } 885 }
1094 886
1095 u = r->upstream; 887 if (rc == NGX_ERROR) {
1096
1097 if (rc == NGX_HTTP_UWSGI_PARSE_NO_HEADER) {
1098 r->http_version = NGX_HTTP_VERSION_9; 888 r->http_version = NGX_HTTP_VERSION_9;
1099 889
1100 u->process_header = ngx_http_uwsgi_process_header; 890 u->process_header = ngx_http_uwsgi_process_header;
1101 891
1102 return ngx_http_uwsgi_process_header(r); 892 return ngx_http_uwsgi_process_header(r);
1103 } 893 }
1104 894
1105 if (u->state) { 895 if (u->state) {
1106 u->state->status = ctx->status; 896 u->state->status = status->code;
1107 } 897 }
1108 898
1109 u->headers_in.status_n = ctx->status; 899 u->headers_in.status_n = status->code;
1110 900
1111 u->headers_in.status_line.len = ctx->status_end - ctx->status_start; 901 u->headers_in.status_line.len = status->end - status->start;
1112 u->headers_in.status_line.data = ngx_pnalloc(r->pool, 902 u->headers_in.status_line.data = ngx_pnalloc(r->pool,
1113 u->headers_in.status_line.len); 903 u->headers_in.status_line.len);
1114 if (u->headers_in.status_line.data == NULL) { 904 if (u->headers_in.status_line.data == NULL) {
1115 return NGX_ERROR; 905 return NGX_ERROR;
1116 } 906 }
1117 907
1118 ngx_memcpy(u->headers_in.status_line.data, ctx->status_start, 908 ngx_memcpy(u->headers_in.status_line.data, status->start,
1119 u->headers_in.status_line.len); 909 u->headers_in.status_line.len);
1120 910
1121 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 911 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1122 "http uwsgi status %ui \"%V\"", 912 "http uwsgi status %ui \"%V\"",
1123 u->headers_in.status_n, &u->headers_in.status_line); 913 u->headers_in.status_n, &u->headers_in.status_line);