wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, const char* method, int contentLength, SecBuffer* ntlmToken) { wStream* s; HttpRequest* request; char* base64NtlmToken = NULL; request = http_request_new(); if (ntlmToken) base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer); http_request_set_method(request, method); request->ContentLength = contentLength; http_request_set_uri(request, http->URI); if (base64NtlmToken) { http_request_set_auth_scheme(request, "NTLM"); http_request_set_auth_param(request, base64NtlmToken); } s = http_request_write(http, request); http_request_free(request); free(base64NtlmToken); return s; }
struct task* create_task(downloader *dler, const char *url, const char *fullname) { struct task *task = (struct task*)malloc(sizeof(struct task)); task->dler = dler; task->next = dler->tasks; dler->tasks = task; task->head_request = http_request_new(task); task->name = strdup(fullname); task->cur_size = 0; task->blocks = NULL; task->start_time = uv_now(dler->mainloop); task->consumed_time = 0; task->last_step_time = task->start_time; task->last_step_size = task->cur_size; if (strncmp(url, "http://", 7) == 0) { task->url = http_parse_url(url); } else { int len = strlen(url); char *new_url = (char*)calloc(1, len + 7 + 1); memcpy(new_url, "http://", 7); memcpy(new_url + 7, url, len); task->url = http_parse_url(new_url); free(new_url); } if (task->url == NULL) { printf("parse url failed\n"); exit(-1); } /* change host to a zero-terminated string for uv_getaddrinfo() */ uv_buf_t buf = http_url_get_field(task->url, UF_HOST); char *host = (char*)calloc(1, buf.len + 1); memcpy(host, buf.base, buf.len); struct addrinfo hints; hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = 0; uv_getaddrinfo_t *getaddrinfo = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t)); getaddrinfo->data = task; uv_getaddrinfo(dler->mainloop, getaddrinfo, on_resolved, host, NULL, &hints); free(host); return task; }
wStream* rdg_build_http_request(rdpRdg* rdg, char* method) { wStream* s; HttpRequest* request = NULL; SecBuffer* ntlmToken = NULL; char* base64NtlmToken = NULL; assert(method != NULL); request = http_request_new(); if (!request) return NULL; http_request_set_method(request, method); http_request_set_uri(request, rdg->http->URI); if (!request->Method || !request->URI) return NULL; if (rdg->ntlm) { ntlmToken = rdg->ntlm->outputBuffer; if (ntlmToken) base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer); if (base64NtlmToken) { http_request_set_auth_scheme(request, "NTLM"); http_request_set_auth_param(request, base64NtlmToken); free(base64NtlmToken); if (!request->AuthScheme || !request->AuthParam) return NULL; } } if (rdg->state == RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED) { http_request_set_transfer_encoding(request, "chunked"); } s = http_request_write(rdg->http, request); http_request_free(request); if (s) Stream_SealLength(s); return s; }
static void http_client_loop(struct http_thread_env *hte) { gchar *line = NULL; gsize nbyte = 0; HttpRequest *req = NULL; gint n; while ((n = getline(&line, &nbyte, hte->fp)) >= 0) { line[n] = '\0'; if (n && line[n - 1] == '\n') line[--n] = '\0'; if (n && line[n - 1] == '\r') line[--n] = '\0'; if (n) mbb_log_lvl(MBB_LOG_HTTP, "recv: %s", line); if (req == NULL) { if ((req = http_request_new(line)) == NULL) { push_http_msg(hte, MBB_MSG_INVALID_HEADER, line); break; } if (! parse_url(req->url, &hte->json, &hte->method)) { push_http_error_msg(hte, "invalid url %s", req->url); break; } } else if (n) { if (http_request_add_header(req, line) == FALSE) { mbb_log_lvl(MBB_LOG_HTTP, "invalid header"); push_http_msg(hte, MBB_MSG_INVALID_HEADER, line); break; } } else { if (req->method == HTTP_METHOD_POST) { if (process_http_body(hte, req) == FALSE) break; } process_http(hte, req); break; } } if (req != NULL) http_request_free(req); if (hte->root_tag != NULL) { xml_tag_free(hte->root_tag); hte->root_tag = NULL; } g_free(line); }
gboolean handle_accept( GIOChannel *sock, GIOCondition cond, void *dummy ) { GIOChannel *conn; http_request *req; int fd; fd = accept( g_io_channel_unix_get_fd(sock), NULL, NULL ); g_assert( fd != -1 ); conn = g_io_channel_unix_new( fd ); req = http_request_new( conn ); g_io_add_watch( conn, G_IO_IN, (GIOFunc) handle_read, req ); return TRUE; }
int main(int argc, char* argv[]){ size_t reqlen; HTTPRequest* req; const char* test_req; req = http_request_new(); test_req ="GET /index.html HTTP/1.1" CRLF\ "Content-Length: 1" CRLF\ "A: B" CRLF\ "C: D" CRLF\ CRLF\ "x"; reqlen = strlen(test_req) - 1; //http_request_parse_feed(req, test_req, strlen(test_req)); for(size_t i = 0; i < reqlen / 9; i+=9){ http_request_parse_feed(req,test_req,9); test_req+=9; } http_request_parse_feed(req,test_req,reqlen - reqlen / 9); /*while(*test_req!='\0'){ http_request_parse_feed(req,test_req,1); ++test_req; };*/ printf("method: %d\n, URI:\"%s\"\n, version: %d\n"\ "header1: \"%s\": \"%s\"\n"\ "header3: \"%s\": %s\n"\ "err : %d\n"\ "body: %s\n", req->method, req->URI, req->http_version, req->headers[0].name, req->headers[0].value, req->headers[2].name, req->headers[2].value, req->err, req->body); http_request_free(req); exit(EXIT_SUCCESS); }
wStream* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_length, TSG_CHANNEL channel) { wStream* s; HttpContext* http_context; HttpRequest* http_request; char* base64_ntlm_token = NULL; http_request = http_request_new(); if (ntlm_token) base64_ntlm_token = crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer); if (channel == TSG_CHANNEL_IN) { http_context = rpc->NtlmHttpIn->context; http_request_set_method(http_request, "RPC_IN_DATA"); } else if (channel == TSG_CHANNEL_OUT) { http_context = rpc->NtlmHttpOut->context; http_request_set_method(http_request, "RPC_OUT_DATA"); } else { return NULL; } http_request->ContentLength = content_length; http_request_set_uri(http_request, http_context->URI); if (base64_ntlm_token) { http_request_set_auth_scheme(http_request, "NTLM"); http_request_set_auth_param(http_request, base64_ntlm_token); } s = http_request_write(http_context, http_request); http_request_free(http_request); free(base64_ntlm_token); return s; }
http_request_t * http_request (const char *url, int port) { http_request_t *req = NULL; socket_t *sock = NULL; char *buf = NULL; char *data = NULL; size_t len = 0; size_t size = 0; int rc = 0; // init sock = sock_tcp_client_new(url, port); if (NULL == sock) { return NULL; } data = (char *) malloc(sizeof(char) * MAX_REQUEST_BUFFER_SIZE); if (NULL == data) { sock_free(sock); return NULL; } // connect rc = sock_connect(sock); if (rc < 0) { sock_free(sock); return NULL; } // read while ((len = sock_read(sock, buf, MAX_REQUEST_BUFFER_SIZE)) > 0) { printf("%s\n", buf); } req = http_request_new((http_socket_t *) sock, buf); if (NULL == req) { sock_free(sock); return NULL; } sock_close(sock); return NULL; }
static wStream* rdg_build_http_request(rdpRdg* rdg, const char* method, const char* transferEncoding) { wStream* s = NULL; HttpRequest* request = NULL; assert(method != NULL); request = http_request_new(); if (!request) return NULL; http_request_set_method(request, method); http_request_set_uri(request, rdg->http->URI); if (!request->Method || !request->URI) goto out; if (rdg->ntlm) { if (!rdg_set_ntlm_auth_header(rdg->ntlm, request)) goto out; } if (transferEncoding) { http_request_set_transfer_encoding(request, transferEncoding); } s = http_request_write(rdg->http, request); out: http_request_free(request); if (s) Stream_SealLength(s); return s; }
/* Extract http_pair_t objects from flow's packet_t chain */ int flow_extract_http(flow_t *f) { /* check if the flow is carrying HTTP again */ if( f->http == FALSE) return 1; /* * Find the actual FIN sequences. */ seq_t *seq = f->order->src; seq_t *src_fin_seq = NULL; seq_t *dst_fin_seq = NULL; int found = 0; while(seq != NULL) { /* Update flow's first byte time. * FBT of flow refers to the payload's FBT. */ if(seq->pkt != NULL && found == 0) { found = 1; f->fb_sec = seq->cap_sec; f->fb_usec = seq->cap_usec; } /*Search the FIN sequence in sequence queue.*/ if(seq->th_flags & TH_FIN == TH_FIN) { src_fin_seq = seq; break; } seq = seq->next; } seq = f->order->dst; while(seq != NULL) { /*Search the FIN sequence in sequence queue.*/ if(seq->th_flags & TH_FIN == TH_FIN) { dst_fin_seq = seq; break; } seq = seq->next; } /* * Set the client and server FIN sequences. */ seq_t *fin_seq = NULL; /* The actual FIN sequence. */ u_int8_t fin_dir = 0; /* fin_dir: * 0: Not set; * 1: src_fin_seq is used; * 2: dst_fin_seq is used; */ if (src_fin_seq != NULL && dst_fin_seq == NULL) { fin_seq = src_fin_seq; fin_dir = 1; } else if (src_fin_seq == NULL && dst_fin_seq != NULL) { fin_seq = dst_fin_seq; fin_dir = 2; } else if (src_fin_seq != NULL && dst_fin_seq != NULL) { fin_seq = src_fin_seq; fin_dir = 1; if(compare_sequence_time(src_fin_seq, dst_fin_seq) == 1) { fin_seq = dst_fin_seq; fin_dir = 2; } } else { fin_seq = NULL; fin_dir = 0; } /* * First step: find requests */ packet_t *pkt; request_t *req; response_t *rsp; int reqn = 0; // Number of requests. int rspn = 0; // Number of responses. http_pair_t *new_http = NULL; seq_t *seq_next = NULL; /* for temp */ seq_t *first_seq = NULL; /* Set seq and seq_next */ seq = f->order->src; if( seq != NULL) { seq_next = seq->next; } else { seq_next = NULL; /* NULL */ } if (fin_seq != NULL && seq != NULL) { /*A FIN packet exists.*/ while(compare_sequence_time(seq, fin_seq) < 0) { pkt = seq->pkt; if(pkt != NULL && pkt->http == HTTP_REQ) { /* When a new HTTP request is found, * create a HTTP pair object, then add the object to * flow's HTTP chain. */ reqn++; /* new HTTP pair object*/ new_http = http_new(); first_seq = seq; new_http->req_fb_sec = seq->cap_sec; new_http->req_fb_usec = seq->cap_usec; new_http->req_lb_sec = seq->cap_sec; new_http->req_lb_usec = seq->cap_usec; /* Add the object to flow's HTTP chain */ flow_add_http(f, new_http); /* new request object */ req = http_request_new(); /* Add the request object to the foregoing HTTP pair object */ http_add_request(new_http, req); /* parse and write values to foregoing request object */ http_parse_request(req, pkt->tcp_odata, pkt->tcp_odata + pkt->tcp_dl); } else { /*Omit the TCP handshake sequences.*/ if(new_http == NULL) { seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; continue; } } if( new_http != NULL ) { if( seq_next == NULL || seq_next == fin_seq || seq_next->pkt != NULL ||\ compare_sequence_time(seq_next, fin_seq) >= 0 ){ //assert(seq->nxt_seq != 0); if( seq->nxt_seq != 0){ new_http->req_total_len = seq->nxt_seq - first_seq->seq; new_http->req_body_len = 0; } /*Update flow's last byte time.*/ if ((seq->cap_sec > f->lb_sec) || (seq->cap_sec == f->lb_sec && seq->cap_usec > f->lb_usec)) { f->lb_sec = seq->cap_sec; f->lb_usec = seq->cap_usec; } } else { //assert(seq->seq <= seq_next->seq); } } /* Continue to next sequence.*/ seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; } } else { /* No FIN packet found.*/ while(seq != NULL) { pkt = seq->pkt; if(pkt != NULL && pkt->http == HTTP_REQ) { /* When a new HTTP request is found, * create a HTTP pair object, then add the object to * flow's HTTP chain. */ reqn++; /* new HTTP pair object*/ new_http = http_new(); first_seq = seq; new_http->req_fb_sec = seq->cap_sec; new_http->req_fb_usec = seq->cap_usec; new_http->req_lb_sec = seq->cap_sec; new_http->req_lb_usec = seq->cap_usec; /* Add the object to flow's HTTP chain */ flow_add_http(f, new_http); /* new request object */ req = http_request_new(); /* Add the request object to the foregoing HTTP pair object */ http_add_request(new_http, req); /* parse and write values to foregoing request object */ http_parse_request(req, pkt->tcp_odata, pkt->tcp_odata + pkt->tcp_dl); } else { if(new_http == NULL) { /*Omit the TCP handshake sequences.*/ seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; continue; } } if( new_http != NULL ) { if( seq_next == NULL || seq_next->pkt != NULL ) { //assert(seq->nxt_seq != 0); if( seq->nxt_seq != 0){ new_http->req_total_len = seq->nxt_seq - first_seq->seq; new_http->req_body_len = 0; } /*Update flow's last byte time.*/ if ((seq->cap_sec > f->lb_sec) || (seq->cap_sec == f->lb_sec && seq->cap_usec > f->lb_usec)) { f->lb_sec = seq->cap_sec; f->lb_usec = seq->cap_usec; } } else { //assert(seq->seq <= seq_next->seq); } } /*Continue to next sequence.*/ seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; } } /* If no responses found, we treat the flow as invalid and stop parsing */ if(reqn == 0) return 1; /* Second step: find responses */ http_pair_t *tmp = f->http_f; http_pair_t *found_http = NULL; seq = f->order->dst; if( seq != NULL) seq_next = seq->next; else seq_next = NULL; /* NULL */ if(fin_seq != NULL && seq != NULL){ /*There is FIN packet.*/ while(compare_sequence_time(seq, fin_seq) < 0) { pkt = seq->pkt; if ( pkt != NULL && pkt->http == HTTP_RSP) { /* * Similar to the request parsing, a new response is * added to the first pair without response */ rspn++; /* Try to find the first pair without response */ while(tmp != NULL) { if(tmp->response_header == NULL) break; tmp = tmp->next; } if(tmp == NULL) /* no response empty, then return */ return 1; else { /*Found!*/ found_http = tmp; first_seq = seq; found_http->rsp_fb_sec = seq->cap_sec; found_http->rsp_fb_usec = seq->cap_usec; rsp = http_response_new(); http_add_response(found_http, rsp); http_parse_response(rsp, pkt->tcp_odata, pkt->tcp_odata + pkt->tcp_dl); } } else { if(found_http == NULL) { seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; continue; } } if ( found_http != NULL ) { /*first_seq != NULL*/ if( seq_next == NULL || seq_next == fin_seq || seq_next->pkt != NULL ||\ compare_sequence_time(seq_next, fin_seq) >= 0 ) { found_http->rsp_lb_sec = seq->cap_sec; found_http->rsp_lb_usec = seq->cap_usec; //assert( seq->nxt_seq != 0 ); if(seq->nxt_seq != 0){ found_http->rsp_total_len = seq->nxt_seq - first_seq->seq; //printf("%d,%d", found_http->rsp_total_len, found_http->response_header->hdlen); //assert(found_http->rsp_total_len >= found_http->response_header->hdlen); found_http->rsp_body_len = found_http->rsp_total_len - found_http->response_header->hdlen; } /*Update flow's last byte time.*/ if ((seq->cap_sec > f->lb_sec) || (seq->cap_sec == f->lb_sec && seq->cap_usec > f->lb_usec)) { f->lb_sec = seq->cap_sec; f->lb_usec = seq->cap_usec; } } else { //assert(seq->seq <= seq_next->seq); } } seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; } } else { /*There is no FIN packet.*/ while(seq != NULL) { pkt = seq->pkt; if ( pkt != NULL && pkt->http == HTTP_RSP ) { /* * Similar to the request parsing, a new response is * added to the first pair without response */ rspn++; /* Try to find the first pair without response */ while(tmp != NULL) { if(tmp->response_header == NULL) break; tmp = tmp->next; } if(tmp == NULL) /* no response empty, then return */ return 1; else { /*Found!*/ found_http = tmp; first_seq = seq; found_http->rsp_fb_sec = seq->cap_sec; found_http->rsp_fb_usec = seq->cap_usec; rsp = http_response_new(); http_add_response(found_http, rsp); http_parse_response(rsp, pkt->tcp_odata, pkt->tcp_odata + pkt->tcp_dl); } } else { if(found_http == NULL) { seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; continue; } } if ( found_http != NULL ) { /*first_seq != NULL*/ if( seq_next == NULL || seq_next->pkt != NULL ) { found_http->rsp_lb_sec = seq->cap_sec; found_http->rsp_lb_usec = seq->cap_usec; //assert( seq->nxt_seq != 0 ); if(seq->nxt_seq != 0){ found_http->rsp_total_len = seq->nxt_seq - first_seq->seq; assert(found_http->rsp_total_len >= found_http->response_header->hdlen); found_http->rsp_body_len = found_http->rsp_total_len - found_http->response_header->hdlen; } /*Update flow's last byte time.*/ if ((seq->cap_sec > f->lb_sec) || (seq->cap_sec == f->lb_sec && seq->cap_usec > f->lb_usec)) { f->lb_sec = seq->cap_sec; f->lb_usec = seq->cap_usec; } } else { //assert(seq->seq <= seq_next->seq); } } seq = seq->next; if(seq != NULL) seq_next = seq->next; else break; } } return 0; }
int main(int argc, char **argv) { HttpRequest *req = NULL; int port = 8000; int c; char *didiwiki_home = NULL; int restore_WikiHelp = 0; struct in_addr address; /* default values */ debug = 0; //normal mode hostlogin = 0; //host will have to login nologin = 0; //users will have to login. dosendmail = 0; //don't send systematically email at each registration lgindex = 20; //print 20 files before to make a new index box /* by default bind server to "0.0.0.0" */ address.s_addr = inet_addr("0.0.0.0"); while (1) { static struct option long_options[] = { {"autologin", no_argument, 0, 'a'}, {"nologin", no_argument, 0, 'n'}, {"debug", no_argument, 0, 'd'}, {"version", no_argument, 0, 'v'}, {"listen", required_argument, 0, 'l'}, {"port", required_argument, 0, 'p'}, {"home", required_argument, 0, 'h'}, {"restore", no_argument, 0, 'r'}, {"sendmail", no_argument, 0, 's'}, {"index", required_argument, 0, 'i'}, {"help", no_argument, 0, 10 }, {0, 0, 0, 0} }; /* getopt_long stores the option index here */ int option_index = 0; c = getopt_long (argc, argv, "adl:p:h:i:rsv", long_options, &option_index); /* detect the end of the options */ if (c == -1) break; switch (c) { case 0: break; case 'i': //set index length lgindex = atoi(optarg); if (lgindex==0) lgindex=20; fprintf(stderr,"Index length = %i\n",lgindex); break; case 'a': //autologin for the localhost hostlogin = 1; fprintf(stderr,"Localhost is logged in.\n"); break; case 'n': //autologin any user nologin = 1; fprintf(stderr,"Any user registrered or not will be logged in.\n"); break; case 'd': debug = 1; break; case 'v': printf("CiWiki alias DidiWiki - version %s\n\n",VERSION); return 0; case 'p': //default port is 8000 port = atoi(optarg); break; case 'h': //default home directory is ~/.didiwiki didiwiki_home = optarg; break; case 'l': //listen a inet address if(inet_aton(optarg,&address) == 0) { fprintf(stderr, "didiwiki: invalid ip address \"%s\"\n", optarg); exit(1); } else address.s_addr = inet_addr(optarg); break; case 'r': //rewrite Wikihelp page restore_WikiHelp=1; break; case 's': dosendmail= 1; break; case 10: usage(); break; default: usage(); } } //end while wiki_init(didiwiki_home,restore_WikiHelp); if (debug) { req = http_request_new(); /* reads request from stdin */ } else { req = http_server(address, port); /* forks here */ } wiki_handle_http_request(req); return 0; }
/* ** Implement an HTTP server daemon. */ HttpRequest* http_server(struct in_addr address, int iPort) { int listener; /* The server socket */ int connection; /* A socket for each connection */ fd_set readfds; /* Set of file descriptors for select() */ socklen_t lenaddr; /* Length of the inaddr structure */ int child; /* PID of the child process */ int nchildren = 0; /* Number of child processes */ struct timeval delay; /* How long to wait inside select() */ struct sockaddr_in inaddr; /* The socket address */ int reuse = 1; int n = 0; char url_prefix[256]; int val; //not used /* catch SIGINT */ (void) signal(SIGINT, sigint); /* catch SIGTERM */ (void) signal(SIGTERM, sigterm); memset(&inaddr, 0, sizeof(inaddr)); inaddr.sin_family = AF_INET; inaddr.sin_addr.s_addr = address.s_addr; inaddr.sin_port = htons(iPort); listener = socket(AF_INET, SOCK_STREAM, 0); fprintf(stderr,"DidiWiki firing up ...\n"); if( listener < 0 ) { fprintf(stderr,"Can't create a socket\n"); exit(1); } #ifdef SO_REUSEADDR setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); #endif while (n < 10) { fprintf(stderr,"Attempting to bind to %s:%i .. ", inet_ntoa(address), iPort); inaddr.sin_port = htons(iPort + n); if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr)) < 0 ) { fprintf(stderr,"Failed! \n"); n++; continue; } fprintf(stderr,"Success! \n"); break; } if (n == 10) { fprintf(stderr,"Can't bind to any ports, giving up.\n"); exit(1); } fprintf(stderr,"DidiWiki Started. Please point your browser at %s:%i\n", inet_ntoa(address), iPort); /* log starting information */ openlog("didiwiki", 0, 0); syslog(LOG_LOCAL0|LOG_INFO, "started with PID %d", getpid()); /* Set DIDIWIKI_URL_PREFIX if not already set - rss uses it */ snprintf(url_prefix, 256, "%s:%i/", inet_ntoa(address), iPort+n); setenv("DIDIWIKI_URL_PREFIX", url_prefix , 0); listen(listener,10); /* Listen undefinitely */ while( 1 ) { if( nchildren>MAX_PARALLEL ) { /* Slow down if connections are arriving too fast */ sleep( nchildren-MAX_PARALLEL ); } delay.tv_sec = 60; delay.tv_usec = 0; FD_ZERO(&readfds); FD_SET( listener, &readfds); if( select( listener+1, &readfds, 0, 0, &delay) ) { lenaddr = sizeof(inaddr); connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr); if( connection>=0 ) { child = fork(); if( child!=0 ) { if( child>0 ) nchildren++; close(connection); } else { /* *child*, connect stdin/out to socket */ /* then return req object for caller to handle */ close(0); val = dup(connection); close(1); val = dup(connection); close(2); val = dup(connection); close(connection); return http_request_new(); } } } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ) nchildren--; } /* NOT REACHED */ exit(1); }