static int expect100(void) { ne_socket *sock = ne_sock_create(); char req[BUFSIZ], buf[BUFSIZ]; ne_status status = {0}; const ne_inet_addr *ia; int success = 0; if (strcmp(ne_get_scheme(i_session), "https") == 0) { t_context("skipping for SSL server"); return SKIP; } for (ia = ne_addr_first(i_address); ia && !success; ia = ne_addr_next(i_address)) success = ne_sock_connect(sock, ia, i_port) == 0; ONN("could not connect to server", !success); sprintf(req, "PUT %sexpect100 HTTP/1.1" EOL "Host: %s" EOL "Content-Length: 100" EOL "Expect: 100-continue" EOL EOL, i_path, ne_get_server_hostport(i_session)); NE_DEBUG(NE_DBG_SOCKET, "Request:\n%s", req); ONS("sending request", ne_sock_fullwrite(sock, req, strlen(req))); switch (ne_sock_block(sock, 30)) { case NE_SOCK_TIMEOUT: ONN("timeout waiting for interim response", FAIL); break; case 0: /* no error. */ break; default: ONN("error reading from socket", FAIL); break; } ONS("reading status line", ne_sock_readline(sock, buf, BUFSIZ)); NE_DEBUG(NE_DBG_HTTP, "[status] %s", buf); ONN("parse status line", ne_parse_statusline(buf, &status)); if (status.code == 100) { char rbuf[100] = {0}; ONN("write request body", ne_sock_fullwrite(sock, rbuf, 100)); } ne_sock_close(sock); return OK; }
/* Implements svn_ra_neon__endelm_cb_t . */ static svn_error_t * end_207_element(void *baton, int state, const char *nspace, const char *name) { multistatus_baton_t *b = baton; switch (state) { case ELEM_multistatus: if (b->contains_error) { if (svn_stringbuf_isempty(b->description)) return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, _("The request response contained at least " "one error")); else if (b->contains_precondition_error) return svn_error_create(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL, b->description->data); else return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, b->description->data); } break; case ELEM_responsedescription: if (b->in_propstat) svn_stringbuf_set(b->propstat_description, b->cdata->data); else { if (! svn_stringbuf_isempty(b->description)) svn_stringbuf_appendcstr(b->description, "\n"); svn_stringbuf_appendstr(b->description, b->cdata); } break; case ELEM_status: { ne_status status; if (ne_parse_statusline(b->cdata->data, &status) == 0) { /*### I wanted ||=, but I guess the end result is the same */ if (! b->in_propstat) b->contains_error |= (status.klass != 2); else b->propstat_has_error = (status.klass != 2); /* Handle "412 Precondition Failed" specially */ if (status.code == 412) b->contains_precondition_error = TRUE; free(status.reason_phrase); } else return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, _("The response contains a non-conforming " "HTTP status line")); } break; case ELEM_propstat: b->in_propstat = FALSE; b->contains_error |= b->propstat_has_error; svn_stringbuf_appendcstr(b->description, apr_psprintf(b->req->pool, _("Error setting property '%s': "), b->propname->data)); svn_stringbuf_appendstr(b->description, b->propstat_description); default: /* do nothing */ break; } /* When we have an element which wants cdata, we'll set it all up in start_207_element() again */ b->want_cdata = NULL; return SVN_NO_ERROR; }
static svn_error_t * end_element(void *baton, int state, const char *nspace, const char *name) { propfind_ctx_t *pc = baton; svn_ra_neon__resource_t *rsrc = pc->rsrc; const svn_string_t *value = NULL; const elem_defn *parent_defn; const elem_defn *defn; ne_status status; const char *cdata = pc->cdata->data; switch (state) { case ELEM_response: /* Verify that we've received a URL for this resource. */ if (!pc->rsrc->url) return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL); /* Store the resource in the top-level hash table. */ apr_hash_set(pc->props, pc->rsrc->url, APR_HASH_KEY_STRING, pc->rsrc); pc->rsrc = NULL; return SVN_NO_ERROR; case ELEM_propstat: /* We're at the end of a set of properties. Do the right thing status-wise. */ if (pc->status) { /* We have a status. Loop over the buffered properties, and if the status is a good one (200), copy them into the resources's property hash. Regardless of the status, we'll be removing these from the temporary buffer as we go along. */ apr_hash_index_t *hi = apr_hash_first(pc->pool, pc->propbuffer); for (; hi; hi = apr_hash_next(hi)) { const void *key; apr_ssize_t klen; void *val; apr_hash_this(hi, &key, &klen, &val); if (pc->status == 200) apr_hash_set(rsrc->propset, key, klen, val); apr_hash_set(pc->propbuffer, key, klen, NULL); } } else if (! pc->status) { /* No status at all? Bogosity. */ return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL); } return SVN_NO_ERROR; case ELEM_status: /* Parse the <status> tag's CDATA for a status code. */ if (ne_parse_statusline(cdata, &status)) return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL); free(status.reason_phrase); pc->status = status.code; return SVN_NO_ERROR; case ELEM_href: /* Special handling for <href> that belongs to the <response> tag. */ if (rsrc->href_parent == ELEM_response) return assign_rsrc_url(pc->rsrc, cdata, pc->pool); /* Use the parent element's name, not the href. */ parent_defn = defn_from_id(rsrc->href_parent); /* No known parent? Get outta here. */ if (!parent_defn) return SVN_NO_ERROR; /* All other href's we'll treat as property values. */ name = parent_defn->name; value = svn_string_create(cdata, pc->pool); break; default: /*** This case is, as usual, for everything not covered by other cases. ELM->id should be either ELEM_unknown, or one of the ids in the elem_definitions[] structure. In this case, we seek to handle properties. Since ELEM_unknown should only occur for properties, we will handle that id. All other ids will be searched for in the elem_definitions[] structure to determine if they are properties. Properties, we handle; all else hits the road. ***/ if (state == ELEM_unknown) { name = apr_pstrcat(pc->pool, nspace, name, NULL); } else { defn = defn_from_id(state); if (! (defn && defn->is_property)) return SVN_NO_ERROR; name = defn->name; } /* Check for encoding attribute. */ if (pc->encoding == NULL) { /* Handle the property value by converting it to string. */ value = svn_string_create(cdata, pc->pool); break; } /* Check for known encoding type */ if (strcmp(pc->encoding, "base64") != 0) return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL); /* There is an encoding on this property, handle it. * the braces are needed to allocate "in" on the stack. */ { svn_string_t in; in.data = cdata; in.len = strlen(cdata); value = svn_base64_decode_string(&in, pc->pool); } pc->encoding = NULL; /* Reset encoding for future attribute(s). */ } /*** Handling resource properties from here out. ***/ /* Add properties to the temporary propbuffer. At the end of the <propstat>, we'll either dump the props as invalid or move them into the resource's property hash. */ apr_hash_set(pc->propbuffer, name, APR_HASH_KEY_STRING, value); return SVN_NO_ERROR; }