static CamReturn send_application_info_enquiry (CamApplicationInfo * info, CamSLSession * session) { GST_DEBUG ("sending application info enquiry"); return send_simple (info, session, TAG_APPLICATION_INFO_ENQUIRY); }
static CamReturn send_profile_enquiry (CamResourceManager * mgr, CamSLSession * session) { GST_DEBUG ("sending profile enquiry"); return send_simple (mgr, session, TAG_PROFILE_ENQUIRY); }
static CamReturn send_profile_change (CamResourceManager * mgr, CamSLSession * session) { GST_DEBUG ("sending profile change"); return send_simple (mgr, session, TAG_PROFILE_CHANGE); }
void Client::decline() { send_simple(A_DECLINE); }
void Client::confirm() { send_simple(A_CONFIRM); }
void Client::roll_dice() { send_simple(A_ROLL_DICE); }
void Client::start_game() { send_simple(A_START_GAME); }
void Client::request_update() { send_simple(A_SEND_UPDATE); }
/* * Process a request from our HTTP client. The main server loop calls this * when the socket has data ready to read. */ int TadsHttpServerThread::process_request() { StringRef *hdrs = new StringRef(1024); TadsHttpRequestHeader *hdr_list = 0, *hdr_tail = 0; TadsHttpRequest *req = 0; char *verb; size_t verb_len; char *resource_name; size_t res_name_len; int ok = FALSE; long ofs; char *p, *hbody; StringRef *body = 0; int overflow = FALSE; long hbodylen; const char *hcl, *hte; /* content-length, transfer-encoding */ /* * Read the header. We read data into our buffer until we find a * double CR-LF sequence, indicating the end of the header. */ if ((ofs = read_to_nl(hdrs, 0, 0, 4)) < 0) goto done; /* the body, if any, starts after the double line break */ hbody = hdrs->get() + ofs; hbodylen = hdrs->getlen() - ofs; /* truncate the headers to the CR-LF-CR-LF sequence */ hdrs->truncate(ofs - 2); /* * Parse the main verb in the header - get the method and the resource * ID. The format is: * *. <space>* VERB <space>+ RESOURCE <space>+ HTTP-VERSION <CRLF> */ p = hdrs->get(); parse_tok(p, verb, verb_len); parse_tok(p, resource_name, res_name_len); /* now parse the remaining headers */ TadsHttpRequestHeader::parse_headers(hdr_list, hdr_tail, FALSE, hdrs, 0); /* * Check to see if there's a message body. There is if there's a * content-length or transfer-encoding header. */ hcl = hdr_list->find("content-length"); hte = hdr_list->find("transfer-encoding"); if (hcl != 0 || hte != 0) { /* * There's a content body. If there's a content-length field, * pre-allocate a chunk of memory, then read the number of bytes * indicated. If it's a chunked transfer, read it in pieces. */ if (hcl != 0) { /* get the length */ long hclval = atol(hcl); /* if it's non-zero, read the content */ if (hclval != 0) { /* if this exceeds the size limit, abort */ if (upload_limit != 0 && hclval > upload_limit) { /* set the overflow flag, discard the input, and abort */ overflow = TRUE; read(0, 0, hclval, 5000); goto done_with_upload; } /* allocate the buffer; it's initially empty */ body = new StringRef(hclval); /* copy any portion of the body we've already read */ if (hbodylen != 0) { /* limit this to the declared size */ if (hbodylen > hclval) hbodylen = hclval; /* copy the data */ body->append(hbody, hbodylen); /* deduct the remaining size */ hclval -= hbodylen; } /* read the body */ if (hclval != 0 && read(body->getend(), hclval, hclval, 5000) < 0) { send_simple(S_http_400, "text/html", "Error receiving request message body"); goto done; } /* set the body length */ body->addlen(hclval); } } else if (stricmp(hte, "chunked") == 0) { /* set up a string buffer for the content */ const long initlen = 32000; body = new StringRef(hbodylen > initlen ? hbodylen : initlen); /* if we've already read some body text, copy it to the buffer */ if (hbodylen != 0) body->append(hbody, hbodylen); /* keep going until we reach the end marker */ for (ofs = 0 ; ; ) { /* read to the first newline */ long nlofs = read_to_nl(body, ofs, 0, 2); if (nlofs < 0) goto done; /* get the chunk length */ long chunklen = strtol(body->get() + ofs, 0, 16); /* * We're done with the chunk length. Move any read-ahead * content down in memory so that it directly abuts the * preceding chunk, so that when we're done we'll have the * content assembled into one contiguous piece. */ long ralen = body->getlen() - nlofs; if (ralen > 0) memmove(body->get() + ofs, body->get() + nlofs, body->getlen() - nlofs); /* stop at the end of the read-ahead portion */ body->truncate(ofs + ralen); /* if the chunk length is zero, we're done */ if (chunklen == 0) break; /* check if this would overflow our upload size limit */ if (upload_limit != 0 && !overflow && body->getlen() + chunklen > upload_limit) { /* flag the overflow, but keep reading the content */ overflow = TRUE; } /* * figure the remaining read size for this chunk, after any * read-ahead portion */ long chunkrem = chunklen - ralen; /* * if we've already overflowed, read and discard the chunk; * otherwise read it into our buffer */ if (chunkrem + 2 <= 0) { /* * We've already read ahead by enough to cover the next * chunk and the newline at the end. Go in and delete * the newline (or as much of it as exists). Start by * getting the offset of the newline: it's just after * the current chunk, which starts at 'ofs' and runs * for 'chunklen'. */ nlofs = ofs + chunklen; /* * if we haven't yet read the full newline sequence, do * so now */ if (ralen - chunklen < 2) { long nllen = 2 - (ralen - chunklen); body->ensure(nllen); if (read(body->getend(), nllen, nllen, 30000) < 0) { send_simple(S_http_400, "text/html", "Error receiving request message chunk"); goto done; } } /* * if there's anything after the newline, move it down * to overwrite the newline */ if (ralen - chunklen > 2) { /* move the bytes */ memmove(body->get() + nlofs, body->get() + nlofs + 2, ralen - chunklen - 2); /* adjust the size for the closed gap */ body->truncate(body->getlen() - 2); } /* resume from after the newline */ ofs = nlofs; } else if (overflow) { /* overflow - discard the chunk size (plus the CR-LF) */ if (read(0, 0, chunkrem+2, 30000) < 0) goto done; /* clear the buffer */ body->truncate(0); ofs = 0; } else { /* ensure the buffer is big enough */ body->ensure(chunkrem + 2); /* read the chunk, plus the CR-LF that follows */ if (read(body->getend(), chunkrem + 2, chunkrem + 2, 30000) < 0) { send_simple(S_http_400, "text/html", "Error receiving request message chunk"); goto done; } /* count the amount we just read in the buffer length */ body->addlen(chunkrem + 2); /* verify that the last two bytes are indeed CR-LF */ if (memcmp(body->getend() - 2, "\r\n", 2) != 0) { send_simple(S_http_400, "text/html", "Error in request message chunk"); goto done; } /* * move past the chunk for the next read, minus the * CR-LF that follows the chunk - that isn't part of * the data, but just part of the protocol */ ofs = body->getlen() - 2; body->truncate(ofs); } } /* * Read to the closing blank line. We've just passed one * newline, following the '0' end length marker, so we're in * state 2. We could have either another newline following, or * "trailers" (more headers, following the content body). */ long nlofs = read_to_nl(body, ofs, 2, 4); if (nlofs < 0) goto done; /* * if we have more than just the closing blank line, we have * trailers - append them to the headers */ if (nlofs > ofs + 2) { TadsHttpRequestHeader::parse_headers( hdr_list, hdr_tail, TRUE, body, ofs); } /* * the trailers (if any) and closing newline aren't part of the * content - clip them out of the body */ body->truncate(ofs); } else { /* * Other combinations of these headers are illegal. Send an * error and abort. */ send_simple(S_http_400, "text/html", "<html><title>Bad Request</title>" "<h1>Bad Request</h1>" "This server does not accept the specified " "transfer-encoding."); goto done; } done_with_upload: /* done with the upload - check for overflow */ if (overflow) { /* release the body, if present */ if (body != 0) { body->release_ref(); body = 0; } } } /* create a message object for the request */ req = new TadsHttpRequest( this, verb, verb_len, hdrs, hdr_list, body, overflow, resource_name, res_name_len, listener->get_shutdown_evt()); /* we've handed over the header list to the request */ hdr_list = 0; /* send it to the main thread, and wait for the reply */ if (queue->send(req, OS_FOREVER)) { /* * success - the server will already have sent the reply, so we're * done */ } else if (queue->is_quitting()) { /* failed due to server shutdown */ send_simple(S_http_503, "text/html", S_http_503_quitting_body); } else { /* 'send' failed - return an internal server error */ send_simple(S_http_500, "text/html", S_http_500_body); } /* we're done with the request */ req->release_ref(); /* success */ ok = TRUE; done: /* release the message body buffer */ if (body != 0) body->release_ref(); /* release the header buffer */ hdrs->release_ref(); /* delete the header list */ if (hdr_list != 0) delete hdr_list; /* return the success/failure indication */ return ok; }