static int large_get(void) { ne_request *req = ne_request_create(i_session, "GET", path); char buffer[BLOCKSIZE], origin[BLOCKSIZE * 2]; long long progress = 0; ssize_t offset = 0; ssize_t bytes; memcpy(origin, block, BLOCKSIZE); memcpy(origin + BLOCKSIZE, block, BLOCKSIZE); ONNREQ("begin large GET request", ne_begin_request(req)); ONNREQ("failed GET request", ne_get_status(req)->klass != 2); while ((bytes = ne_read_response_block(req, buffer, BLOCKSIZE)) > 0) { ONV(memcmp(origin + offset, buffer, bytes), ("byte mismatch at %" NE_FMT_LONG_LONG, progress)); offset = (offset + bytes) % BLOCKSIZE; progress += bytes; } ONNREQ("failed reading GET response", bytes < 0); ONNREQ("end large GET request", ne_end_request(req)); ne_request_destroy(req); return OK; }
static FillBufferResult fill_buffer (struct neon_handle * h) { int bsize = free_rb (& h->rb); int to_read = MIN (bsize, NEON_NETBLKSIZE); char buffer[NEON_NETBLKSIZE]; bsize = ne_read_response_block (h->request, buffer, to_read); if (! bsize) { _DEBUG ("<%p> End of file encountered", h); return FILL_BUFFER_EOF; } if (bsize < 0) { _ERROR ("<%p> Error while reading from the network", (void *) h); ne_request_destroy (h->request); h->request = NULL; return FILL_BUFFER_ERROR; } _DEBUG ("<%p> Read %d bytes of %d", h, bsize, to_read); write_rb (& h->rb, buffer, bsize); return FILL_BUFFER_SUCCESS; }
static gint gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, GstBuffer * outbuf) { GstMapInfo map = GST_MAP_INFO_INIT; gint ret; gint read = 0; gint sizetoread; /* Loop sending the request: * Retry whilst authentication fails and we supply it. */ ssize_t len = 0; if (!gst_buffer_map (outbuf, &map, GST_MAP_WRITE)) return -1; sizetoread = map.size; while (sizetoread > 0) { len = ne_read_response_block (src->request, (gchar *) map.data + read, sizetoread); if (len > 0) { read += len; sizetoread -= len; } else { break; } } gst_buffer_set_size (outbuf, read); GST_BUFFER_OFFSET (outbuf) = src->read_position; if (len < 0) { read = -2; goto done; } else if (len == 0) { ret = ne_end_request (src->request); if (ret != NE_RETRY) { if (ret == NE_OK) { src->eos = TRUE; } else { read = -3; } } goto done; } if (read > 0) src->read_position += read; done: gst_buffer_unmap (outbuf, &map); return read; }
int ne_read_response_to_buf(ne_request *req, char *buf, ssize_t *bytes_read) { ssize_t len; *bytes_read = 0; while ((len = ne_read_response_block(req, buf, sizeof buf)) > 0) { buf += len; (*bytes_read) += len; } return len == 0 ? NE_OK : NE_ERROR; }
static gint gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, GstBuffer * outbuf) { gint ret; gint read = 0; gint sizetoread = GST_BUFFER_SIZE (outbuf); /* Loop sending the request: * Retry whilst authentication fails and we supply it. */ ssize_t len = 0; while (sizetoread > 0) { len = ne_read_response_block (src->request, (gchar *) GST_BUFFER_DATA (outbuf) + read, sizetoread); if (len > 0) { read += len; sizetoread -= len; } else { break; } } GST_BUFFER_SIZE (outbuf) = read; if (len < 0) { read = -2; goto done; } else if (len == 0) { ret = ne_end_request (src->request); if (ret != NE_RETRY) { if (ret == NE_OK) { src->eos = TRUE; } else { read = -3; } } goto done; } if (read > 0) src->read_position += read; done: return read; }
static void s3_parse_xml_response(S3 *s3,ne_request *req, ne_xml_startelm_cb *startelm, ne_xml_cdata_cb *cdata, ne_xml_endelm_cb *endelm, void *userdata) { char buffer[4096]; size_t bytes_read; ne_xml_parser *xml; xml = ne_xml_create(); ne_xml_push_handler(xml,startelm,cdata,endelm,userdata); while((bytes_read = ne_read_response_block(req,buffer,4096)) > 0) { if(ne_xml_parse(xml,buffer,bytes_read) != 0) strncpy(s3->error,ne_xml_get_error(xml),511); } ne_xml_parse(xml,buffer,0); ne_xml_destroy(xml); }
static int read_large_response(void) { ne_session *sess; ne_request *req; off64_t count = 0; int ret; char buf[8192]; CALL(make_session(&sess, serve_large_response, NULL)); req = ne_request_create(sess, "GET", "/foo"); #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, ne_debug_mask & ~(NE_DBG_HTTPBODY|NE_DBG_HTTP)); #endif ret = ne_begin_request(req); if (ret == NE_OK) { while ((ret = ne_read_response_block(req, buf, sizeof buf)) > 0) count += ret; if (ret == NE_OK) ret = ne_end_request(req); } #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, ne_debug_mask & (NE_DBG_HTTPBODY|NE_DBG_HTTP)); #endif ONV(ret, ("request failed: %s", ne_get_error(sess))); ONV(count != RESPSIZE, ("response body was %" NE_FMT_OFF64_T " not %" NE_FMT_OFF64_T, count, RESPSIZE)); ne_request_destroy(req); CALL(any_2xx_request(sess, "/bar")); CALL(await_server()); ne_session_destroy(sess); return OK; }
int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser) { char buf[8000]; ssize_t bytes; int ret = 0; while ((bytes = ne_read_response_block(req, buf, sizeof buf)) > 0) { ret = ne_xml_parse(parser, buf, bytes); if (ret) return parse_error(ne_get_session(req), parser); } if (bytes == 0) { /* Tell the parser that end of document was reached: */ if (ne_xml_parse(parser, NULL, 0) == 0) return NE_OK; else return parse_error(ne_get_session(req), parser); } else { return NE_ERROR; } }
int s3_get_object(S3 *s3,const char *bucket,const char *key,const S3WriteCallback *wcb) { ne_request *req; int err, retry; if(!s3) return -1; if(!bucket) return -1; if(!wcb) return -1; s3_begin_session(s3); req = s3_new_request(s3,"GET",bucket,key,NULL,NULL); // send to server do { err = ne_begin_request(req); if(err != NE_OK) err = -EIO; else { if(ne_get_status(req)->code != 200) { s3_handle_error_response(s3,req); if(ne_get_status(req)->code == 404) err = -ENOENT; else err = -EACCES; } else { char buffer[4096]; size_t bytes_read; while((bytes_read = ne_read_response_block(req,buffer,4096)) > 0) { wcb->callback(wcb->userdata,buffer,bytes_read); } } retry = ne_end_request(req); } } while(retry == NE_RETRY); ne_request_destroy(req); s3_end_session(s3); return err; }
static int netxml_alarm_subscribe(const char *page) { int ret, port = -1, secret = -1; char buf[LARGEBUF], *s; ne_request *request; ne_sock_addr *addr; const ne_inet_addr *ai; char resp_buf[LARGEBUF]; /* Clear response buffer */ memset(resp_buf, 0, sizeof(resp_buf)); upsdebugx(2, "%s: %s", __func__, page); sock = ne_sock_create(); if (gethostname(buf, sizeof(buf)) == 0) { dstate_setinfo("driver.hostname", "%s", buf); } else { dstate_setinfo("driver.hostname", "<unknown>"); } #ifdef HAVE_NE_SOCK_CONNECT_TIMEOUT ne_sock_connect_timeout(sock, timeout); #endif ne_sock_read_timeout(sock, 1); netxml_get_page(subdriver->configure); snprintf(buf, sizeof(buf), "<?xml version=\"1.0\"?>\n"); snprintfcat(buf, sizeof(buf), "<Subscribe>\n"); snprintfcat(buf, sizeof(buf), "<Class>%s v%s</Class>\n", progname, DRIVER_VERSION); snprintfcat(buf, sizeof(buf), "<Type>connected socket</Type>\n"); snprintfcat(buf, sizeof(buf), "<HostName>%s</HostName>\n", dstate_getinfo("driver.hostname")); snprintfcat(buf, sizeof(buf), "<XMLClientParameters>\n"); snprintfcat(buf, sizeof(buf), "<ShutdownDuration>%d</ShutdownDuration>\n", shutdown_duration); if( shutdown_timer > 0 ) { snprintfcat(buf, sizeof(buf), "<ShutdownTimer>%d</ShutdownTimer>\r\n", shutdown_timer); } else { snprintfcat(buf, sizeof(buf), "<ShutdownTimer>NONE</ShutdownTimer>\n"); } snprintfcat(buf, sizeof(buf), "<AutoConfig>LOCAL</AutoConfig>\n"); snprintfcat(buf, sizeof(buf), "<OutletGroup>1</OutletGroup>\n"); snprintfcat(buf, sizeof(buf), "</XMLClientParameters>\n"); snprintfcat(buf, sizeof(buf), "<Warning></Warning>\n"); snprintfcat(buf, sizeof(buf), "</Subscribe>\n"); /* now send subscription message setting all the proper flags */ request = ne_request_create(session, "POST", page); ne_set_request_body_buffer(request, buf, strlen(buf)); /* as the NMC reply is not xml standard compliant let's parse it this way */ do { #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(timeout+1); #endif ret = ne_begin_request(request); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(0); #endif if (ret != NE_OK) { break; } ret = ne_read_response_block(request, resp_buf, sizeof(resp_buf)); if (ret == NE_OK) { ret = ne_end_request(request); } } while (ret == NE_RETRY); ne_request_destroy(request); /* due to different formats used by the various NMCs, we need to\ break up the reply in lines and parse each one separately */ for (s = strtok(resp_buf, "\r\n"); s != NULL; s = strtok(NULL, "\r\n")) { upsdebugx(2, "%s: parsing %s", __func__, s); if (!strncasecmp(s, "<Port>", 6) && (sscanf(s+6, "%u", &port) != 1)) { return NE_RETRY; } if (!strncasecmp(s, "<Secret>", 8) && (sscanf(s+8, "%u", &secret) != 1)) { return NE_RETRY; } } if ((port == -1) || (secret == -1)) { upsdebugx(2, "%s: parsing initial subcription failed", __func__); return NE_RETRY; } /* Resolve the given hostname. 'flags' must be zero. Hex * string IPv6 addresses (e.g. `::1') may be enclosed in brackets * (e.g. `[::1]'). */ addr = ne_addr_resolve(uri.host, 0); /* Returns zero if name resolution was successful, non-zero on * error. */ if (ne_addr_result(addr) != 0) { upsdebugx(2, "%s: name resolution failure on %s: %s", __func__, uri.host, ne_addr_error(addr, buf, sizeof(buf))); ne_addr_destroy(addr); return NE_RETRY; } for (ai = ne_addr_first(addr); ai != NULL; ai = ne_addr_next(addr)) { upsdebugx(2, "%s: connecting to host %s port %d", __func__, ne_iaddr_print(ai, buf, sizeof(buf)), port); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(timeout+1); #endif ret = ne_sock_connect(sock, ai, port); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(0); #endif if (ret == NE_OK) { upsdebugx(2, "%s: connection to %s open on fd %d", __func__, uri.host, ne_sock_fd(sock)); break; } } ne_addr_destroy(addr); if (ai == NULL) { upsdebugx(2, "%s: failed to create listening socket", __func__); return NE_RETRY; } snprintf(buf, sizeof(buf), "<Subscription Identification=\"%u\"></Subscription>", secret); ret = ne_sock_fullwrite(sock, buf, strlen(buf) + 1); if (ret != NE_OK) { upsdebugx(2, "%s: send failed: %s", __func__, ne_sock_error(sock)); return NE_RETRY; } ret = ne_sock_read(sock, buf, sizeof(buf)); if (ret < 1) { upsdebugx(2, "%s: read failed: %s", __func__, ne_sock_error(sock)); return NE_RETRY; } if (strcasecmp(buf, "<Subscription Answer=\"ok\"></Subscription>")) { upsdebugx(2, "%s: subscription rejected", __func__); return NE_RETRY; } upslogx(LOG_INFO, "NSM connection to '%s' established", uri.host); return NE_OK; }
/** * \brief Send HTTP request over a session * * The function creates HTTP request, sends it and reads-out the response. * * \param[in] session HTTP session * \param[in] method Request method * \param[in] uri Request URI * \param[in] ct Request content type (optional, \c NULL accepted) * \param[in] req_body Request body (optional, \c NULL is accepted) * \param[out] resp_body Response body (optional, \c NULL is accepted) * * \return HTTP status code if response was sent, 0 on send error */ static int send_http_request( ne_session *session, const char *method, const char *uri, const char *ct, ne_buffer *req_body, ne_buffer *resp_body) { int resp_code = 0; ne_request *req = NULL; /* Create request */ req = ne_request_create(session, method, uri); /* Neon claims that request creation is always successful */ assert(NULL != req); do { /* Pragmatic do ... while (0) loop allowing breaks on error */ const ne_status *req_st; /* Set Content-Type */ if (NULL != ct) ne_add_request_header(req, "Content-Type", ct); /* Set request body */ if (NULL != req_body) /* BEWARE: The terminating '\0' byte is "used", too */ ne_set_request_body_buffer(req, req_body->data, req_body->used - 1); /* Send request */ int status = ne_begin_request(req); if (NE_OK != status) { break; } /* Read response */ assert(NE_OK == status); for (;;) { char buff[512]; ssize_t read; read = ne_read_response_block(req, buff, sizeof(buff)); /* Read failure */ if (0 > read) { status = NE_ERROR; break; } if (0 == read) break; if (NULL != resp_body) ne_buffer_append(resp_body, buff, read); } if (NE_OK != status) { break; } /* Request served */ ne_end_request(req); /* Get response code */ req_st = ne_get_status(req); assert(NULL != req_st); resp_code = req_st->code; } while (0); /* end of do ... while (0) pragmatic loop */ if (NULL != req) ne_request_destroy(req); return resp_code; }