error_t httpWriteStream(HttpConnection *connection, const void *data, size_t length) { error_t error; uint_t n; //Use chunked encoding transfer? if(connection->response.chunkedEncoding) { //Any data to send? if(length > 0) { char_t s[8]; //The chunk-size field is a string of hex digits //indicating the size of the chunk n = sprintf(s, "%X\r\n", length); //Send the chunk-size field error = httpSend(connection, s, n, HTTP_FLAG_DELAY); //Failed to send data? if(error) return error; //Send the chunk-data error = httpSend(connection, data, length, HTTP_FLAG_DELAY); //Failed to send data? if(error) return error; //Terminate the chunk-data by CRLF error = httpSend(connection, "\r\n", 2, HTTP_FLAG_DELAY); } else { //Any chunk whose size is zero may terminate the data //transfer and must be discarded error = NO_ERROR; } } //Default encoding? else { //The length of the body shall not exceed the value //specified in the Content-Length field length = MIN(length, connection->response.byteCount); //Send user data error = httpSend(connection, data, length, HTTP_FLAG_DELAY); //Decrement the count of remaining bytes to be transferred connection->response.byteCount -= length; } //Return status code return error; }
/* function send(...content): Number */ static EjsNumber *ws_send(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv) { EjsArray *args; EjsByteArray *ba; EjsAny *arg; ssize nbytes; int i; args = (EjsArray*) argv[0]; if (ws->conn->state < HTTP_STATE_PARSED && !waitForHttpState(ws, HTTP_STATE_PARSED, -1, 1)) { return ESV(null); } nbytes = 0; for (i = 0; i < args->length; i++) { if ((arg = ejsGetProperty(ejs, args, i)) != 0) { if (ejsIs(ejs, arg, ByteArray)) { ba = (EjsByteArray*) arg; nbytes = ejsGetByteArrayAvailableData(ba); nbytes = httpSendBlock(ws->conn, WS_MSG_BINARY, (cchar*) &ba->value[ba->readPosition], nbytes, HTTP_BLOCK); } else { nbytes = httpSend(ws->conn, ejsToMulti(ejs, arg)); } if (nbytes < 0) { return ESV(null); } } } return ejsCreateNumber(ejs, (MprNumber) nbytes); }
void uploadctr(char *filename, char *ip) { int ret, size, p, n, k, i, j; FILE *fd; SOCKET sd; unsigned char *buf; fd = fopen(filename, "rb"); if ( fd == NULL ) { printf("file %s not found\n", filename); return; } #ifndef __WIN32__ if (!is_regular_file(filename)) { printf("file %s is not a regular file\n", filename); fclose(fd); return; } #endif fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); buf = malloc(size); if ( buf == NULL ) { printf("Not enough memory!\n"); fclose(fd); return; } fread(buf, size, 1, fd); // gah no validation, M4 will verify some... fclose(fd); ret = httpConnect(ip); if ( ret >= 0 ) { sd = ret; // connect socket if ( httpSend(sd, "/CARTIMG.BIN", buf, size, "upfile", "/upload.html", ip) >= 0 ) ret = httpResponse(sd); httpClose(sd); if ( ret == 200 ) printf("Upload OK!\r\n"); else printf("Upload error code. %i\r\n", ret); } else printf("Connect to %s failed\n", ip); free(buf); }
error_t httpCloseStream(HttpConnection *connection) { error_t error; //Use chunked encoding transfer? if(connection->response.chunkedEncoding) { //The chunked encoding is ended by any chunk whose size is zero error = httpSend(connection, "0\r\n\r\n", 5, HTTP_FLAG_NO_DELAY); } else { //Flush the send buffer error = httpSend(connection, "", 0, HTTP_FLAG_NO_DELAY); } //Return status code return error; }
void AutoConnection::connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) { address = QUrl(((flags & MTPDdcOption::Flag::f_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString())); connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); _addrHttp = addr; _portHttp = port; _flagsHttp = flags; mtpBuffer buffer(preparePQFake(httpNonce)); DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4")); httpSend(buffer); }
static void echo_callback(HttpConn *conn, int event, int arg) { HttpPacket *packet; HttpWebSocket *ws; cchar *data; traceEvent(conn, event, arg); if (event == HTTP_EVENT_READABLE) { packet = httpGetPacket(conn->readq); assure(packet); /* Ignore precedding packets and just trace the last */ if (packet->last) { ws = conn->rx->webSocket; httpSend(conn, "{type: %d, last: %d, length: %d, data: \"%s\"}\n", packet->type, packet->last, ws->messageLength, snclone(mprGetBufStart(packet->content), 10)); } } }
error_t httpWriteHeader(HttpConnection *connection) { error_t error; uint_t i; char_t *p; //HTTP version 0.9? if(connection->response.version == HTTP_VERSION_0_9) { //Enforce default parameters connection->response.keepAlive = FALSE; connection->response.chunkedEncoding = FALSE; //The size of the response body is not limited connection->response.byteCount = UINT_MAX; //We are done since HTTP 0.9 does not support Full-Response format return NO_ERROR; } //When generating dynamic web pages with HTTP 1.0, the only way to //signal the end of the body is to close the connection if(connection->response.version == HTTP_VERSION_1_0 && connection->response.chunkedEncoding) { //Make the connection non persistent connection->response.keepAlive = FALSE; connection->response.chunkedEncoding = FALSE; //The size of the response body is not limited connection->response.byteCount = UINT_MAX; } else { //Limit the size of the response body connection->response.byteCount = connection->response.contentLength; } //Point to the beginning of the buffer p = connection->buffer; //The first line of a response message is the Status-Line, consisting //of the protocol version followed by a numeric status code and its //associated textual phrase p += sprintf(p, "HTTP/%u.%u %u ", MSB(connection->response.version), LSB(connection->response.version), connection->response.statusCode); //Retrieve the Reason-Phrase that corresponds to the Status-Code for(i = 0; i < arraysize(statusCodeList); i++) { //Check the status code if(statusCodeList[i].value == connection->response.statusCode) { //Append the textual phrase to the Status-Line p += sprintf(p, statusCodeList[i].message); //Break the loop and continue processing break; } } //Properly terminate the Status-Line p += sprintf(p, "\r\n"); //The Server response-header field contains information about the //software used by the origin server to handle the request p += sprintf(p, "Server: Oryx Embedded HTTP Server\r\n"); //Format Location field? if(connection->response.location != NULL) { //Set Location field p += sprintf(p, "Location: %s\r\n", connection->response.location); } //Persistent connection? if(connection->response.keepAlive) { //Set Connection field p += sprintf(p, "Connection: keep-alive\r\n"); //Set Keep-Alive field p += sprintf(p, "Keep-Alive: timeout=%u, max=%u\r\n", HTTP_SERVER_IDLE_TIMEOUT / 1000, HTTP_SERVER_MAX_REQUESTS); } else { //Set Connection field p += sprintf(p, "Connection: close\r\n"); } //Prevent the client from using cache? if(connection->response.noCache) { //Set Pragma field p += sprintf(p, "Pragma: no-cache\r\n"); //Set Cache-Control field p += sprintf(p, "Cache-Control: no-store, no-cache, must-revalidate\r\n"); p += sprintf(p, "Cache-Control: post-check=0, pre-check=0\r\n"); } #if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED) //Use basic access authentication? if(connection->response.auth.mode == HTTP_AUTH_MODE_BASIC) { //Set WWW-Authenticate field p += sprintf(p, "WWW-Authenticate: Basic realm=\"Protected Area\"\r\n"); } #endif #if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED) //Use digest access authentication? if(connection->response.auth.mode == HTTP_AUTH_MODE_DIGEST) { size_t n; uint8_t opaque[16]; //Set WWW-Authenticate field p += sprintf(p, "WWW-Authenticate: Digest\r\n"); p += sprintf(p, " realm=\"Protected Area\",\r\n"); p += sprintf(p, " qop=\"auth\",\r\n"); p += sprintf(p, " nonce=\""); //A server-specified data string which should be uniquely generated //each time a 401 response is made error = httpGenerateNonce(connection->serverContext, p, &n); //Any error to report? if(error) return error; //Advance pointer p += n; //Properly terminate the nonce string p += sprintf(p, "\",\r\n"); //Format opaque parameter p += sprintf(p, " opaque=\""); //Generate a random value error = connection->settings->prngAlgo->read( connection->settings->prngContext, opaque, 16); //Random number generation failed? if(error) return error; //Convert the byte array to hex string httpConvertArrayToHexString(opaque, 16, p); //Advance pointer p += 32; //Properly terminate the opaque string p += sprintf(p, "\""); //The STALE flag indicates that the previous request from the client //was rejected because the nonce value was stale if(connection->response.auth.stale) p += sprintf(p, ",\r\n stale=TRUE"); //Properly terminate the WWW-Authenticate field p += sprintf(p, "\r\n"); } #endif //Content type p += sprintf(p, "Content-Type: %s\r\n", connection->response.contentType); //Use chunked encoding transfer? if(connection->response.chunkedEncoding) { //Set Transfer-Encoding field p += sprintf(p, "Transfer-Encoding: chunked\r\n"); } //Persistent connection? else if(connection->response.keepAlive) { //Set Content-Length field p += sprintf(p, "Content-Length: %" PRIuSIZE "\r\n", connection->response.contentLength); } //Terminate the header with an empty line p += sprintf(p, "\r\n"); //Debug message TRACE_DEBUG("HTTP response header:\r\n%s", connection->buffer); //Send HTTP response header to the client error = httpSend(connection, connection->buffer, strlen(connection->buffer), HTTP_FLAG_DELAY); //Return status code return error; }
int httpALC(char* path, char* param, int socket) { char buffer[1024]; if (strcmp(path, "/button") == 0) { pushButtonEvent(atoi(param)); httpSend(socket, buffer, sprintf(buffer, "OK:%i", atoi(param))); return 1; } if (strcmp(path, "/command") == 0) { httpSend(socket, buffer, sprintf(buffer, "OK")); return 1; } if (strcmp(path, "/state") == 0) { getState(buffer); httpSend(socket, buffer, strlen(buffer)); return 1; } if (strcmp(path, "/adminstate") == 0) { getAdminState(buffer); httpSend(socket, buffer, strlen(buffer)); return 1; } if (strcmp(path, "/action") == 0) { pthread_mutex_lock(&webActionMutex); strncpy(webActionBuffer, param, 1024); webActionBuffer[1024-1] = '\0'; pthread_mutex_unlock(&webActionMutex); return 1; } if (strcmp(path, "/loglist") == 0) { DIR* dh = opendir("logs"); struct dirent *entry; while((entry=readdir(dh))!=NULL) { if (entry->d_name[0] == '.') continue; httpSend(socket, entry->d_name, strlen(entry->d_name)); httpSend(socket, "\n", 1); } closedir(dh); return 1; } if (strcmp(path, "/log") == 0) { FILE* f; char filename[PATH_MAX]; snprintf(filename, PATH_MAX, "logs/%s", param); filename[PATH_MAX - 1] = '\0'; f = fopen(filename, "rb"); if (f) { char buffer[4096]; int size; while((size = fread(buffer, 1, sizeof(buffer), f)) > 0) { httpSend(socket, buffer, size); } fclose(f); return 1; } } return 0; }
void upload(char *filename, char *path, char *ip, int opt, unsigned short start, unsigned short exec) { int ret, size, p, n, k, i, j; char fullpath[256]; // don't exceed this, the cpc wouldn't be able |cd it anyway FILE *fd; SOCKET sd; unsigned char *buf; fd = fopen(filename, "rb"); if ( fd == NULL ) { printf("file %s not found\n", filename); return; } #ifndef __WIN32__ if (!is_regular_file(filename)) { printf("file %s is not a regular file\n", filename); fclose(fd); return; } #endif fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); buf = malloc(size+0x80); if ( buf == NULL ) { printf("Not enough memory!\n"); fclose(fd); return; } if ( opt != 0 ) { _cpchead *cpcheader = (_cpchead *)buf; memset(cpcheader, 0, 0x80); // set up cleaned filename and extionsion formatfn(cpcheader->filename, filename); getExtension(cpcheader->extension, filename); // add more file types here... and more paramters.... switch (opt) { case 1: cpcheader->addr = 0x172; // protext uses this cpcheader->type = 10; cpcheader->size = size; cpcheader->size2 = size; cpcheader->checksum = checksum16(buf, 66); break; default: case 2: // binary header cpcheader->addr = start; cpcheader->exec = exec; cpcheader->type = 2; cpcheader->size = size; cpcheader->size2 = size; cpcheader->checksum = checksum16(buf, 66); break; } fread(&buf[0x80], size, 1, fd); size+=0x80; } else fread(buf, size, 1, fd); fclose(fd); ret = httpConnect(ip); if ( ret >= 0 ) { sd = ret; // connect socket p = pathPos(filename, strlen(filename)); // strip any PC path from filename sprintf(fullpath, "%s/%s", path, &filename[p]); k = strlen(fullpath); n = 0; while ( n < k ) // remove leading / from path { if ( fullpath[n] != '/' ) break; n++; } // remove duplicate /'s k = strlen(fullpath); j = 0; for (i=n; i < (k+1); i++) { if ( (fullpath[i] == '/') && (fullpath[i+1] == '/') ) i++; fullpath[j++] = fullpath[i]; } if ( httpSend(sd, fullpath, buf, size, "upfile", "/upload.html", ip) >= 0 ) ret = httpResponse(sd); httpClose(sd); if ( ret == 200 ) printf("Upload OK!\r\n"); else printf("Upload error code. %i\r\n", ret); } else printf("Connect to %s failed\n", ip); free(buf); }