int httpLocalRequest(ObjectPtr object, int method, int from, int to, HTTPRequestPtr requestor, void *closure) { if (object->requestor == NULL) object->requestor = requestor; if (!disableLocalInterface && urlIsSpecial(object->key, object->key_size)) return httpSpecialRequest(object, method, from, to, requestor, closure); if (method >= METHOD_POST) { httpClientError(requestor, 405, internAtom("Method not allowed")); requestor->connection->flags &= ~CONN_READER; return 1; } if (object->flags & OBJECT_INITIAL) { abortObject(object, 404, internAtom("Not found")); } object->age = current_time.tv_sec; object->date = current_time.tv_sec; object->flags &= ~OBJECT_VALIDATING; notifyObject(object); return 1; }
int httpSpecialDoSide(HTTPRequestPtr requestor) { HTTPConnectionPtr client = requestor->connection; if(client->reqlen - client->reqbegin >= client->bodylen) { AtomPtr data; data = internAtomN(client->reqbuf + client->reqbegin, client->reqlen - client->reqbegin); client->reqbegin = 0; client->reqlen = 0; if(data == NULL) { do_log(L_ERROR, "Couldn't allocate data.\n"); httpClientError(requestor, 500, internAtom("Couldn't allocate data")); return 1; } httpSpecialDoSideFinish(data, requestor); return 1; } if(client->reqlen - client->reqbegin >= CHUNK_SIZE) { httpClientError(requestor, 500, internAtom("POST too large")); return 1; } if(client->reqbegin > 0 && client->reqlen > client->reqbegin) { memmove(client->reqbuf, client->reqbuf + client->reqbegin, client->reqlen - client->reqbegin); } client->reqlen -= client->reqbegin; client->reqbegin = 0; do_stream(IO_READ | IO_NOTNOW, client->fd, client->reqlen, client->reqbuf, CHUNK_SIZE, httpSpecialClientSideHandler, client); return 1; }
int httpSpecialSideRequest(ObjectPtr object, int method, int from, int to, HTTPRequestPtr requestor, void *closure) { HTTPConnectionPtr client = requestor->connection; assert(client->request == requestor); if(method != METHOD_POST) { httpClientError(requestor, 405, internAtom("Method not allowed")); requestor->connection->flags &= ~CONN_READER; return 1; } return httpSpecialDoSide(requestor); }
int httpSpecialClientSideHandler(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { HTTPConnectionPtr connection = srequest->data; HTTPRequestPtr request = connection->request; int push; (void)event; if ((request->object->flags & OBJECT_ABORTED) || !(request->object->flags & OBJECT_INPROGRESS)) { httpClientDiscardBody(connection); httpClientError(request, 503, internAtom("Post aborted")); return 1; } if (status < 0) { do_log_error(L_ERROR, -status, "Reading from client"); if (status == -EDOGRACEFUL) httpClientFinish(connection, 1); else httpClientFinish(connection, 2); return 1; } push = MIN(srequest->offset - connection->reqlen, connection->bodylen - connection->reqoffset); if (push > 0) { connection->reqlen += push; httpSpecialDoSide(request); } do_log(L_ERROR, "Incomplete client request.\n"); connection->flags &= ~CONN_READER; httpClientRawError(connection, 502, internAtom("Incomplete client request"), 1); return 1; }