SWAT建模避坑指南:HRU划分中土地利用/土壤数据重分类的那些‘坑’与最佳实践
2026/6/5 4:39:38
ngx_http_auth_basic_handler 函数 定义在 ./nginx-1.24.0/src/http/modules/ngx_http_auth_basic_module.cstaticngx_int_tngx_http_auth_basic_handler(ngx_http_request_t*r){off_toffset;ssize_tn;ngx_fd_tfd;ngx_int_trc;ngx_err_terr;ngx_str_tpwd,realm,user_file;ngx_uint_ti,level,login,left,passwd;ngx_file_tfile;ngx_http_auth_basic_loc_conf_t*alcf;u_char buf[NGX_HTTP_AUTH_BUF_SIZE];enum{sw_login,sw_passwd,sw_skip}state;alcf=ngx_http_get_module_loc_conf(r,ngx_http_auth_basic_module);if(alcf->realm==NULL||alcf->user_file==NULL){returnNGX_DECLINED;}if(ngx_http_complex_value(r,alcf->realm,&realm)!=NGX_OK){returnNGX_ERROR;}if(realm.len==3&&ngx_strncmp(realm.data,"off",3)==0){returnNGX_DECLINED;}rc=ngx_http_auth_basic_user(r);if(rc==NGX_DECLINED){ngx_log_error(NGX_LOG_INFO,r->connection->log,0,"no user/password was provided for basic authentication");returnngx_http_auth_basic_set_realm(r,&realm);}if(rc==NGX_ERROR){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}if(ngx_http_complex_value(r,alcf->user_file,&user_file)!=NGX_OK){returnNGX_ERROR;}fd=ngx_open_file(user_file.data,NGX_FILE_RDONLY,NGX_FILE_OPEN,0);if(fd==NGX_INVALID_FILE){err=ngx_errno;if(err==NGX_ENOENT){level=NGX_LOG_ERR;rc=NGX_HTTP_FORBIDDEN;}else{level=NGX_LOG_CRIT;rc=NGX_HTTP_INTERNAL_SERVER_ERROR;}ngx_log_error(level,r->connection->log,err,ngx_open_file_n" \"%s\" failed",user_file.data);returnrc;}ngx_memzero(&file,sizeof(ngx_file_t));file.fd=fd;file.name=user_file;file.log=r->connection->log;state=sw_login;passwd=0;login=0;left=0;offset=0;for(;;){i=left;n=ngx_read_file(&file,buf+left,NGX_HTTP_AUTH_BUF_SIZE-left,offset);if(n==NGX_ERROR){rc=NGX_HTTP_INTERNAL_SERVER_ERROR;gotocleanup;}if(n==0){break;}for(i=left;i<left+n;i++){switch(state){casesw_login:if(login==0){if(buf[i]=='#'||buf[i]==CR){state=sw_skip;break;}if(buf[i]==LF){break;}}if(buf[i]!=r->headers_in.user.data[login]){state=sw_skip;break;}if(login==r->headers_in.user.len){state=sw_passwd;passwd=i+1;}login++;break;casesw_passwd:if(buf[i]==LF||buf[i]==CR||buf[i]==':'){buf[i]='\0';pwd.len=i-passwd;pwd.data=&buf[passwd];rc=ngx_http_auth_basic_crypt_handler(r,&pwd,&realm);gotocleanup;}break;casesw_skip:if(buf[i]==LF){state=sw_login;login=0;}break;}}if(state==sw_passwd){left=left+n-passwd;ngx_memmove(buf,&buf[passwd],left);passwd=0;}else{left=0;}offset+=n;}if(state==sw_passwd){pwd.len=i-passwd;pwd.data=ngx_pnalloc(r->pool,pwd.len+1);if(pwd.data==NULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}ngx_cpystrn(pwd.data,&buf[passwd],pwd.len+1);rc=ngx_http_auth_basic_crypt_handler(r,&pwd,&realm);gotocleanup;}ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"user \"%V\" was not found in \"%s\"",&r->headers_in.user,user_file.data);rc=ngx_http_auth_basic_set_realm(r,&realm);cleanup:if(ngx_close_file(file.fd)==NGX_FILE_ERROR){ngx_log_error(NGX_LOG_ALERT,r->connection->log,ngx_errno,ngx_close_file_n" \"%s\" failed",user_file.data);}ngx_explicit_memzero(buf,NGX_HTTP_AUTH_BUF_SIZE);returnrc;}ngx_http_auth_basic_handler 函数是 HTTP Basic 认证的处理函数。 它从请求中解析用户凭据,打开密码文件(如 htpasswd), 通过状态机逐行匹配用户名,并用加密算法验证密码, 最终返回认证通过、拒绝(401/403)或内部错误等状态。staticngx_int_tngx_http_auth_basic_handler(ngx_http_request_t*r)返回值 用于返回函数执行结果的状态码参数 ngx_http_request_t *r 指向当前 HTTP 请求上下文结构体1 局部变量 2 配置提取与校验 3 配置解析 4 Authorization 头解析与无凭证处理 5 打开文件 6 初始化 7 文件读取与解析循环 8 处理文件末尾无换行 9 用户未找到处理 10 清理1 局部变量{off_toffset;ssize_tn;ngx_fd_tfd;ngx_int_trc;ngx_err_terr;ngx_str_tpwd,realm,user_file;ngx_uint_ti,level,login,left,passwd;ngx_file_tfile;ngx_http_auth_basic_loc_conf_t*alcf;u_char buf[NGX_HTTP_AUTH_BUF_SIZE];enum{sw_login,sw_passwd,sw_skip}state;2 配置提取与校验alcf=ngx_http_get_module_loc_conf(r,ngx_http_auth_basic_module);if(alcf->realm==NULL||alcf->user_file==NULL){returnNGX_DECLINED;}3 配置解析if(ngx_http_complex_value(r,alcf->realm,&realm)!=NGX_OK){returnNGX_ERROR;}if(realm.len==3&&ngx_strncmp(realm.data,"off",3)==0){returnNGX_DECLINED;}4 Authorization 头解析与无凭证处理rc=ngx_http_auth_basic_user(r);if(rc==NGX_DECLINED){ngx_log_error(NGX_LOG_INFO,r->connection->log,0,"no user/password was provided for basic authentication");returnngx_http_auth_basic_set_realm(r,&realm);}if(rc==NGX_ERROR){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}5 打开文件if(ngx_http_complex_value(r,alcf->user_file,&user_file)!=NGX_OK){returnNGX_ERROR;}fd=ngx_open_file(user_file.data,NGX_FILE_RDONLY,NGX_FILE_OPEN,0);if(fd==NGX_INVALID_FILE){err=ngx_errno;if(err==NGX_ENOENT){level=NGX_LOG_ERR;rc=NGX_HTTP_FORBIDDEN;}else{level=NGX_LOG_CRIT;rc=NGX_HTTP_INTERNAL_SERVER_ERROR;}ngx_log_error(level,r->connection->log,err,ngx_open_file_n" \"%s\" failed",user_file.data);returnrc;}6 初始化ngx_memzero(&file,sizeof(ngx_file_t));file.fd=fd;file.name=user_file;file.log=r->connection->log;state=sw_login;passwd=0;login=0;left=0;offset=0;7 文件读取与解析循环for(;;){i=left;n=ngx_read_file(&file,buf+left,NGX_HTTP_AUTH_BUF_SIZE-left,offset);if(n==NGX_ERROR){rc=NGX_HTTP_INTERNAL_SERVER_ERROR;gotocleanup;}if(n==0){break;}for(i=left;i<left+n;i++){switch(state){casesw_login:if(login==0){if(buf[i]=='#'||buf[i]==CR){state=sw_skip;break;}if(buf[i]==LF){break;}}if(buf[i]!=r->headers_in.user.data[login]){state=sw_skip;break;}if(login==r->headers_in.user.len){state=sw_passwd;passwd=i+1;}login++;break;casesw_passwd:if(buf[i]==LF||buf[i]==CR||buf[i]==':'){buf[i]='\0';pwd.len=i-passwd;pwd.data=&buf[passwd];rc=ngx_http_auth_basic_crypt_handler(r,&pwd,&realm);gotocleanup;}break;casesw_skip:if(buf[i]==LF){state=sw_login;login=0;}break;}}if(state==sw_passwd){left=left+n-passwd;ngx_memmove(buf,&buf[passwd],left);passwd=0;}else{left=0;}offset+=n;}8 处理文件末尾无换行if(state==sw_passwd){pwd.len=i-passwd;pwd.data=ngx_pnalloc(r->pool,pwd.len+1);if(pwd.data==NULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}ngx_cpystrn(pwd.data,&buf[passwd],pwd.len+1);rc=ngx_http_auth_basic_crypt_handler(r,&pwd,&realm);gotocleanup;}9 用户未找到处理ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"user \"%V\" was not found in \"%s\"",&r->headers_in.user,user_file.data);rc=ngx_http_auth_basic_set_realm(r,&realm);10 清理cleanup:if(ngx_close_file(file.fd)==NGX_FILE_ERROR){ngx_log_error(NGX_LOG_ALERT,r->connection->log,ngx_errno,ngx_close_file_n" \"%s\" failed",user_file.data);}ngx_explicit_memzero(buf,NGX_HTTP_AUTH_BUF_SIZE);returnrc;}