http_client::~http_client(void) { if (req_) http_req_free(req_); else if (hdr_req_) http_hdr_req_free(hdr_req_); }
void client_event_free(client_event * e) { if (e->request_info != NULL) { http_req_free(e->request_info); } if (e->response_info != NULL) { http_resp_free(e->response_info); } free(e); }
void http_client::reset(void) { if (req_) { http_req_free(req_); req_ = NULL; } else if (hdr_req_) http_hdr_req_free(hdr_req_); hdr_req_ = http_hdr_req_new(); json_.reset(); }
void http_client::reset(void) { if (buf_) buf_->clear(); if (res_) { // 说明是长连接的第二次请求,所以需要把上次请求的 // 响应头对象及响应体对象释放 acl_assert(hdr_res_); http_res_free(res_); hdr_res_ = NULL; res_ = NULL; } else if (hdr_res_) { // 说明是长连接的第二次请求,因为有可能第一次请求 // 只有响应头,所以仅需要释放上次的响应头对象 http_hdr_res_free(hdr_res_); hdr_res_ = NULL; } if (req_) { acl_assert(hdr_req_); http_req_free(req_); hdr_req_ = NULL; req_ = NULL; } else if (hdr_req_) { http_hdr_req_free(hdr_req_); hdr_req_ = NULL; } if (zstream_) { delete zstream_; zstream_ = NULL; } last_ret_ = -1; body_finish_ = false; chunked_transfer_ = false; }
int main(int argc, char **argv) { int i, s, done, print_body, gssapi_done, gssapi_started, optidx = 0; const char *host, *page; struct http_req req; char *headers[99]; /* XXX */ int num_headers; krb5_storage *sp; gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; gss_name_t server = GSS_C_NO_NAME; gss_OID mech_oid, cred_mech_oid; OM_uint32 flags; OM_uint32 maj_stat, min_stat; setprogname(argv[0]); if(getarg(http_args, num_http_args, argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; mech_oid = select_mech(mech); if (cred_mech_str) cred_mech_oid = select_mech(cred_mech_str); else cred_mech_oid = mech_oid; if (argc != 1 && argc != 2) errx(1, "usage: %s host [page]", getprogname()); host = argv[0]; if (argc == 2) page = argv[1]; else page = "/"; flags = 0; if (delegate_flag) flags |= GSS_C_DELEG_FLAG; if (policy_flag) flags |= GSS_C_DELEG_POLICY_FLAG; if (mutual_flag) flags |= GSS_C_MUTUAL_FLAG; done = 0; num_headers = 0; gssapi_done = 0; gssapi_started = 0; if (client_str) { gss_buffer_desc name_buffer; gss_name_t name; gss_OID_set mechset = GSS_C_NO_OID_SET; name_buffer.value = client_str; name_buffer.length = strlen(client_str); maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_USER_NAME, &name); if (maj_stat) errx(1, "failed to import name"); if (cred_mech_oid) { gss_create_empty_oid_set(&min_stat, &mechset); gss_add_oid_set_member(&min_stat, cred_mech_oid, &mechset); } maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE, mechset, GSS_C_INITIATE, &client_cred, NULL, NULL); gss_release_name(&min_stat, &name); gss_release_oid_set(&min_stat, &mechset); if (maj_stat) errx(1, "failed to find cred of name %s", client_str); } { gss_buffer_desc name_token; char *name; asprintf(&name, "%s@%s", gss_service, host); name_token.length = strlen(name); name_token.value = name; maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &server); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_inport_name: %s", name); free(name); } s = do_connect(host, port_str); if (s < 0) errx(1, "connection failed"); sp = krb5_storage_from_fd(s); if (sp == NULL) errx(1, "krb5_storage_from_fd"); do { print_body = 0; http_query(sp, host, page, headers, num_headers, &req); for (i = 0 ; i < num_headers; i++) free(headers[i]); num_headers = 0; if (strstr(req.response, " 200 ") != NULL) { print_body = 1; done = 1; } else if (strstr(req.response, " 401 ") != NULL) { if (http_find_header(&req, "WWW-Authenticate:") == NULL) errx(1, "Got %s but missed `WWW-Authenticate'", req.response); } if (!gssapi_done) { const char *h = http_find_header(&req, "WWW-Authenticate:"); if (h == NULL) errx(1, "Got %s but missed `WWW-Authenticate'", req.response); if (strncasecmp(h, "Negotiate", 9) == 0) { gss_buffer_desc input_token, output_token; if (verbose_flag) printf("Negotiate found\n"); i = 9; while(h[i] && isspace((unsigned char)h[i])) i++; if (h[i] != '\0') { size_t len = strlen(&h[i]); int slen; if (len == 0) errx(1, "invalid Negotiate token"); input_token.value = emalloc(len); slen = base64_decode(&h[i], input_token.value); if (slen < 0) errx(1, "invalid base64 Negotiate token %s", &h[i]); input_token.length = slen; } else { if (gssapi_started) errx(1, "Negotiate already started"); gssapi_started = 1; input_token.length = 0; input_token.value = NULL; } if (strstr(req.response, " 200 ") != NULL) sleep(1); maj_stat = gss_init_sec_context(&min_stat, client_cred, &context_hdl, server, mech_oid, flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &input_token, NULL, &output_token, NULL, NULL); if (maj_stat == GSS_S_CONTINUE_NEEDED) { } else if (maj_stat == GSS_S_COMPLETE) { gss_name_t targ_name, src_name; gss_buffer_desc name_buffer; gss_OID mech_type; gssapi_done = 1; maj_stat = gss_inquire_context(&min_stat, context_hdl, &src_name, &targ_name, NULL, &mech_type, NULL, NULL, NULL); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_inquire_context"); printf("Negotiate done: %s\n", mech); maj_stat = gss_display_name(&min_stat, src_name, &name_buffer, NULL); if (GSS_ERROR(maj_stat)) gss_print_errors(min_stat); else printf("Source: %.*s\n", (int)name_buffer.length, (char *)name_buffer.value); gss_release_buffer(&min_stat, &name_buffer); maj_stat = gss_display_name(&min_stat, targ_name, &name_buffer, NULL); if (GSS_ERROR(maj_stat)) gss_print_errors(min_stat); else printf("Target: %.*s\n", (int)name_buffer.length, (char *)name_buffer.value); gss_release_name(&min_stat, &targ_name); gss_release_buffer(&min_stat, &name_buffer); } else { gss_err (1, min_stat, "gss_init_sec_context"); } if (output_token.length) { char *neg_token; base64_encode(output_token.value, (int)output_token.length, &neg_token); asprintf(&headers[0], "Authorization: Negotiate %s", neg_token); num_headers = 1; free(neg_token); gss_release_buffer(&min_stat, &output_token); } if (input_token.length) free(input_token.value); } else done = 1; } else done = 1; if (print_body || verbose_flag) printf("%.*s\n", (int)req.body_size, (char *)req.body); http_req_free(&req); } while (!done); if (gssapi_done == 0) errx(1, "gssapi not done but http dance done"); krb5_storage_free(sp); close(s); return 0; }
static void thread_run(void *arg) { CONN *conn = (CONN*) arg; ACL_VSTREAM *client = conn->stream; const char *reply_200 = "HTTP/1.1 200 OK\r\n" "Server: nginx/0.6.32\r\n" "Date: Tue, 29 Dec 2009 02:18:25 GMT\r\n" "Content-Type: text/html\r\n" "Content-Length: 43\r\n" "Last-Modified: Mon, 16 Nov 2009 02:18:14 GMT\r\n" "Connection: keep-alive\r\n" "Accept-Ranges: bytes\r\n\r\n" "<html>\n" "<body>\n" "hello world!\n" "</body>\n" "</html>\n"; int ret, keep_alive; char buf[4096]; while (0) { ret = read(ACL_VSTREAM_SOCK(client), buf, sizeof(buf)); if (ret == ACL_VSTREAM_EOF) break; ret = acl_vstream_writen(client, reply_200, strlen(reply_200)); if (ret == ACL_VSTREAM_EOF) break; } while (0) { ret = acl_vstream_read(client, buf, sizeof(buf)); if (ret == ACL_VSTREAM_EOF) break; ret = acl_vstream_writen(client, reply_200, strlen(reply_200)); if (ret == ACL_VSTREAM_EOF) break; } while (0) { /* HTTP_REQ *req; */ HTTP_HDR_REQ *hdr_req = http_hdr_req_new(); ret = http_hdr_req_get_sync(hdr_req, client, 300); if (ret < 0) { http_hdr_req_free(hdr_req); break; } if (http_hdr_req_parse(hdr_req) < 0) { http_hdr_req_free(hdr_req); printf("parse error\n"); break; } /* keep_alive = hdr_req->hdr.keep_alive; if (hdr_req->hdr.content_length > 0) { req = http_req_new(hdr_req); ret = (int) http_req_body_get_sync(req, client, buf, sizeof(buf)); if (ret < 0) { http_req_free(req); break; } http_req_free(req); } else { http_hdr_req_free(hdr_req); } */ http_hdr_req_free(hdr_req); ret = acl_vstream_writen(client, reply_200, strlen(reply_200)); if (ret == ACL_VSTREAM_EOF) { break; } /* if (!keep_alive) break; */ } while (1) { HTTP_REQ *req; HTTP_HDR_REQ *hdr_req = http_hdr_req_new(); ret = http_hdr_req_get_sync(hdr_req, client, 0); if (ret < 0) { http_hdr_req_free(hdr_req); break; } if (http_hdr_req_parse(hdr_req) < 0) { http_hdr_req_free(hdr_req); printf("parse error\n"); break; } keep_alive = hdr_req->hdr.keep_alive; if (hdr_req->hdr.content_length > 0) { req = http_req_new(hdr_req); ret = (int) http_req_body_get_sync(req, client, buf, sizeof(buf)); if (ret < 0) { http_req_free(req); break; } http_req_free(req); } else { http_hdr_req_free(hdr_req); } ret = acl_vstream_writen(client, reply_200, strlen(reply_200)); if (ret == ACL_VSTREAM_EOF) { break; } if (!keep_alive) break; } acl_vstream_close(client); acl_myfree(conn); printf("thread(%ld) exit\n", (long) acl_pthread_self()); }
int main(int argc, char **argv) { struct http_req req; const char *host, *page; int i, done, print_body, gssapi_done, gssapi_started; char *headers[10]; /* XXX */ int num_headers; gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; gss_name_t server = GSS_C_NO_NAME; int optind = 0; gss_OID mech_oid; OM_uint32 flags; setprogname(argv[0]); if(getarg(http_args, num_http_args, argc, argv, &optind)) usage(1); if (help_flag) usage (0); if(version_flag) { print_version(NULL); exit(0); } argc -= optind; argv += optind; mech_oid = select_mech(mech); if (argc != 1 && argc != 2) errx(1, "usage: %s host [page]", getprogname()); host = argv[0]; if (argc == 2) page = argv[1]; else page = "/"; flags = 0; if (delegate_flag) flags |= GSS_C_DELEG_FLAG; if (mutual_flag) flags |= GSS_C_MUTUAL_FLAG; done = 0; num_headers = 0; gssapi_done = 1; gssapi_started = 0; do { print_body = 0; http_query(host, page, headers, num_headers, &req); for (i = 0 ; i < num_headers; i++) free(headers[i]); num_headers = 0; if (strstr(req.response, " 200 ") != NULL) { print_body = 1; done = 1; } else if (strstr(req.response, " 401 ") != NULL) { if (http_find_header(&req, "WWW-Authenticate:") == NULL) errx(1, "Got %s but missed `WWW-Authenticate'", req.response); gssapi_done = 0; } if (!gssapi_done) { const char *h = http_find_header(&req, "WWW-Authenticate:"); if (h == NULL) errx(1, "Got %s but missed `WWW-Authenticate'", req.response); if (strncasecmp(h, "Negotiate", 9) == 0) { OM_uint32 maj_stat, min_stat; gss_buffer_desc input_token, output_token; if (verbose_flag) printf("Negotiate found\n"); if (server == GSS_C_NO_NAME) { char *name; asprintf(&name, "%s@%s", gss_service, host); input_token.length = strlen(name); input_token.value = name; maj_stat = gss_import_name(&min_stat, &input_token, GSS_C_NT_HOSTBASED_SERVICE, &server); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_inport_name"); free(name); input_token.length = 0; input_token.value = NULL; } i = 9; while(h[i] && isspace((unsigned char)h[i])) i++; if (h[i] != '\0') { int len = strlen(&h[i]); if (len == 0) errx(1, "invalid Negotiate token"); input_token.value = emalloc(len); len = base64_decode(&h[i], input_token.value); if (len < 0) errx(1, "invalid base64 Negotiate token %s", &h[i]); input_token.length = len; } else { if (gssapi_started) errx(1, "Negotiate already started"); gssapi_started = 1; input_token.length = 0; input_token.value = NULL; } maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &context_hdl, server, mech_oid, flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &input_token, NULL, &output_token, NULL, NULL); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_init_sec_context"); else if (maj_stat & GSS_S_CONTINUE_NEEDED) gssapi_done = 0; else { gss_name_t targ_name, src_name; gss_buffer_desc name_buffer; gss_OID mech_type; gssapi_done = 1; printf("Negotiate done: %s\n", mech); maj_stat = gss_inquire_context(&min_stat, context_hdl, &src_name, &targ_name, NULL, &mech_type, NULL, NULL, NULL); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_inquire_context"); maj_stat = gss_display_name(&min_stat, src_name, &name_buffer, NULL); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_display_name"); printf("Source: %.*s\n", (int)name_buffer.length, (char *)name_buffer.value); gss_release_buffer(&min_stat, &name_buffer); maj_stat = gss_display_name(&min_stat, targ_name, &name_buffer, NULL); if (GSS_ERROR(maj_stat)) gss_err (1, min_stat, "gss_display_name"); printf("Target: %.*s\n", (int)name_buffer.length, (char *)name_buffer.value); gss_release_name(&min_stat, &targ_name); gss_release_buffer(&min_stat, &name_buffer); } if (output_token.length) { char *neg_token; base64_encode(output_token.value, output_token.length, &neg_token); asprintf(&headers[0], "Authorization: Negotiate %s", neg_token); num_headers = 1; free(neg_token); gss_release_buffer(&min_stat, &output_token); } if (input_token.length) free(input_token.value); } else done = 1; } else done = 1; if (verbose_flag) { printf("%s\n\n", req.response); for (i = 0; i < req.num_headers; i++) printf("%s\n", req.headers[i]); printf("\n"); } if (print_body || verbose_flag) printf("%.*s\n", (int)req.body_size, (char *)req.body); http_req_free(&req); } while (!done); if (gssapi_done == 0) errx(1, "gssapi not done but http dance done"); return 0; }